commons-javaflow-0.0~svn20060411/0000755000175000017500000000000011135725056016277 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/project.properties0000644000175000017500000000345710374227647022103 0ustar drazzibdrazzibmaven.changelog.factory=org.apache.maven.svnlib.SvnChangeLogFactory maven.username = ${user.name} maven.javadoc.author=false maven.javadoc.links=http://java.sun.com/products/jdk/1.4/docs/api maven.xdoc.jsl=../commons-build/commons-site.jsl maven.xdoc.date=bottom maven.xdoc.poweredby.image=maven-feather.png maven.xdoc.version=${pom.currentVersion} maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html maven.xdoc.includeProjectDocumentation=yes maven.compile.debug=on maven.compile.deprecation=off maven.compile.optimize=off # Jar Manifest Additional Attributes maven.jar.manifest.attributes.list=Implementation-Vendor-Id,X-Compile-Source-JDK,X-Compile-Target-JDK maven.jar.manifest.attribute.Implementation-Vendor-Id=org.apache maven.jar.manifest.attribute.X-Compile-Source-JDK=${maven.compile.source} maven.jar.manifest.attribute.X-Compile-Target-JDK=${maven.compile.target} maven.jarResources.basedir=src/java maven.jar.excludes=**/package.html maven.junit.fork=true maven.test.failure.ignore = true #maven.test.skip = true maven.junit.sysproperties=org.xml.sax.driver org.xml.sax.driver=org.apache.xerces.parsers.SAXParser # 'BCEL' or 'ASM' to specify the transformer to use for testing. test.transformer=BCEL # ------------------------------------------------------------------------ # M A V E N J A R O V E R R I D E # ------------------------------------------------------------------------ maven.jar.override = on # ------------------------------------------------------------------------ # Jars set explicity by path. # ------------------------------------------------------------------------ maven.jar.commons-jci = lib/commons-jci-r291284.jar #maven.jar.commons-io = lib/commons-io-20050621.133116.jar maven.jar.bcel = lib/jakarta-bcel-20050813.jar maven.jar.asm-all = lib/asm-all-2.2.1.jar commons-javaflow-0.0~svn20060411/CREDITS.txt0000644000175000017500000000077310231510435020131 0ustar drazzibdrazzibC R E D I T S This file is meant to provide the deserved visibility for major efforts or donation to the javaflow project. The initial idea of using bytecode transformation for implementing a portable execution state serialization and migration mechanism was borrowed from the discontinued Brakes research project. The javaflow project would like to thank the Brakes team for their efforts in this space. http://www.cs.kuleuven.ac.be/cwis/research/distrinet/public/research/showproject.php?ABBREV=brakes commons-javaflow-0.0~svn20060411/LICENSE.txt0000644000175000017500000002613510210074047020117 0ustar drazzibdrazzib Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. commons-javaflow-0.0~svn20060411/maven.xml0000644000175000017500000000144010360675473020134 0ustar drazzibdrazzib commons-javaflow-0.0~svn20060411/.project0000644000175000017500000000055710166355452017757 0ustar drazzibdrazzib javaflow org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature commons-javaflow-0.0~svn20060411/project.xml0000644000175000017500000001475210366740030020472 0ustar drazzibdrazzib 3 Javaflow commons-javaflow commons-javaflow 1.0-SNAPSHOT 2004 Commons Javaflow Commons Javaflow /images/javaflow-logo-white.png http://jakarta.apache.org/commons/sandbox/${pom.artifactId.substring(8)}/ org.apache.commons.${pom.artifactId.substring(8)} The Apache Software Foundation http://jakarta.apache.org http://jakarta.apache.org/images/original-jakarta-logo.gif The Apache Software License, Version 2.0 /LICENSE.txt repo jakarta http://issues.apache.org/bugzilla/ jakarta.apache.org /www/jakarta.apache.org/commons/sandbox/${pom.artifactId.substring(8)}/ /www/jakarta.apache.org/builds/jakarta-commons/${pom.artifactId.substring(8)}/ scm:svn:http://svn.apache.org/repos/asf/jakarta/commons/sandbox/${pom.artifactId.substring(8)}/trunk http://svn.apache.org/repos/asf Commons Dev List commons-dev-subscribe@jakarta.apache.org commons-dev-unsubscribe@jakarta.apache.org http://mail-archives.apache.org/eyebrowse/SummarizeList?listName=commons-dev@jakarta.apache.org Commons User List commons-user-subscribe@jakarta.apache.org commons-user-unsubscribe@jakarta.apache.org http://mail-archives.apache.org/eyebrowse/SummarizeList?listName=commons-user@jakarta.apache.org Torsten Curdt tcurdt tcurdt at apache.org Kohsuke Kawaguchi kohsuke kohsuke at apache.org Martin Cooper martinc martinc@apache.org Informatica Eugene Kuleshov eu at javatx.org maven maven-xdoc-plugin 1.9.2 http://maven.apache.org/reference/plugins/xdoc plugin commons-logging commons-logging 1.0.4 commons-logging commons-logging-api 1.0.4 bcel bcel 20050813 ${basedir}/lib/jakarta-bcel-20050813.jar jar commons-jci commons-jci r291284 ${basedir}/lib/commons-jci-r291284.jar jar asm asm-all 2.2.1 ${basedir}/lib/asm-all-2.2.1.jar jar commons-io commons-io 1.1 ant ant 1.5.3-1 junit junit 3.8.1 junit-addons junit-addons 1.4 xstream xstream 1.1 commons-dev@jakarta.apache.org src/java src/test **/*TestCase.java **/Abstract*TestCase.java src/java **/*.properties maven-license-plugin maven-changelog-plugin maven-changes-plugin maven-developer-activity-plugin maven-file-activity-plugin maven-javadoc-plugin maven-junit-report-plugin maven-jxr-plugin maven-linkcheck-plugin commons-javaflow-0.0~svn20060411/NOTICE.txt0000644000175000017500000000014510210074047020007 0ustar drazzibdrazzibThis product includes software developed by The Apache Software Foundation (http://www.apache.org/). commons-javaflow-0.0~svn20060411/src/0000755000175000017500000000000011135725055017065 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/0000755000175000017500000000000011135725055020044 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/Justice.java0000644000175000017500000000400610354150256022312 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.bcel.verifier.VerifierFactory; import org.apache.bcel.verifier.Verifier; import org.apache.bcel.verifier.VerificationResult; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.Repository; /** * Reads a class file from stdin and runs BCEL Justice verifier. * *

* This is supposed to help us by giving us where the generate byte code is wrong, * but it turns out that this isn't as useful as I hoped for ... * *

Usage

*
 * $ cat Foo.class | java Justice
 * 
* * @author Kohsuke Kawaguchi */ public class Justice { public static void main(String[] args) throws Exception { ClassParser cp = new ClassParser(System.in,null); JavaClass clazz = cp.parse(); Repository.addClass(clazz); Verifier v = VerifierFactory.getVerifier(clazz.getClassName()); System.out.println("Pass 1"); report(v.doPass1()); System.out.println("Pass 2"); report(v.doPass2()); for( int i=0; i * Reads a class file image from stdin, write to stdout. * * @author Kohsuke Kawaguchi */ public class RewriteTool { public static void main(String[] args) throws IOException { ResourceTransformer trans = new BcelClassTransformer(); if(args.length>0 && args[0].equals("asm")) trans = new AsmClassTransformer(); byte[] out = trans.transform(RewritingUtils.toByteArray(System.in)); System.out.write(out); } } commons-javaflow-0.0~svn20060411/src/test/org/0000755000175000017500000000000011135725055020633 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/0000755000175000017500000000000011135725055022054 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/0000755000175000017500000000000011135725055023527 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/0000755000175000017500000000000011135725055025340 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/flow/0000755000175000017500000000000011135725055026307 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/0000755000175000017500000000000011135725055027136 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/0000755000175000017500000000000011135725055032204 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/0000755000175000017500000000000011135725055033111 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/DefaultConstructorTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/D0000644000175000017500000000126410360675473033231 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractDefaultConstructorTestCase; public final class DefaultConstructorTestCase extends AbstractDefaultConstructorTestCase { public static Test suite() throws Exception { final Class test = DefaultConstructorTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/InvokerTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/I0000644000175000017500000000121010360675473033225 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractInvokerTestCase; public final class InvokerTestCase extends AbstractInvokerTestCase { public static Test suite() throws Exception { final Class test = InvokerTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/SimpleTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/S0000644000175000017500000000120110360675473033237 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractSimpleTestCase; public final class SimpleTestCase extends AbstractSimpleTestCase { public static Test suite() throws Exception { final Class test = SimpleTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/CounterTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/C0000644000175000017500000000120510360675473033223 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractCounterTestCase; public final class CounterTestCase extends AbstractCounterTestCase { public static Test suite() throws Exception { final Class test = CounterTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/StackTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/S0000644000175000017500000000117510360675473033251 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractStackTestCase; public final class StackTestCase extends AbstractStackTestCase { public static Test suite() throws Exception { final Class test = StackTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformerClassLoader.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/B0000644000175000017500000000061010360675473033221 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import org.apache.commons.javaflow.bytecode.transformation.AbstractClassTransformerClassLoader; public final class BcelClassTransformerClassLoader extends AbstractClassTransformerClassLoader { public BcelClassTransformerClassLoader( final String pPrefix ) { super(pPrefix, new BcelClassTransformer()); } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/ClassAccessTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/C0000644000175000017500000000122010360675473033220 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractClassAccessTestCase; public class ClassAccessTestCase extends AbstractClassAccessTestCase { public static Test suite() throws Exception { final Class test = ClassAccessTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/ResumeTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/R0000644000175000017500000000120010360675473033235 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractResumeTestCase; public final class ResumeTestCase extends AbstractResumeTestCase { public static Test suite() throws Exception { final Class test = ResumeTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/BlackRedTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/B0000644000175000017500000000121210360675473033220 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractBlackRedTestCase; public final class BlackRedTestCase extends AbstractBlackRedTestCase { public static Test suite() throws Exception { final Class test = BlackRedTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/NoReferenceTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/N0000644000175000017500000000122710360675473033242 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractNoReferenceTestCase; public final class NoReferenceTestCase extends AbstractNoReferenceTestCase { public static Test suite() throws Exception { final Class test = NoReferenceTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/SerializationTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/S0000644000175000017500000000123410360675473033245 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractSerializationTestCase; public final class SerializationTestCase extends AbstractSerializationTestCase { public static Test suite() throws Exception { final Class test = SerializationTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/NewObjectTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/bcel/N0000644000175000017500000000121410360675473033236 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractNewObjectTestCase; public final class NewObjectTestCase extends AbstractNewObjectTestCase { public static Test suite() throws Exception { final Class test = NewObjectTestCase.class; final BcelClassTransformerClassLoader classloader = new BcelClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/DefaultConstructorDump.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/Defaul0000644000175000017500000001055510360675473033344 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; public class DefaultConstructorDump implements Opcodes { public static byte[] dump() throws Exception { FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; ClassWriter cw = new ClassWriter(true); cw.visit( V1_2, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, "org/apache/commons/javaflow/bytecode/transformation/asm/data/DefaultConstructor", null, "java/lang/Thread", null); cw.visitSource( "DefaultConstructor.java", null); { mv = cw.visitMethod( ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel( l0); mv.visitVarInsn( ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, "java/lang/Thread", "", "()V"); mv.visitMethodInsn( INVOKESTATIC, "org/apache/commons/javaflow/bytecode/StackRecorder", "get", "()Lorg/apache/commons/javaflow/bytecode/StackRecorder;"); mv.visitInsn( DUP); mv.visitVarInsn( ASTORE, 1); Label l1 = new Label(); mv.visitJumpInsn( IFNULL, l1); mv.visitVarInsn( ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "isRestoring", "()Z"); mv.visitJumpInsn( IFEQ, l1); mv.visitVarInsn( ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "popInt", "()I"); Label l2 = new Label(); mv.visitTableSwitchInsn( 0, 0, l1, new Label[] { l2}); mv.visitLabel( l2); mv.visitLdcInsn( "restore locals"); mv.visitInsn( POP); mv.visitVarInsn( ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "popObject", "()Ljava/lang/Object;"); mv.visitTypeInsn( CHECKCAST, "org/apache/commons/javaflow/bytecode/transformation/asm/data/DefaultConstructor"); mv.visitVarInsn( ASTORE, 0); mv.visitLdcInsn( "restore stack"); mv.visitInsn( POP); mv.visitLdcInsn( "restore reference"); mv.visitInsn( POP); mv.visitVarInsn( ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "popReference", "()Ljava/lang/Object;"); mv.visitTypeInsn( CHECKCAST, "java/io/PrintStream"); mv.visitLdcInsn( "restore params"); mv.visitInsn( POP); mv.visitInsn( ACONST_NULL); mv.visitTypeInsn( CHECKCAST, "java/lang/String"); Label l3 = new Label(); mv.visitJumpInsn( GOTO, l3); mv.visitLabel( l1); mv.visitFieldInsn( GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); mv.visitLdcInsn( "aaa"); mv.visitLabel( l3); mv.visitMethodInsn( INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); mv.visitVarInsn( ALOAD, 1); Label l5 = new Label(); mv.visitJumpInsn( IFNULL, l5); mv.visitVarInsn( ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "isCapturing", "()Z"); mv.visitJumpInsn( IFEQ, l5); mv.visitVarInsn( ALOAD, 1); mv.visitVarInsn( ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "pushReference", "(Ljava/lang/Object;)V"); mv.visitVarInsn( ALOAD, 1); mv.visitVarInsn( ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "pushObject", "(Ljava/lang/Object;)V"); mv.visitVarInsn( ALOAD, 1); mv.visitIntInsn( BIPUSH, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/apache/commons/javaflow/bytecode/StackRecorder", "pushInt", "(I)V"); mv.visitInsn( RETURN); mv.visitLabel( l5); mv.visitInsn( RETURN); Label l6 = new Label(); mv.visitLabel( l6); mv.visitLocalVariable( "this", "Lorg/apache/commons/javaflow/bytecode/transformation/asm/data/DefaultConstructor;", null, l1, l6, 0); mv.visitLocalVariable( "__stackRecorder", "Lorg/apache/commons/javaflow/bytecode/StackRecorder;", null, l0, l6, 1); mv.visitMaxs( 2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/AbstractClassTransformerClassLoader.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/Abstra0000644000175000017500000000466710360675473033367 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation; import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.IOUtils; import org.objectweb.asm.ClassReader; public abstract class AbstractClassTransformerClassLoader extends ClassLoader { private final ResourceTransformer transformer; private final String prefix; private final ClassLoader classloader; public AbstractClassTransformerClassLoader(final String pPrefix, final ResourceTransformer pTransformer) { prefix = pPrefix; transformer = pTransformer; classloader = getClass().getClassLoader(); } protected byte[] transform( final InputStream pClassStream ) throws IOException { return transformer.transform(IOUtils.toByteArray(pClassStream)); } public Class loadClass( final String name ) throws ClassNotFoundException { if (name.startsWith("org.apache.commons.javaflow.bytecode.transformation.")) { //System.err.println("Loading: " + name); try { final InputStream is = getClass().getResourceAsStream( "/" + name.replace('.', '/') + ".class"); byte[] bytecode; if (name.startsWith("org.apache.commons.javaflow.bytecode.transformation.data.")) { //System.err.println("Instrumenting: " + name); // bytecode = DefaultConstructorDump.dump(); bytecode = transform(is); /* * FileOutputStream os = new FileOutputStream(name+".class"); * os.write(bytecode); os.flush(); os.close(); */ // CheckClassAdapter.verify(new ClassReader(bytecode), true); } else { ClassReader cr = new ClassReader(is); bytecode = cr.b; } return super.defineClass(name, bytecode, 0, bytecode.length); // } catch( Error ex) { // new ClassReader(bytecode).accept(new TraceClassVisitor(new // PrintWriter(System.err)), false); // throw ex; } catch (Throwable ex) { System.err.println("Load error: " + ex.toString()); ex.printStackTrace(); throw new ClassNotFoundException(name + " " + ex.getMessage(), ex); } } return classloader.loadClass(name); } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/AbstractTransformerTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/Abstra0000644000175000017500000000326510360675473033360 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import junit.framework.TestCase; import org.apache.commons.javaflow.bytecode.transformation.asm.AsmClassTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.util.CheckClassAdapter; import org.objectweb.asm.util.TraceClassVisitor; public abstract class AbstractTransformerTestCase extends TestCase { protected void assertSameTransformation( final String pClazzName ) throws IOException { final InputStream is = getStream(pClazzName); final ClassReader cr = new ClassReader(is); final AsmClassTransformer t1 = new AsmClassTransformer(); final BcelClassTransformer t2 = new BcelClassTransformer(); final byte[] bytecode = t1.transform(cr.b); CheckClassAdapter.verify(new ClassReader(bytecode), true); final StringWriter sw1 = new StringWriter(); new ClassReader(bytecode).accept(new TraceClassVisitor(new PrintWriter(sw1)), false); final StringWriter sw2 = new StringWriter(); new ClassReader(t2.transform(cr.b)).accept(new TraceClassVisitor(new PrintWriter(sw2)), false); assertEquals(sw2.toString(), sw1.toString()); } protected void runTest() throws Throwable { try { super.runTest(); } catch( Throwable e) { throw e; } } private InputStream getStream( String name) { return getClass().getResourceAsStream("/" + name.replace( '.', '/') + ".class"); } } commons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/0000755000175000017500000000000011135725055033115 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/CounterFlow.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/C0000644000175000017500000000063210360675473033232 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; /** * @author Kohsuke Kawaguchi */ public final class CounterFlow implements Runnable { final int up; public CounterFlow( int up) { this.up = up; } public void run() { for( int i = 0; i < up; i++) { System.err.println(i); Continuation.suspend(); } } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/ClassAccess1.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/C0000644000175000017500000000052410360675473033232 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; public final class ClassAccess1 implements Runnable { public void run() { final Class clazz1 = ClassAccess1.class; final Class clazz2 = this.getClass(); Continuation.suspend(); } }././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/SimpleSerializable.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/S0000644000175000017500000000131210360675473033246 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import java.io.Serializable; import org.apache.commons.javaflow.Continuation; public final class SimpleSerializable implements Runnable, Serializable { private static final long serialVersionUID = 1L; public int g = -1; // global count throughout all continuations public int l = -1; // local count mapped to a global variable so // we can access is public void run() { int local = -1; ++g; l=++local; Continuation.suspend(); ++g; l=++local; Continuation.suspend(); ++g; l=++local; Continuation.suspend(); ++g; l=++local; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/ClassAccess2.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/C0000644000175000017500000000030710360675473033231 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; public final class ClassAccess2 implements Runnable { public void run() { Object o = ClassAccess2.class; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/ClassAccess3.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/C0000644000175000017500000000254310360675473033235 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; public final class ClassAccess3 implements Runnable { /* L0 (0) GETSTATIC ClassAccess2.class$0 : Class DUP IFNONNULL L1 POP L2 (5) LDC "asm.data.ClassAccess2" INVOKESTATIC Class.forName(String) : Class L3 (8) DUP PUTSTATIC ClassAccess2.class$0 : Class GOTO L1 L4 (12) NEW NoClassDefFoundError DUP_X1 SWAP INVOKEVIRTUAL Throwable.getMessage() : String INVOKESPECIAL NoClassDefFoundError.(String) : void ATHROW L1 (19) ASTORE 1: clazz1 L5 (21) INVOKESTATIC Continuation.suspend() : void L6 (23) RETURN L7 (25) TRYCATCHBLOCK L2 L3 L4 ClassNotFoundException */ static Class class$0; public void run() { // final Class clazz1 = ClassAccess2.class; // final Class clazz2 = this.getClass(); // if(class$0==null) { try { class$0 = Class.forName("asm.data.ClassAccess2"); } catch(ClassNotFoundException ex) { throw new NoClassDefFoundError(ex.getMessage()); } // } Continuation.suspend(); } }././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/NewObject.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/N0000644000175000017500000000125110360675473033243 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import junit.framework.Assert; /** * Test that allocates a lot of new objects. Javaflow performs some tricky * instrumentation on new object allocations, especially when it has arguments. * Nesting object allocations makes it even more interesting. * * @author Kohsuke Kawaguchi */ public final class NewObject implements Runnable { static char[] ch = { 'a', 'b', 'c'}; public void run() { String s = new String( new String( new String( ch, 0, ch.length).toCharArray(), 0, ch.length)); // String s = new String( new String( ch).toCharArray()); Assert.assertEquals( s, "abc"); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/BlackRed.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/B0000644000175000017500000000206510360675473033233 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; import java.io.Serializable; /** * Test for making sure that rstack works correctly. For this test we need to * have a stack frame that goes through multiple objects of different types. * * @author Kohsuke Kawaguchi */ public final class BlackRed implements Runnable, Serializable { public void run() { // new Black( new Red( new Black( new Suspend()))).run(); new Black( new Suspend()).run(); } class Black implements Runnable { final Runnable r; public Black( Runnable r) { this.r = r; } public void run() { String s = "foo"; // have some random variable r.run(); } } class Red implements Runnable { final Runnable r; public Red( Runnable r) { this.r = r; } public void run() { int i = 5; // have some random variable r.run(); } } class Suspend implements Runnable { public void run() { Continuation.suspend(); } } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/NoReference.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/N0000644000175000017500000000036610360675473033251 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; public final class NoReference implements Runnable { public void run() { new Object(); Continuation.suspend(); } }././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/NullVariableMethodFlow.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/N0000644000175000017500000000160210360675473033243 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import java.util.Properties; /** * A regression test case for handling null in the local variables. * * @author Kohsuke Kawaguchi */ public class NullVariableMethodFlow implements Runnable { public void run() { getLocalAddress(System.getProperties()); } public static String getLocalAddress(Properties session) { String x = null, y; // when javaflow generates the store/load code around this invocation, // x is of the type 'null'. we have to restore the local variable // in the correct type (in particular not java/lang/Object, but "null") // or otherwise VerifyError occurs. y = session.getProperty("a"); if (y == null) { x = session.getProperty("b"); } if (y == null) y = x; return y; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/Stack.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/S0000644000175000017500000000142310360675473033251 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; /** * Regression test case. * *

* When the stack size reaches the maximum in a constructor method invocation, * there was a bug where we failed to expand the stack size appropriately. * * This is a regression test for that case. * * * @author Kohsuke Kawaguchi */ public final class Stack implements Runnable { public void run() { final Object o = foo("abc","def"); } private Object foo(String a, String b) { return new StrStr(a,b); } private static final class StrStr { private final String value; public StrStr(String a, String b) { value = a+b; } public String toString() { return value; } } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/DefaultConstructor.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/D0000644000175000017500000000032310360675473033230 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; public final class DefaultConstructor implements Runnable { public DefaultConstructor() { } public void run() { } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/Simple.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/data/S0000644000175000017500000000112710360675473033252 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.data; import org.apache.commons.javaflow.Continuation; public final class Simple implements Runnable { public int g = -1; // global count throughout all continuations public int l = -1; // local count mapped to a global variable so // we can access is public void run() { int local = -1; ++g; l=++local; Continuation.suspend(); ++g; l=++local; Continuation.suspend(); ++g; l=++local; Continuation.suspend(); ++g; l=++local; } }././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/commons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000755000175000017500000000000011135725055033346 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractBlackRedTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000117410360675473033362 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.BlackRed; public abstract class AbstractBlackRedTestCase extends AbstractTransformerTestCase { public void testBlackRed() { final Runnable r = new BlackRed(); final Continuation c1 = Continuation.startWith(r); assertTrue(c1 != null); final Continuation c2 = Continuation.continueWith(c1); assertTrue(c2 == null); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractClassAccessTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000153210360675473033360 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.ClassAccess1; import org.apache.commons.javaflow.bytecode.transformation.data.ClassAccess2; public abstract class AbstractClassAccessTestCase extends AbstractTransformerTestCase { public void testClassAccess1() throws Exception { final ClassAccess1 r = new ClassAccess1(); final Continuation c = Continuation.startWith(r); assertTrue(c != null); } public void testClassAccess2() throws Exception { final ClassAccess2 r = new ClassAccess2(); final Continuation c = Continuation.startWith(r); assertTrue(c != null); } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractNewObjectTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000106010360675473033354 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.NewObject; public abstract class AbstractNewObjectTestCase extends AbstractTransformerTestCase { public void testNewObject() throws Exception { final Runnable r = new NewObject(); final Continuation c = Continuation.startWith(r); assertTrue(c == null); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractDefaultConstructorTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000073110360675473033360 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import junit.framework.TestCase; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.data.DefaultConstructor; public class AbstractDefaultConstructorTestCase extends TestCase { public void testInvoker() { Runnable o = new DefaultConstructor(); Continuation c = Continuation.startWith(o); assertTrue(c == null); } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractInvokerTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000105210360675473033355 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.Invoker; public abstract class AbstractInvokerTestCase extends AbstractTransformerTestCase { public void testInvoker() { Runnable r = new Thread(); Runnable o = new Invoker(r); Continuation c = Continuation.startWith(o); assertTrue(c != null); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractSerializationTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000566010360675473033366 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import junitx.util.PrivateAccessor; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.Invoker; import org.apache.commons.javaflow.bytecode.transformation.data.Simple; import org.apache.commons.javaflow.bytecode.transformation.data.SimpleSerializable; import org.apache.tools.ant.util.FileUtils; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; public abstract class AbstractSerializationTestCase extends AbstractTransformerTestCase { private File output; public void testSuspend() throws Exception { final SimpleSerializable r = new SimpleSerializable(); assertTrue(r.g == -1); assertTrue(r.l == -1); Continuation c1 = Continuation.startWith(r); assertTrue(r.g == 0); assertTrue(r.l == 0); final XStream xstream = new XStream(new DomDriver()); final String xml = xstream.toXML(c1); output = File.createTempFile("continuation", "xml"); output.deleteOnExit(); final FileOutputStream fos = new FileOutputStream(output); fos.write(xml.getBytes()); } public void testResume() throws Exception { testSuspend(); assertTrue("suspend must succeed to create the output first", output != null); final String xml = FileUtils.readFully(new FileReader(output)); final XStream xstream = new XStream(new DomDriver()); final Object o = xstream.fromXML(xml); assertTrue(o instanceof Continuation); final Continuation c1 = (Continuation) o; final SimpleSerializable r1 = (SimpleSerializable) PrivateAccessor.getField(PrivateAccessor .getField(c1, "stackRecorder"), "runnable"); assertTrue(r1.g == 0); assertTrue(r1.l == 0); final Continuation c2 = Continuation.continueWith(c1); final SimpleSerializable r2 = (SimpleSerializable) PrivateAccessor.getField(PrivateAccessor .getField(c1, "stackRecorder"), "runnable"); assertTrue(r2.g == 1); assertTrue(r2.l == 1); assertTrue(r1 == r2); } public void testSerializableCheck() throws Exception { final Runnable r1 = new Simple(); Continuation c1 = Continuation.startWith(r1); assertTrue(c1 != null); assertTrue(!c1.isSerializable()); final Runnable r2 = new SimpleSerializable(); Continuation c2 = Continuation.startWith(r2); assertTrue(c2 != null); assertTrue(c2.isSerializable()); final Runnable r3 = new SimpleSerializable(); Continuation c3 = Continuation.startWith(new Invoker(r3)); assertTrue(c3 != null); assertTrue(c3.isSerializable()); } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractCounterTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000126410360675473033362 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.CounterFlow; public abstract class AbstractCounterTestCase extends AbstractTransformerTestCase { public void testCounter() { final int count = 5; final Runnable r = new CounterFlow(count); int i = 0; Continuation c = Continuation.startWith(r); while (c != null) { c = Continuation.continueWith(c); i++; } assertTrue(i == count); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/UsageTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000102310360675473033353 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import junit.framework.TestCase; import org.apache.commons.javaflow.bytecode.transformation.data.Simple; public final class UsageTestCase extends TestCase { public void testIncorrectUsageWithNormalClassLoader() throws Exception { try { final Runnable r = new Simple(); r.run(); fail(); } catch (final Exception e) { assertTrue(e instanceof IllegalStateException); } } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractSimpleTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000105310360675473033356 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.Simple; public abstract class AbstractSimpleTestCase extends AbstractTransformerTestCase { public void testSimpleSuspend() throws Exception { final Runnable r = new Simple(); final Continuation c = Continuation.startWith(r); assertTrue(c != null); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractNoReferenceTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000107010360675473033355 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.NoReference; public abstract class AbstractNoReferenceTestCase extends AbstractTransformerTestCase { public void testNoReference() throws Exception { final Runnable r = new NoReference(); final Continuation c = Continuation.startWith(r); assertTrue(c != null); } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractResumeTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000305110360675473033356 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.SimpleSerializable; public abstract class AbstractResumeTestCase extends AbstractTransformerTestCase { public void testSimpleSuspendResume() throws Exception { final SimpleSerializable r = new SimpleSerializable(); assertTrue(r.g == -1); assertTrue(r.l == -1); Continuation c1 = Continuation.startWith(r); assertTrue(r.g == 0); assertTrue(r.l == 0); Continuation c2 = Continuation.continueWith(c1); assertTrue(r.g == 1); assertTrue(r.l == 1); Continuation c3 = Continuation.continueWith(c2); assertTrue(r.g == 2); assertTrue(r.l == 2); } public void testContinuationBranching() throws Exception { final SimpleSerializable r = new SimpleSerializable(); assertTrue(r.g == -1); assertTrue(r.l == -1); Continuation c1 = Continuation.startWith(r); assertTrue(r.g == 0); assertTrue(r.l == 0); Continuation c2 = Continuation.continueWith(c1); assertTrue(r.g == 1); assertTrue(r.l == 1); Continuation c31 = Continuation.continueWith(c2); assertTrue(r.g == 2); assertTrue(r.l == 2); Continuation c32 = Continuation.continueWith(c2); assertTrue(r.g == 3); assertTrue(r.l == 2); } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/AbstractStackTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000104010360675473033352 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; import org.apache.commons.javaflow.bytecode.transformation.data.Stack; public abstract class AbstractStackTestCase extends AbstractTransformerTestCase { public void testStack() throws Exception { final Runnable r = new Stack(); final Continuation c = Continuation.startWith(r); assertTrue(c == null); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/RewritingTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/tests/0000644000175000017500000000441010360675473033356 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.tests; import org.apache.commons.javaflow.bytecode.transformation.AbstractTransformerTestCase; public final class RewritingTestCase extends AbstractTransformerTestCase { // public void testBlackRed() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.BlackRed"); // } // public void testClassAccess1() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.ClassAccess1"); // } // public void testClassAccess2() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.ClassAccess2"); // } // public void testClassAccess3() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.ClassAccess3"); // } // public void testCounterFlow() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.CounterFlow"); // } // public void testDefaultConstructor() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.DefaultConstructor"); // } // public void testNewObject() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.NewObject"); // } // public void testNoReference() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.NoReference"); // } // public void testNullVariableMethodFlow() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.NullVariableMethodFlow"); // } // public void testSimple() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.Simple"); // } // public void testSimpleSerializable() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.SimpleSerializable"); // } // public void testStack() throws Exception { // assertSameTransformation("org.apache.commons.javaflow.bytecode.transformation.data.Stack"); // } } commons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/0000755000175000017500000000000011135725055032764 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/DefaultConstructorTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/De0000644000175000017500000000126110360675473033246 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractDefaultConstructorTestCase; public final class DefaultConstructorTestCase extends AbstractDefaultConstructorTestCase { public static Test suite() throws Exception { final Class test = DefaultConstructorTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/InvokerTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/In0000644000175000017500000000120510360675473033262 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractInvokerTestCase; public final class InvokerTestCase extends AbstractInvokerTestCase { public static Test suite() throws Exception { final Class test = InvokerTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/SimpleTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Si0000644000175000017500000000117610360675473033276 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractSimpleTestCase; public final class SimpleTestCase extends AbstractSimpleTestCase { public static Test suite() throws Exception { final Class test = SimpleTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/CounterTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Co0000644000175000017500000000120210360675473033252 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractCounterTestCase; public final class CounterTestCase extends AbstractCounterTestCase { public static Test suite() throws Exception { final Class test = CounterTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/StackTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/St0000644000175000017500000000117210360675473033305 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractStackTestCase; public final class StackTestCase extends AbstractStackTestCase { public static Test suite() throws Exception { final Class test = StackTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/ClassAccessTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Cl0000644000175000017500000000121510360675473033253 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractClassAccessTestCase; public class ClassAccessTestCase extends AbstractClassAccessTestCase { public static Test suite() throws Exception { final Class test = ClassAccessTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/ResumeTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Re0000644000175000017500000000117510360675473033270 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractResumeTestCase; public final class ResumeTestCase extends AbstractResumeTestCase { public static Test suite() throws Exception { final Class test = ResumeTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/BlackRedTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Bl0000644000175000017500000000120710360675473033253 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractBlackRedTestCase; public final class BlackRedTestCase extends AbstractBlackRedTestCase { public static Test suite() throws Exception { final Class test = BlackRedTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/AsmClassTransformerClassLoader.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/As0000644000175000017500000000060010360675473033255 0ustar drazzibdrazzib package org.apache.commons.javaflow.bytecode.transformation.asm; import org.apache.commons.javaflow.bytecode.transformation.AbstractClassTransformerClassLoader; public class AsmClassTransformerClassLoader extends AbstractClassTransformerClassLoader { public AsmClassTransformerClassLoader( final String pPrefix ) { super(pPrefix, new AsmClassTransformer()); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/NoReferenceTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/No0000644000175000017500000000122410360675473033271 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractNoReferenceTestCase; public final class NoReferenceTestCase extends AbstractNoReferenceTestCase { public static Test suite() throws Exception { final Class test = NoReferenceTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/SerializationTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Se0000644000175000017500000000123110360675473033262 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractSerializationTestCase; public final class SerializationTestCase extends AbstractSerializationTestCase { public static Test suite() throws Exception { final Class test = SerializationTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/NewObjectTestCase.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/asm/Ne0000644000175000017500000000121110360675473033253 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.asm; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.javaflow.bytecode.transformation.tests.AbstractNewObjectTestCase; public final class NewObjectTestCase extends AbstractNewObjectTestCase { public static Test suite() throws Exception { final Class test = NewObjectTestCase.class; final AsmClassTransformerClassLoader classloader = new AsmClassTransformerClassLoader(test.getPackage().getName()); final Class clazz = classloader.loadClass(test.getName()); return new TestSuite(clazz); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/Invoker.javacommons-javaflow-0.0~svn20060411/src/test/org/apache/commons/javaflow/bytecode/transformation/Invoke0000644000175000017500000000044710360675473033376 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation; public final class Invoker implements Runnable { private Runnable runnable; public Invoker(Runnable runnable) { this.runnable = runnable; } public void run() { runnable.run(); } } commons-javaflow-0.0~svn20060411/src/java/0000755000175000017500000000000011135725055020006 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/0000755000175000017500000000000011135725055020575 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/0000755000175000017500000000000011135725055022016 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/0000755000175000017500000000000011135725055023471 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/0000755000175000017500000000000011135725055025302 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/ContinuationClassLoader.java0000644000175000017500000003551410353415567032751 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * {@link URLClassLoader} with bytecode instrumentation for javaflow. * *

* This class loader is useful where the application can set up multiple * class loaders (such as in a container environment, * ClassWorlds, or * Forehead) and when you can * isolate the continuation-enabled portion of your application into a separate * jar file. */ public final class ContinuationClassLoader extends URLClassLoader { private final static Log log = LogFactory.getLog(ContinuationClassLoader.class); private final ResourceTransformer transformer; /** * Indicates whether the parent class loader should be * consulted before trying to load with this class loader. */ private boolean parentFirst = true; /** * These are the package roots that are to be loaded by the parent class * loader regardless of whether the parent class loader is being searched * first or not. */ private List systemPackages = new ArrayList(); /** * These are the package roots that are to be loaded by this class loader * regardless of whether the parent class loader is being searched first * or not. */ private List loaderPackages = new ArrayList(); /** * Whether or not this classloader will ignore the base * classloader if it can't find a class. * * @see #setIsolated(boolean) */ private boolean ignoreBase = false; /* The context to be used when loading classes and resources */ private final AccessControlContext acc; private static final int BUFFER_SIZE = 4096; /** * Creates a classloader by using the classpath given. * * @param urls * The URLs from which to load classes and resources * @param parent * The parent classloader to which unsatisfied loading * attempts are delegated. May be null, * in which case the {@link ClassLoader#getSystemClassLoader() system classloader} * is used as the parent. * @param transformer * This transformer is used to perform the byte-code enhancement. * May not be null. */ public ContinuationClassLoader(URL[] urls, ClassLoader parent, ResourceTransformer transformer) { super(urls,fixNullParent(parent)); if(transformer==null) throw new IllegalArgumentException(); this.transformer = transformer; acc = AccessController.getContext(); } public ContinuationClassLoader(URL[] urls, ClassLoader parent) { this(urls,parent,new BcelClassTransformer()); } private static ClassLoader fixNullParent(ClassLoader classLoader) { if(classLoader!=null) { return classLoader; } else { return getSystemClassLoader(); } } /** * Control whether class lookup is delegated to the parent loader first * or after this loader. Use with extreme caution. Setting this to * false violates the class loader hierarchy and can lead to Linkage errors * * @param parentFirst if true, delegate initial class search to the parent * classloader. */ public void setParentFirst(boolean parentFirst) { this.parentFirst = parentFirst; } /** * Sets whether this classloader should run in isolated mode. In * isolated mode, classes not found on the given classpath will * not be referred to the parent class loader but will cause a * ClassNotFoundException. * * @param isolated Whether or not this classloader should run in * isolated mode. */ public void setIsolated(boolean isolated) { ignoreBase = isolated; } /** * Adds a package root to the list of packages which must be loaded on the * parent loader. * * All subpackages are also included. * * @param packageRoot The root of all packages to be included. * Should not be null. */ public synchronized void addSystemPackageRoot(String packageRoot) { systemPackages.add(appendDot(packageRoot)); } /** * Adds a package root to the list of packages which must be loaded using * this loader. * * All subpackages are also included. * * @param packageRoot The root of all packages to be included. * Should not be null. */ public synchronized void addLoaderPackageRoot(String packageRoot) { loaderPackages.add(appendDot(packageRoot)); } private String appendDot(String str) { if(str.endsWith(".")) str += '.'; return str; } /** * Loads a class through this class loader even if that class is available * on the parent classpath. * * This ensures that any classes which are loaded by the returned class * will use this classloader. * * @param classname The name of the class to be loaded. * Must not be null. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on this loader's classpath. */ public Class forceLoadClass(String classname) throws ClassNotFoundException { log.debug("force loading " + classname); Class theClass = findLoadedClass(classname); if (theClass == null) { theClass = findClass(classname); } return theClass; } /** * Tests whether or not the parent classloader should be checked for * a resource before this one. If the resource matches both the * "use parent classloader first" and the "use this classloader first" * lists, the latter takes priority. * * @param resourceName The name of the resource to check. * Must not be null. * * @return whether or not the parent classloader should be checked for a * resource before this one is. */ private synchronized boolean isParentFirst(String resourceName) { // default to the global setting and then see // if this class belongs to a package which has been // designated to use a specific loader first // (this one or the parent one) // XXX - shouldn't this always return false in isolated mode? boolean useParentFirst = parentFirst; for (Iterator itr = systemPackages.iterator(); itr.hasNext();) { String packageName = (String) itr.next(); if (resourceName.startsWith(packageName)) { useParentFirst = true; break; } } for (Iterator itr = loaderPackages.iterator(); itr.hasNext();) { String packageName = (String) itr.next(); if (resourceName.startsWith(packageName)) { useParentFirst = false; break; } } return useParentFirst; } /** * Loads a class with this class loader. * * This class attempts to load the class in an order determined by whether * or not the class matches the system/loader package lists, with the * loader package list taking priority. If the classloader is in isolated * mode, failure to load the class in this loader will result in a * ClassNotFoundException. * * @param classname The name of the class to be loaded. * Must not be null. * @param resolve true if all classes upon which this class * depends are to be loaded. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on the system classpath (when not in isolated mode) or this loader's * classpath. */ protected synchronized Class loadClass(String classname, boolean resolve) throws ClassNotFoundException { // 'sync' is needed - otherwise 2 threads can load the same class // twice, resulting in LinkageError: duplicated class definition. // findLoadedClass avoids that, but without sync it won't work. Class theClass = findLoadedClass(classname); if (theClass != null) { return theClass; } if (isParentFirst(classname)) { try { theClass = getParent().loadClass(classname); log.debug("Class " + classname + " loaded from parent loader " + "(parentFirst)"); } catch (ClassNotFoundException cnfe) { theClass = findClass(classname); log.debug("Class " + classname + " loaded from ant loader " + "(parentFirst)"); } } else { try { theClass = findClass(classname); log.debug("Class " + classname + " loaded from ant loader"); } catch (ClassNotFoundException cnfe) { if (ignoreBase) { throw cnfe; } theClass = getParent().loadClass(classname); log.debug("Class " + classname + " loaded from parent loader"); } } if (resolve) { resolveClass(theClass); } return theClass; } /** * Define a class given its bytes * * @param classData the bytecode data for the class * @param classname the name of the class * * @return the Class instance created from the given data */ protected Class defineClassFromData(final byte[] classData, final String classname) { return (Class)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // define a package if necessary. int i = classname.lastIndexOf('.'); if (i>0) { String packageName = classname.substring(0,i); Package pkg = getPackage(packageName); if(pkg==null) { definePackage(packageName,null,null,null,null,null,null,null); } } byte[] newData = transformer.transform(classData); ProtectionDomain domain = this.getClass().getProtectionDomain(); return defineClass(classname,newData,0,newData.length,domain); } },acc); } /** * Reads a class definition from a stream. * * @param stream The stream from which the class is to be read. * Must not be null. * @param classname The name of the class in the stream. * Must not be null. * * @return the Class object read from the stream. * * @exception IOException if there is a problem reading the class from the * stream. * @exception SecurityException if there is a security problem while * reading the class from the stream. */ private Class getClassFromStream(InputStream stream, String classname) throws IOException, SecurityException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int bytesRead; byte[] buffer = new byte[BUFFER_SIZE]; while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) { baos.write(buffer, 0, bytesRead); } byte[] classData = baos.toByteArray(); return defineClassFromData(classData, classname); } /** * Searches for and load a class on the classpath of this class loader. * * @param name The name of the class to be loaded. Must not be * null. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on this loader's classpath. */ public Class findClass(final String name) throws ClassNotFoundException { log.debug("Finding class " + name); // locate the class file String classFileName = name.replace('.', '/') + ".class"; InputStream stream = getResourceAsStream(classFileName); if(stream==null) throw new ClassNotFoundException(name); try { return getClassFromStream(stream, name); } catch (IOException e) { throw new ClassNotFoundException(name,e); } finally { try { stream.close(); } catch (IOException e) { // ignore } } } /** * Finds the resource with the given name. A resource is * some data (images, audio, text, etc) that can be accessed by class * code in a way that is independent of the location of the code. * * @param name The name of the resource for which a stream is required. * Must not be null. * @return a URL for reading the resource, or null if the * resource could not be found or the caller doesn't have * adequate privileges to get the resource. */ public synchronized URL getResource(String name) { // we need to search the components of the path to see if // we can find the class we want. if (isParentFirst(name)) { return super.getResource(name); } // try this class loader first, then parent URL url = findResource(name); if(url==null) { url = getParent().getResource(name); } return url; } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/Continuation.java0000644000175000017500000002410610371667464030634 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow; import java.io.Serializable; import org.apache.commons.javaflow.bytecode.StackRecorder; import org.apache.commons.javaflow.utils.ReflectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Snapshot of a thread execution state. * *

* A {@link Continuation} object is an immutable object that captures everything in * the Java stack. This includes * (1) current instruction pointer, * (2) return addresses, and * (3) local variables. * *

* Continuation objects are used to restore the captured execution states * later. * * @author Stephan Michels * @author Torsten Curdt * @version CVS $Revision: 375299 $ */ public final class Continuation implements Serializable { private static final Log log = LogFactory.getLog(Continuation.class); private static final long serialVersionUID = 2L; private final StackRecorder stackRecorder; /** * Create a new continuation, which continue a previous continuation. */ private Continuation( final StackRecorder pStackRecorder ) { stackRecorder = pStackRecorder; } /** * get the current context. * *

* This method returns the same context object given to {@link #startWith(Runnable, Object)} * or {@link #continueWith(Continuation, Object)}. * *

* A different context can be used for each run of a continuation, so * this mechanism can be used to associate some state with each execution. * * @return * null if this method is invoked outside {@link #startWith(Runnable, Object)} * or {@link #continueWith(Continuation, Object)} . */ public static Object getContext() { return StackRecorder.get().getContext(); } /** * Creates a new {@link Continuation} object from the specified {@link Runnable} * object. * *

* Unlike the {@link #startWith(Runnable)} method, this method doesn't actually * execute the Runnable object. It will be executed when * it's {@link #continueWith(Continuation) continued}. * * @return * always return a non-null valid object. */ public static Continuation startSuspendedWith( final Runnable pTarget ) { return new Continuation(new StackRecorder(pTarget)); } /** * Starts executing the specified {@link Runnable} object in an environment * that allows {@link Continuation#suspend()}. * *

* This is a short hand for startWith(target,null). * * @see #startWith(Runnable, Object). */ public static Continuation startWith( final Runnable pTarget ) { return startWith(pTarget, null); } /** * Starts executing the specified {@link Runnable} object in an environment * that allows {@link Continuation#suspend()}. * * This method blocks until the continuation suspends or completes. * * @param pTarget * The object whose run method will be executed. * @param pContext * This value can be obtained from {@link #getContext()} until this method returns. * Can be null. * @return * If the execution completes and there's nothing more to continue, return null. * Otherwise, the execution has been {@link #suspend() suspended}, in which case * a new non-null continuation is returned. * @see #getContext() */ public static Continuation startWith( final Runnable pTarget, final Object pContext ) { if(pTarget == null) { throw new IllegalArgumentException("target is null"); } log.debug("starting new flow from " + ReflectionUtils.getClassName(pTarget) + "/" + ReflectionUtils.getClassLoaderName(pTarget)); return continueWith(new Continuation(new StackRecorder(pTarget)), pContext); } /** * Resumes the execution of the specified continuation from where it's left off. * *

* This is a short hand for continueWith(resumed,null). * * @see #continueWith(Continuation, Object) */ public static Continuation continueWith(final Continuation pOldContinuation) { return continueWith(pOldContinuation, null); } /** * Resumes the execution of the specified continuation from where it's left off * and creates a new continuation representing the new state. * * This method blocks until the continuation suspends or completes. * * @param pOldContinuation * The resumed continuation to be executed. Must not be null. * @param pContext * This value can be obtained from {@link #getContext()} until this method returns. * Can be null. * @return * If the execution completes and there's nothing more to continue, return null. * Otherwise, the execution has been {@link #suspend() suspended}, in which case * a new non-null continuation is returned. * @see #getContext() */ public static Continuation continueWith(final Continuation pOldContinuation, final Object pContext) { if(pOldContinuation == null) { throw new IllegalArgumentException("continuation parameter must not be null."); } log.debug("continueing with continuation " + ReflectionUtils.getClassName(pOldContinuation) + "/" + ReflectionUtils.getClassLoaderName(pOldContinuation)); while(true) { try { StackRecorder pStackRecorder = new StackRecorder(pOldContinuation.stackRecorder).execute(pContext); if(pStackRecorder == null) { return null; } else { return new Continuation(pStackRecorder); } } catch (ContinuationDeath e) { if(e.mode.equals(ContinuationDeath.MODE_AGAIN)) continue; // re-execute immediately if(e.mode.equals(ContinuationDeath.MODE_EXIT)) return null; // no more thing to continue if(e.mode.equals(ContinuationDeath.MODE_CANCEL)) return pOldContinuation; throw new IllegalStateException("Illegal mode "+e.mode); } } } public boolean isSerializable() { return stackRecorder.isSerializable(); } /** * Stops the running continuation. * *

* This method can be only called inside {@link #continueWith} or {@link #startWith} methods. * When called, the thread returns from the above methods with a new {@link Continuation} * object that captures the thread state. * * @throws IllegalStateException * if this method is called outside the {@link #continueWith} or {@link #startWith} methods. */ public static void suspend() { StackRecorder.suspend(); } /** * Completes the execution of the running continuation. * *

* This method can be only called inside {@link #continueWith} or {@link #startWith} methods. * When called, the thread returns from the above methods with null, * indicating that there's nothing more to continue. * *

* This method is similiar to how {@link System#exit(int)} works for JVM. */ public static void exit() { throw new ContinuationDeath(ContinuationDeath.MODE_EXIT); } /** * Jumps to where the execution was resumed. * *

* This method can be only called inside {@link #continueWith} or {@link #startWith} methods. * When called, the execution jumps to where it was resumed * (if the execution has never resumed before, from the beginning * of {@link Runnable#run()}.) * *

* Consider the following example: * *

     * Continuation.suspend();
     * System.out.println("resumed");
     *
     * r = new Random().nextInt(5);
     * if(r!=0) {
     *   System.out.println("do it again");
     *   Continuation.again();
     * }
     *
     * System.out.println("done");
     * 
* *

* This program produces an output like this (the exact number of * 'do it again' depends on each execution, as it's random.) * *

     * resumed
     * do it again
     * resumed
     * do it again
     * resumed
     * do it again
     * resumed
     * done
     * 
* *

* The calling {@link Continuation#startWith(Runnable)} method and * {@link Continuation#continueWith(Continuation)} method does not * return when a program running inside uses this method. */ public static void again() { throw new ContinuationDeath(ContinuationDeath.MODE_AGAIN); } /** * Jumps to where the execution was resumed, and suspend execution. * *

* This method almost works like the {@link #again()} method, * but instead of re-executing, this method first suspends the execution. * *

* Therefore, * the calling {@link Continuation#startWith(Runnable)} method and * {@link Continuation#continueWith(Continuation)} method * return when a program running inside uses this method. */ public static void cancel() { throw new ContinuationDeath(ContinuationDeath.MODE_CANCEL); } public String toString() { return "Continuation@" + hashCode() + "/" + ReflectionUtils.getClassLoaderName(this); } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/stores/0000755000175000017500000000000011135725055026621 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/stores/JavaflowResourceStore.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/stores/JavaflowResourceStore.j0000644000175000017500000000630210315242673033272 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.stores; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.apache.bcel.Repository; import org.apache.bcel.util.ClassLoaderRepository; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer; import org.apache.commons.jci.stores.MemoryResourceStore; import org.apache.commons.jci.stores.ResourceStore; import org.apache.commons.jci.stores.TransactionalResourceStore; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Due to the BCEL dependency handling all * classes have to be store first and then * be rewritten. Otherwise we could just * delegate to the TransformingResourceStore * * @author tcurdt */ public final class JavaflowResourceStore extends TransactionalResourceStore { private final static Log log = LogFactory.getLog(JavaflowResourceStore.class); private final TransformingResourceStore tstore; private final Collection changes = new ArrayList(); public JavaflowResourceStore() { this(new MemoryResourceStore()); } public JavaflowResourceStore(final ResourceStore pStore) { super(pStore); tstore = new TransformingResourceStore( pStore, new ResourceTransformer[] { new BcelClassTransformer() } ); Repository.setRepository(new ClassLoaderRepository(this.getClass().getClassLoader())); } public void write(final String pResourceName, final byte[] pResourceData) { super.write(pResourceName, pResourceData); changes.add(pResourceName); } public void onStart() { changes.clear(); } public void onStop() { if (changes.size() > 0) { log.debug("rewriting" + changes); for (Iterator it = changes.iterator(); it.hasNext();) { final String clazzName = (String) it.next(); try { final byte[] oldClazz = super.read(clazzName); if (oldClazz == null) { throw new ClassNotFoundException("could not find " + clazzName); } tstore.write(clazzName, oldClazz); log.debug("rewrote " + clazzName); } catch (ClassNotFoundException e) { log.error("", e); } } changes.clear(); } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/stores/TransformingResourceStore.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/stores/TransformingResourceSto0000644000175000017500000000356410315242673033422 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.stores; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.jci.stores.ResourceStore; /** * @author tcurdt * */ public final class TransformingResourceStore implements ResourceStore { private final ResourceStore store; private final ResourceTransformer[] transformers; public TransformingResourceStore( final ResourceStore pStore, final ResourceTransformer[] pTransformers) { store = pStore; transformers = pTransformers; } public byte[] read(String resourceName) { return store.read(resourceName); } public void remove(String resourceName) { store.remove(resourceName); } public void write(String resourceName, byte[] resourceData) { byte[] out = resourceData; // FIXME: make the matching configurable //if (resourceName.endsWith(".class")) { byte[] in = resourceData; for(int i=0; i * This class is only for javaflow internal code. * * @author Kohsuke Kawaguchi */ public final class ContinuationDeath extends Error { final String mode; public ContinuationDeath(String mode) { this.mode = mode; } /** * Signals that the continuation wants to exit the execution. */ static final String MODE_EXIT = "exit"; /** * Signals that the execution should restart immediately * from where it resumed. */ static final String MODE_AGAIN = "again"; /** * Signals that the exeuction should suspend, * by using the original continuation. */ static final String MODE_CANCEL = "cancel"; } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/utils/0000755000175000017500000000000011135725055026442 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/utils/ReflectionUtils.java0000644000175000017500000001213210323570510032407 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author tcurdt * */ public final class ReflectionUtils { private final static Log log = LogFactory.getLog(ReflectionUtils.class); public interface Matcher { boolean matches(final String pName); } public interface Indexer { void put(final Map pMap, final String pKey, final Object pObject); } private static Indexer defaultIndexer = new DefaultIndexer(); private static Matcher defaultMatcher = new DefaultMatcher(); public static class DefaultMatcher implements Matcher { public boolean matches(final String pName) { return true; } } public static class DefaultIndexer implements Indexer { public void put(final Map pMap, final String pKey, final Object pObject) { pMap.put(pKey, pObject); } } public static Map discoverFields( final Class pClazz, final Matcher pMatcher ) { return discoverFields(pClazz, pMatcher, defaultIndexer); } public static Map discoverFields( final Class pClazz ) { return discoverFields(pClazz, defaultMatcher, defaultIndexer); } public static Map discoverFields( final Class pClazz, final Matcher pMatcher, final Indexer pIndexer ) { log.debug("discovering fields on " + pClazz.getName()); final Map result = new HashMap(); Class current = pClazz; do { final Field[] fields = current.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { final String fname = fields[i].getName(); if (pMatcher.matches(fname)) { pIndexer.put(result, fname, fields[i]); log.debug("discovered field " + fname + " -> " + fields[i]); } } current = current.getSuperclass(); } while(current != null); return result; } public static Map discoverMethods( final Class pClazz, final Matcher pMatcher ) { return discoverMethods(pClazz, pMatcher, defaultIndexer); } public static Map discoverMethods( final Class pClazz ) { return discoverMethods(pClazz, defaultMatcher, defaultIndexer); } public static Map discoverMethods( final Class pClazz, final Matcher pMatcher, final Indexer pIndexer ) { log.debug("discovering methods on " + pClazz.getName()); final Map result = new HashMap(); Class current = pClazz; do { final Method[] methods = current.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { final String mname = methods[i].getName(); if (pMatcher.matches(mname)) { pIndexer.put(result, mname, methods[i]); log.debug("discovered method " + mname + " -> " + methods[i]); } } current = current.getSuperclass(); } while(current != null); return result; } public static Object cast(Object o) throws IOException, ClassNotFoundException { final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream(buffer); oos.writeObject(o); oos.flush(); final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())); return ois.readObject(); } public static String getClassName(final Object o) { if (o == null) { return "unknown"; } return o.getClass().getName() + "@" + o.hashCode(); } public static String getClassLoaderName(final Object o) { if (o == null) { return "unknown"; } return getClassName(o.getClass().getClassLoader()); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/utils/CompositeTransformer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/utils/CompositeTransformer.jav0000644000175000017500000000131510354314026033323 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.utils; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; /** * {@link ResourceTransformer} whose transformation * is defined in terms of multiple {@link ResourceTransformer}s. * * @author Kohsuke Kawaguchi */ public class CompositeTransformer implements ResourceTransformer { private final ResourceTransformer[] transformers; public CompositeTransformer(ResourceTransformer[] transformers) { this.transformers = transformers; } public byte[] transform(byte[] image) { for (int i = 0; i < transformers.length; i++) { image = transformers[i].transform(image); } return image; } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/utils/RewritingUtils.java0000644000175000017500000001313310355524515032302 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.utils; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; public final class RewritingUtils { private final static Log log = LogFactory.getLog(RewritingUtils.class); public interface Matcher { boolean isMatching( final String name ); } private final static Matcher MATCH_ALL = new Matcher() { public boolean isMatching(final String pName) { return true; } }; /* * @todo multiple transformers */ public static void rewriteClassFile( final File pInput, final ResourceTransformer transformer, final File pOutput ) throws IOException { final byte[] original = toByteArray(pInput); byte[] transformed = transformer.transform(original); final FileOutputStream os = new FileOutputStream(pOutput); os.write(transformed); os.close(); } public static boolean rewriteJar( final JarInputStream pInput, final ResourceTransformer transformer, final JarOutputStream pOutput ) throws IOException { return rewriteJar(pInput, transformer, pOutput, MATCH_ALL); } public static boolean rewriteJar( final JarInputStream pInput, final ResourceTransformer transformer, final JarOutputStream pOutput, final Matcher pMatcher ) throws IOException { boolean changed = false; while(true) { final JarEntry entry = pInput.getNextJarEntry(); if (entry == null) { break; } if (entry.isDirectory()) { pOutput.putNextEntry(new JarEntry(entry)); continue; } final String name = entry.getName(); pOutput.putNextEntry(new JarEntry(name)); if (name.endsWith(".class")) { if (pMatcher.isMatching(name)) { if (log.isDebugEnabled()) { log.debug("transforming " + name); } final byte[] original = toByteArray(pInput); byte[] transformed = transformer.transform(original); pOutput.write(transformed); changed |= transformed.length != original.length; continue; } } else if (name.endsWith(".jar") || name.endsWith(".ear") || name.endsWith(".zip") || name.endsWith(".war")) { changed |= rewriteJar( new JarInputStream(pInput), transformer, new JarOutputStream(pOutput), pMatcher ); continue; } int length = copy(pInput,pOutput); log.debug("copied " + name + "(" + length + ")"); } pInput.close(); pOutput.close(); return changed; } public static byte[] toByteArray(File f) throws IOException { InputStream in = new FileInputStream(f); try { return toByteArray(in); } finally { in.close(); } } public static byte[] toByteArray(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); copy(in,baos); return baos.toByteArray(); } /** * Copies the entire {@link InputStream} to the given {@link OutputStream}. * * @return * the number of bytes copied. */ public static int copy(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[8192]; int n; int total = 0; while ((n = in.read(buf)) >= 0) { out.write(buf, 0, n); total += n; } return total; } public static void main(final String[] args) throws FileNotFoundException, IOException { ResourceTransformer transformer = new BcelClassTransformer(); for (int i=0; i * This option is unpublished, because in a long run we'll * likely to just focus on one transformer and get rid * of the other (and this option will be removed then.) * * @param name * either "BCEL" or "ASM". Case insensitive. */ public void setMode(String name) { name = name.toLowerCase(); if(name.equals("bcel")) transformer = new BcelClassTransformer(); else if(name.equals("asm")) transformer = new AsmClassTransformer(); else throw new BuildException("Unrecognized mode: "+name); } /** * Check that all required attributes have been set and nothing * silly has been entered. * * @since Ant 1.5 */ protected void checkParameters() throws BuildException { checkDir(srcDir,"srcDir"); checkDir(dstDir,"dstDir"); } private void checkDir(final File pDir, final String pDescription) { if (pDir == null) { throw new BuildException("no " + pDescription + " directory is specified", getLocation()); } if (!pDir.exists()) { throw new BuildException(pDescription + " directory \"" + pDir + "\" does not exist", getLocation()); } if (!pDir.isDirectory()) { throw new BuildException(pDescription + " directory \"" + pDir + "\" is not a directory", getLocation()); } } public void execute() throws BuildException { final DirectoryScanner ds = fileset.getDirectoryScanner(getProject()); final String[] fileNames = ds.getIncludedFiles(); // default to BCEL, since the BCEL version is more stable if(transformer==null) transformer = new BcelClassTransformer(); try { for (int i = 0; i < fileNames.length; i++) { final String fileName = fileNames[i]; final File source = new File(srcDir, fileName); final File destination = new File(dstDir, fileName); if (!destination.getParentFile().exists()) { log("Creating dir: " + destination.getParentFile(), Project.MSG_VERBOSE); destination.getParentFile().mkdirs(); } if (source.lastModified() < destination.lastModified()) { log("Omitting " + source + " as " + destination + " is up to date", Project.MSG_VERBOSE); continue; } if (fileName.endsWith(".class")) { log("Rewriting " + source + " to " + destination, Project.MSG_VERBOSE); System.out.println("Rewriting " + source); RewritingUtils.rewriteClassFile( source, transformer, destination ); } if (fileName.endsWith(".jar") || fileName.endsWith(".ear") || fileName.endsWith(".zip") || fileName.endsWith(".war")) { log("Rewriting " + source + " to " + destination, Project.MSG_VERBOSE); RewritingUtils.rewriteJar( new JarInputStream(new FileInputStream(source)), transformer, new JarOutputStream(new FileOutputStream(destination)) ); } } } catch (IOException e) { throw new BuildException(e); } } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/ant/tasks.properties0000644000175000017500000000007010353415567031331 0ustar drazzibdrazzibjavaflow=org.apache.commons.javaflow.ant.AntRewriteTask commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/0000755000175000017500000000000011135725056027101 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/StackRecorder.java0000644000175000017500000001161710371667521032510 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode; import org.apache.commons.javaflow.utils.ReflectionUtils; import org.apache.commons.javaflow.ContinuationDeath; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Adds additional behaviors necessary for stack capture/restore * on top of {@link Stack}. * * @author Kohsuke Kawaguchi */ public final class StackRecorder extends Stack { private static final Log log = LogFactory.getLog(StackRecorder.class); private static final long serialVersionUID = 2L; private static final ThreadLocal threadMap = new ThreadLocal(); /** * True, if the continuation restores the previous stack trace to the last * invocation of suspend(). * *

* This field is accessed from the byte code injected into application code, * and therefore defining a wrapper get method makes it awkward to * step through the user code. That's why this field is public. */ public transient boolean isRestoring = false; /** * True, is the continuation freeze the strack trace, and stops the * continuation. * * @see #isRestoring */ public transient boolean isCapturing = false; /** Context object given by the user */ private transient Object context; /** * Creates a new empty {@link StackRecorder} that runs the given target. */ public StackRecorder( final Runnable pTarget ) { super(pTarget); } /** * Creates a clone of the given {@link StackRecorder}. */ public StackRecorder(final Stack pParent) { super(pParent); } public static void suspend() { log.debug("suspend()"); final StackRecorder stackRecorder = get(); if(stackRecorder == null) { throw new IllegalStateException("No continuation is running"); } stackRecorder.isCapturing = !stackRecorder.isRestoring; stackRecorder.isRestoring = false; } public StackRecorder execute(final Object context) { final StackRecorder old = registerThread(); try { isRestoring = !isEmpty(); // start restoring if we have a filled stack this.context = context; if (isRestoring) { log.debug("Restoring state of " + ReflectionUtils.getClassName(runnable) + "/" + ReflectionUtils.getClassLoaderName(runnable)); } log.debug("calling runnable"); runnable.run(); if (isCapturing) { if(isEmpty()) { // if we were really capturing the stack, at least we should have // one object in the reference stack. Otherwise, it usually means // that the application wasn't instrumented correctly. throw new IllegalStateException("stack corruption. Is "+runnable.getClass()+" instrumented for javaflow?"); } // top of the reference stack is the object that we'll call into // when resuming this continuation. we have a separate Runnable // for this, so throw it away popReference(); return this; } else { return null; // nothing more to continue } } catch(ContinuationDeath cd) { // this isn't an error, so no need to log throw cd; } catch(Error e) { log.error(e.getMessage(),e); throw e; } catch(RuntimeException e) { log.error(e.getMessage(),e); throw e; } finally { this.context = null; deregisterThread(old); } } public Object getContext() { return context; } /** * Bind this stack recorder to running thread. */ private StackRecorder registerThread() { StackRecorder old = get(); threadMap.set(this); return old; } /** * Unbind the current stack recorder to running thread. */ private void deregisterThread(final StackRecorder old) { threadMap.set(old); } /** * Return the continuation, which is associated to the current thread. */ public static StackRecorder get() { return (StackRecorder)threadMap.get(); } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.j0000644000175000017500000000217310325362475033134 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode; import org.objectweb.asm.ClassAdapter; import org.objectweb.asm.ClassReader; import org.objectweb.asm.commons.EmptyVisitor; public final class BytecodeClassLoader extends ClassLoader { class NameClassAdapter extends ClassAdapter { private String className; public NameClassAdapter() { super(new EmptyVisitor()); } public void visit( int version, int access, String name, String signature, String superName, String[] interfaces ) { className = name; } public String getName() { return className; } } public Class loadClass( final byte[] bytecode ) { final NameClassAdapter nameClassAdapter = new NameClassAdapter(); new ClassReader(bytecode).accept(nameClassAdapter, false); final String name = nameClassAdapter.getName().replace('/', '.'); System.out.println("loading class " + name); final Class clazz = defineClass(null, bytecode, 0, bytecode.length); return clazz; } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/0000755000175000017500000000000011135725056032147 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/0000755000175000017500000000000011135725056033054 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/DecompilingVisitor.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/D0000644000175000017500000001371510276745044033175 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel; import java.io.OutputStream; import java.io.PrintWriter; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.ConstantValue; import org.apache.bcel.classfile.Deprecated; import org.apache.bcel.classfile.ExceptionTable; import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.bcel.classfile.Synthetic; import org.apache.bcel.classfile.Utility; import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.CodeExceptionGen; import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.Instruction; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.LocalVariableGen; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.Select; import org.apache.bcel.generic.TABLESWITCH; public final class DecompilingVisitor extends org.apache.bcel.classfile.EmptyVisitor { private JavaClass clazz; private PrintWriter out; private String clazzname; private ConstantPoolGen cp; public DecompilingVisitor(JavaClass clazz, OutputStream out) { this.clazz = clazz; this.out = new PrintWriter(out); clazzname = clazz.getClassName(); cp = new ConstantPoolGen(clazz.getConstantPool()); } public void start() { new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit(); out.close(); } public void visitJavaClass(JavaClass clazz) { out.println("// source " + clazz.getSourceFileName()); out.println(Utility.accessToString(clazz.getAccessFlags(), true) + " " + Utility.classOrInterface(clazz.getAccessFlags()) + " " + clazz.getClassName().replace('.', '/')); out.println(" extends " + clazz.getSuperclassName().replace('.', '/')); String[] interfaces = clazz.getInterfaceNames(); if (interfaces.length > 0) { out.print(" implements"); for (int i = 0; i < interfaces.length; i++) out.print(" " + interfaces[i].replace('.', '/')); out.println(); } out.println(); } public void visitField(Field field) { out.println(" " + Utility.accessToString(field.getAccessFlags()) + " " + field.getType() + " " + field.getName() + ";"); /*if (field.getAttributes().length == 0) out.print("\n");*/ } public void visitConstantValue(ConstantValue cv) { out.println(" = " + cv); } private Method _method; public void visitDeprecated(Deprecated attribute) { } public void visitSynthetic(Synthetic attribute) { } public void visitMethod(Method method) { this._method = method; // Remember for use in subsequent visitXXX calls out.println("\n " + Utility.accessToString(_method.getAccessFlags()) + " " + _method.getReturnType() + " " + _method.getName()); } public void visitExceptionTable(ExceptionTable e) { String[] names = e.getExceptionNames(); for (int i = 0; i < names.length; i++) out.println(" throws " + names[i].replace('.', '/')); } public void visitCode(Code code) { MethodGen mg = new MethodGen(_method, clazzname, cp); InstructionList il = mg.getInstructionList(); InstructionHandle[] ihs = il.getInstructionHandles(); LocalVariableGen[] lvs = mg.getLocalVariables(); CodeExceptionGen[] ehs = mg.getExceptionHandlers(); for (int i = 0; i < lvs.length; i++) { LocalVariableGen l = lvs[i]; out.println(" // local variable " + l.getIndex() + " is \"" + l.getName() + "\" " + l.getType() + " from " + l.getStart().getPosition() + " to " + l.getEnd().getPosition()); } out.print("\n"); for (int i = 0; i < ihs.length; i++) { InstructionHandle ih = ihs[i]; Instruction inst = ih.getInstruction(); out.print(" " + ih.getPosition()); if (inst instanceof BranchInstruction) { if (inst instanceof Select) { // Special cases LOOKUPSWITCH and // TABLESWITCH Select s = (Select) inst; int[] matchs = s.getMatchs(); InstructionHandle[] targets = s.getTargets(); if (s instanceof TABLESWITCH) { out.println(" tableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); for (int j = 0; j < targets.length; j++) out.println(" " + targets[j].getPosition()); } else { // LOOKUPSWITCH out.println(" lookupswitch "); for (int j = 0; j < targets.length; j++) out.println(" " + matchs[j] + " : " + targets[j].getPosition()); } out.println(" default: " + s.getTarget()); // Applies // for // both } else { BranchInstruction bi = (BranchInstruction) inst; ih = bi.getTarget(); //str = get(ih); out.println(" " + Constants.OPCODE_NAMES[bi.getOpcode()] + " " + ih); } } else out.println(" " + inst.toString(cp.getConstantPool())); } out.print("\n"); for (int i = 0; i < ehs.length; i++) { CodeExceptionGen c = ehs[i]; ObjectType caught = c.getCatchType(); String class_name = (caught == null) ? // catch any exception, used // when compiling finally "all" : caught.getClassName().replace('.', '/'); out.println(" catch " + class_name + " from " + c.getStartPC().getPosition() + " to " + c.getEndPC().getPosition() + " using " + c.getHandlerPC().getPosition()); } } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/B0000644000175000017500000011601010354632735033162 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel; import org.apache.bcel.Constants; import org.apache.bcel.Repository; import org.apache.bcel.classfile.Attribute; import org.apache.bcel.classfile.ClassFormatException; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.ConstantCP; import org.apache.bcel.classfile.ConstantNameAndType; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.classfile.ConstantUtf8; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.ACONST_NULL; import org.apache.bcel.generic.ASTORE; import org.apache.bcel.generic.BasicType; import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.GOTO; import org.apache.bcel.generic.IFEQ; import org.apache.bcel.generic.IFNULL; import org.apache.bcel.generic.INVOKESTATIC; import org.apache.bcel.generic.Instruction; import org.apache.bcel.generic.InstructionConstants; import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.InstructionTargeter; import org.apache.bcel.generic.InvokeInstruction; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.ObjectType; import org.apache.bcel.generic.PUSH; import org.apache.bcel.generic.RET; import org.apache.bcel.generic.ReferenceType; import org.apache.bcel.generic.TABLESWITCH; import org.apache.bcel.generic.TargetLostException; import org.apache.bcel.generic.Type; import org.apache.bcel.verifier.exc.AssertionViolatedException; import org.apache.commons.javaflow.bytecode.Continuable; import org.apache.commons.javaflow.bytecode.StackRecorder; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.ControlFlowGraph; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.ExceptionHandler; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.ExecutionPath; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.ExecutionVisitor; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.Frame; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.InstructionContext; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.LocalVariables; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.OperandStack; import org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.UninitializedObjectType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; /** * {@link ResourceTransformer} that uses BCEL. * * @author tcurdt * @author Kohsuke Kawaguchi */ public final class BcelClassTransformer implements ResourceTransformer { private final static Log log = LogFactory.getLog(BcelClassTransformer.class); private static final String STACK_RECORDER_CLASS = StackRecorder.class.getName(); private static final ObjectType STACK_RECORDER_TYPE = new ObjectType(STACK_RECORDER_CLASS); private static final String CONTINUABLE_CLASS = Continuable.class.getName(); private static final String STACK_METHOD = "get"; private static final String POP_METHOD = "pop"; private static final String PUSH_METHOD = "push"; private static final String RESTORING_FIELD = "isRestoring"; private static final String CAPTURING_FIELD = "isCapturing"; private boolean currentMethodStatic = false; public static boolean debug = false; /** * BCEL uses a repository object to load/store information related to other classes, * which are sometimes necessary to perform bytecode instrumentation. *

* Can be null, in which case the global BCEL repository is assumed to work. * *

* repository is a singleton instance in BCEL, so we have to be careful when changing it. * See BugZilla 38057. This is fundamentally broken. */ private org.apache.bcel.util.Repository repository; /** * Since BCEL repository is a global resource, access needs to be controlled among * {@link BcelClassTransformer} instances. */ private static final Object repositoryLock = new Object(); static { try { debug = System.getProperty(BcelClassTransformer.class.getName()+".debug")!=null; } catch (SecurityException e) { // assume no debugging } } public BcelClassTransformer() { } public BcelClassTransformer(org.apache.bcel.util.Repository repository) { this.repository = repository; } public byte[] transform(final byte[] original) { if(repository==null) { return doTransform(original); } else { synchronized(repositoryLock) { org.apache.bcel.util.Repository old = Repository.getRepository(); Repository.setRepository(repository); try { return doTransform(original); } finally { Repository.setRepository(old); } } } } private byte[] doTransform(final byte[] original) { final InputStream is = new ByteArrayInputStream(original); final ClassParser parser = new ClassParser(is, null); JavaClass javaClazz = null; try { javaClazz = parser.parse(); } catch (ClassFormatException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } Repository.addClass(javaClazz); log.debug("transforming class " + javaClazz.getClassName()); //final JavaClass clazz = Repository.lookupClass(clazzName); {// check if this class is already instrumented String[] intfs = javaClazz.getInterfaceNames(); for( int i=0; i no Instruction was executed before // => Top-Level routine (no jsr call before) ics.add(start); ecs.add(ExecutionPath.EMPTY); while (!ics.isEmpty()) { final InstructionContext u = (InstructionContext) ics.remove(0); final ExecutionPath oldchain = (ExecutionPath) ecs.remove(0); final ExecutionPath newchain = oldchain.append(u); if ((u.getInstruction().getInstruction()) instanceof RET) { // where did we come from? this JSR InstructionHandle jsr = oldchain.lastExecutionJSR().getInstruction(); // so the next instruction to execute will be this final InstructionContext theSuccessor = cfg.contextOf(jsr.getNext()); if (theSuccessor.execute(u.getOutFrame(oldchain), newchain, ev)) { ics.add(theSuccessor); ecs.add(newchain); } } else { // "not a ret" // Normal successors. Add them to the queue of successors. final InstructionContext[] succs = u.getSuccessors(); for (int s = 0; s < succs.length; s++) { final InstructionContext v = succs[s]; //if (v.execute(u.getOutFrame(oldchain), newchain, icv, ev)) { if (v.execute(u.getOutFrame(oldchain), newchain, ev)) { ics.add(v); ecs.add(newchain); } } } // Exception Handlers. Add them to the queue of successors. final ExceptionHandler[] exc_hds = u.getExceptionHandlers(); for (int s = 0; s < exc_hds.length; s++) { final InstructionContext v = cfg.contextOf(exc_hds[s].getHandlerStart()); // TODO: the "oldchain" and "newchain" is used to determine the // subroutine // we're in (by searching for the last JSR) by the // InstructionContext // implementation. Therefore, we should not use this chain // mechanism // when dealing with exception handlers. final LocalVariables newLocals = u.getOutFrame(oldchain).getLocals(); final OperandStack newStack = new OperandStack( u.getOutFrame(oldchain).getStack().maxStack(), (exc_hds[s].getExceptionType() == null ? Type.THROWABLE : exc_hds[s] .getExceptionType())); final Frame newFrame = new Frame(newLocals, newStack); if (v.execute(newFrame, ExecutionPath.EMPTY, ev)) { ics.add(v); ecs.add(ExecutionPath.EMPTY); } } } } /** * Creates a {@link Frame} object that represents the state of the stack frame * at the beginning of a method. */ private Frame craeteInitialFrame(MethodGen method, ClassGen clazz) { final Frame vanillaFrame = new Frame(method.getMaxLocals(), method.getMaxStack()); if (!method.isStatic()) { if (method.getName().equals(Constants.CONSTRUCTOR_NAME)) { Frame._this = new UninitializedObjectType(new ObjectType(clazz.getClassName())); vanillaFrame.getLocals().set(0, new UninitializedObjectType(new ObjectType(clazz.getClassName()))); } else { Frame._this = null; vanillaFrame.getLocals().set(0, new ObjectType(clazz.getClassName())); } } // fill local variables with parameter types final Type[] argtypes = method.getArgumentTypes(); int twoslotoffset = 0; for (int j = 0; j < argtypes.length; j++) { if ((argtypes[j] == Type.SHORT) || (argtypes[j] == Type.BYTE) || (argtypes[j] == Type.CHAR) || (argtypes[j] == Type.BOOLEAN)) { argtypes[j] = Type.INT; } vanillaFrame.getLocals().set(twoslotoffset + j + (method.isStatic() ? 0 : 1), argtypes[j]); if (argtypes[j].getSize() == 2) { twoslotoffset++; vanillaFrame.getLocals().set(twoslotoffset + j + (method.isStatic() ? 0 : 1), Type.UNKNOWN); } } return vanillaFrame; } private void rewrite(MethodGen method, ControlFlowGraph cfg) throws ClassNotFoundException { final InstructionFactory insFactory = new InstructionFactory(method.getConstantPool()); final Vector invokeIns = new Vector(); final InstructionList insList = method.getInstructionList(); InstructionHandle ins = insList.getStart(); final InstructionList restorer = new InstructionList(); int count = 0; // count # of breakpoints // we need to expand the local variable size to store arguments for the constructor invocation. // compute the necessary size in this variable. int[] localVarsSize = new int[1]; localVarsSize[0] = method.getMaxLocals(); while (ins != null) { InstructionHandle next = ins.getNext(); // if not traversed by the analyser, then don't rewrite InstructionContext context = null; Frame frame = null; try { context = cfg.contextOf(ins); frame = context.getOutFrame(ExecutionPath.EMPTY); } catch (AssertionViolatedException ave) { // empty } if (frame != null) { if (rewriteable(method, ins)) { // Add frame saver and restorer for the current breakpoint // determine type of object for the method invocation final InvokeInstruction invoke = (InvokeInstruction) ins.getInstruction(); final Type[] arguments = invoke.getArgumentTypes(method.getConstantPool()); ReferenceType objecttype = null; if (!(invoke instanceof INVOKESTATIC)) { objecttype = (ReferenceType) context.getInFrame().getStack().peek(arguments.length); } final InstructionList rList = restoreFrame(method, ins, insFactory, frame, objecttype); insList.append(ins, saveFrame(method, ins, count++, insFactory, frame)); invokeIns.addElement(rList.getStart()); restorer.append(rList); } // remove all new's if (ins.getInstruction().getOpcode() == Constants.NEW) { try { // remove additional dup's while (next != null && next.getInstruction().getOpcode() == Constants.DUP) { context = cfg.contextOf(next); context.getOutFrame(ExecutionPath.EMPTY); final InstructionHandle newnext = next.getNext(); insList.delete(next); next = newnext; } // if there are any dup_x2 following new and dup, replace them with dup. // some java compiler generates such bytecode for code like // someObject.someStringField += "abc" // // which yield // NEW StringBuffer // DUP // ALOAD // someObject // DUP_x2 // GETFIELD someStringField // INVOKESPECIAL StringBuffer. // LDC "abc" // INVOKEVIRTUAL StringBuffer.append // INVOKEVIRTUAL StringBuffer.toString // PUTFIELD someStringField // // replacing this DUP_x2 -> DUP is required for moving the new. if(next!=null && next.getNext()!=null && next.getNext().getInstruction().getOpcode() == Constants.DUP_X2) { InstructionHandle dupx2ptr = next.getNext(); final InstructionHandle newnext = dupx2ptr.getNext(); insList.insert(dupx2ptr, InstructionConstants.DUP); insList.delete(dupx2ptr); next = newnext; } final InstructionTargeter[] targeter = ins.getTargeters(); if (targeter != null) { final InstructionHandle newnext = ins.getNext(); for (int i = 0; i < targeter.length; i++) { targeter[i].updateTarget(ins, newnext); } } insList.delete(ins); } catch (TargetLostException tle) { throw new ClassNotFoundException(tle.getMessage(), tle); } } else if (ins.getInstruction().getOpcode() == Constants.INVOKESPECIAL) { // duplicate stack before invokespecial to insert // uninitialized object frame = context.getInFrame(); final InvokeInstruction invoke = (InvokeInstruction) ins.getInstruction(); final Type[] arguments = invoke.getArgumentTypes(method.getConstantPool()); final OperandStack os = frame.getStack(); final Type type = os.peek(arguments.length); if (type instanceof UninitializedObjectType) { final ObjectType objecttype = ((UninitializedObjectType) type).getInitialized(); final InstructionList duplicator = duplicateStack(method, invoke, objecttype, localVarsSize); final InstructionTargeter[] targeter = ins.getTargeters(); if (targeter != null) { final InstructionHandle newnext = duplicator.getStart(); for (int i = 0; i < targeter.length; i++) { targeter[i].updateTarget(ins, newnext); } } insList.insert(ins, duplicator); } } } ins = next; } // local variable index for storing the StackRecorder object final int varStack = method.getMaxLocals(); // instruction to load the stack recorder Instruction loadStackRecorder = InstructionFactory.createLoad(STACK_RECORDER_TYPE, varStack); final InstructionHandle firstIns = insList.getStart(); if (count > 0) { final InstructionHandle[] tableTargets = new InstructionHandle[count]; int[] match = new int[count]; for (int i = 0; i < count; i++) { match[i] = i; } invokeIns.copyInto(tableTargets); insList.insert(restorer); // select frame restorer insList.insert(new TABLESWITCH(match, tableTargets, firstIns)); insList.insert(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(Type.INT), Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); insList.insert(loadStackRecorder); // test if the continuation should be restored insList.insert(new IFEQ(firstIns)); insList.insert(insFactory.createFieldAccess(STACK_RECORDER_CLASS, RESTORING_FIELD, Type.BOOLEAN, Constants.GETFIELD)); insList.insert(loadStackRecorder); // test if no current continuation exists insList.insert(new IFNULL(firstIns)); // get current continuation and store in the next to last local variable insList.insert(InstructionFactory.createStore(STACK_RECORDER_TYPE, varStack)); insList.insert(InstructionConstants.DUP); insList.insert(insFactory.createInvoke(STACK_RECORDER_CLASS, STACK_METHOD, STACK_RECORDER_TYPE, Type.NO_ARGS, Constants.INVOKESTATIC)); // we need one more variable for storing StackRecorder localVarsSize[0] = Math.max( localVarsSize[0], method.getMaxLocals()+1 ); // make room for additional object (StackRecorder) method.setMaxStack(method.getMaxStack() + 2); } method.setMaxLocals(localVarsSize[0]); // make room for additional 'null' we push on the stack to clear // the local variables that are used during the constructor invocation instrumentation. // ideally we should be able to determine when we need to add +1, but for now just to be // safe and let's always add this. method.setMaxStack(method.getMaxStack() + 1); // remove LocalVariableTypeTable attribute until BCEL #33549 is fixed, // so that JDK 5.0 classes can be instrumented correctly. // see http://issues.apache.org/bugzilla/show_bug.cgi?id=33549 Attribute[] atts = method.getCodeAttributes(); for( int i=0; i= 0; i--) { Type type = arguments[i]; insList.append(InstructionFactory.createStore(type,localVarOffset)); localVarOffset += type.getSize(); } localVarsSize[0] = Math.max(localVarsSize[0],localVarOffset); // create uninitialzed object insList.append(insFactory.createNew(objecttype)); insList.append(InstructionConstants.DUP); // move the arguments back into the operand stack for (int i = 0; i < arguments.length; i++) { Type type = arguments[i]; localVarOffset -= type.getSize(); insList.append(InstructionFactory.createLoad(type,localVarOffset)); if(type instanceof ReferenceType) { // erase the local variable, or else we have a potential for memory leak insList.append(InstructionConstants.ACONST_NULL); insList.append(InstructionFactory.createStore(type,localVarOffset)); } } return insList; } private boolean rewriteable(MethodGen method, InstructionHandle handle) { // check in the invocation can be a breakpoint. int opcode = handle.getInstruction().getOpcode(); if(!(handle.getInstruction() instanceof InvokeInstruction)) return false; // not an INVOKE*** if (opcode == Constants.INVOKESPECIAL) { final InvokeInstruction ivs = (InvokeInstruction) handle.getInstruction(); final String mName = ivs.getMethodName(method.getConstantPool()); if(mName.equals(Constants.CONSTRUCTOR_NAME)) return false; // can't instrument the constructor invocation } // final int index = ((InvokeInstruction) handle.getInstruction()).getIndex(); // final String classname = getObjectType(method.getConstantPool().getConstantPool(), index).getClassName(); // rewrite invocation if object is continuable or a continuation // object // FIXME: //return Repository.implementationOf(classname, CONTINUABLE_CLASS) || Repository.instanceOf(classname, CONTINUATION_CLASS); return true; } private InstructionList saveFrame(MethodGen method, InstructionHandle handle, int pc, InstructionFactory insFactory, Frame frame) { final InstructionList insList = new InstructionList(); // Remove needless return type from stack final InvokeInstruction inv = (InvokeInstruction) handle.getInstruction(); final Type returnType = getReturnType(method.getConstantPool().getConstantPool(), inv.getIndex()); if (returnType.getSize() > 0) { insList.insert(InstructionFactory.createPop(returnType.getSize())); } boolean skipFirst = returnType.getSize() > 0; //if (debug) { // insList.append(insFactory.createPrintln("save stack")); //} // instruction for loading StackRecorder Instruction loadStackRecorder = InstructionFactory.createLoad(STACK_RECORDER_TYPE, method.getMaxLocals()); // save stack final OperandStack os = frame.getStack(); for (int i = skipFirst ? 1 : 0; i < os.size(); i++) { Type type = os.peek(i); if (type instanceof BasicType) { if (type.getSize() < 2 && !type.equals(Type.FLOAT)) { type = Type.INT; } // check for types with two words on stack if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) { insList.append(InstructionConstants.ACONST_NULL); // create dummy stack entry insList.append(loadStackRecorder); insList.append(InstructionConstants.DUP2_X2); // swap Stack object and long/float insList.append(InstructionConstants.POP2); } else { insList.append(loadStackRecorder); insList.append(InstructionConstants.SWAP); } insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(type), Type.VOID, new Type[] { type }, Constants.INVOKEVIRTUAL)); if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) insList.append(InstructionConstants.POP); // remove dummy stack entry } else if (type == null) { insList.append(InstructionConstants.POP); } else if (type instanceof UninitializedObjectType) { // After the remove of new, there shouldn't be a // uninitialized object on the stack } else if (type instanceof ReferenceType) { if(type.equals(Type.NULL)) { // if it's guaranteed to be null, no need to store. // in fact, we can't really store this, because we'll never // be able to restore it as the 'null' type. insList.append(InstructionConstants.POP); } else { insList.append(loadStackRecorder); insList.append(InstructionConstants.SWAP); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(Type.OBJECT), Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); } } } // add isCapturing test if (debug) { insList.insert(insFactory.createPrintln("capturing invocation "+method)); } insList.insert(new IFEQ(handle.getNext())); // test if the continuation should be captured after the invocation insList.insert(insFactory.createFieldAccess(STACK_RECORDER_CLASS, CAPTURING_FIELD, Type.BOOLEAN, Constants.GETFIELD)); insList.insert(loadStackRecorder); // test if continuation exists insList.insert(new IFNULL(handle.getNext())); insList.insert(loadStackRecorder); // save local variables //if (debug) { // insList.append(insFactory.createPrintln("save local variables")); //} final LocalVariables lvs = frame.getLocals(); for (int i = 0; i < lvs.maxLocals(); i++) { Type type = lvs.get(i); if (type instanceof BasicType) { insList.append(loadStackRecorder); insList.append(InstructionFactory.createLoad(type, i)); if (type.getSize() < 2 && !type.equals(Type.FLOAT)) type = Type.INT; insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(type), Type.VOID, new Type[] { type }, Constants.INVOKEVIRTUAL)); } else if (type == null || type==Type.NULL) { // no need to save null } else if (type instanceof UninitializedObjectType) { // no need to save uninitialized objects } else if (type instanceof ReferenceType) { if (i == 0 && !currentMethodStatic) { // remember current object insList.append(loadStackRecorder); insList.append(InstructionFactory.createLoad(type, i)); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, PUSH_METHOD + "Reference", Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); } insList.append(loadStackRecorder); insList.append(InstructionFactory.createLoad(type, i)); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(Type.OBJECT), Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); } } // save programcounter insList.append(loadStackRecorder); insList.append(new PUSH(method.getConstantPool(), pc)); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(Type.INT), Type.VOID, new Type[] { Type.INT }, Constants.INVOKEVIRTUAL)); // return NULL result insList.append(InstructionFactory.createNull(method.getReturnType())); insList.append(InstructionFactory.createReturn(method.getReturnType())); return insList; } private InstructionList restoreFrame(MethodGen method, InstructionHandle handle, InstructionFactory insFactory, Frame frame, ReferenceType objecttype) { final InstructionList insList = new InstructionList(); // restore local variables //if (debug) { // insList.append(insFactory.createPrintln("restore local variables")); //} final LocalVariables lvs = frame.getLocals(); Instruction loadStackRecorder = InstructionFactory.createLoad(STACK_RECORDER_TYPE, method.getMaxLocals()); for (int i = lvs.maxLocals() - 1; i >= 0; i--) { Type type = lvs.get(i); if (type instanceof BasicType) { insList.append(loadStackRecorder); if (type.getSize() < 2 && !type.equals(Type.FLOAT)) { type = Type.INT; } insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(type), type, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); insList.append(InstructionFactory.createStore(type, i)); } else if (type == null) { insList.append(InstructionConstants.ACONST_NULL); insList.append(new ASTORE(i)); } else if (type instanceof UninitializedObjectType) { // No uninitilaized objects should be found // in the local variables. throw new Error("assertion failure"); } else if (type instanceof ReferenceType) { if (type==Type.NULL) { // null type is a special type assignable to any type, // whereas popObject returns a java/lang/Object. // the saveFrame method is written so that we don't save the 'null' object insList.append(InstructionConstants.ACONST_NULL); } else { insList.append(loadStackRecorder); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(Type.OBJECT), Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); if (!type.equals(Type.OBJECT)) { insList.append(insFactory.createCast(Type.OBJECT, type)); } } insList.append(new ASTORE(i)); } } final InvokeInstruction inv = (InvokeInstruction) handle.getInstruction(); final Type returnType = getReturnType(method.getConstantPool().getConstantPool(), inv.getIndex()); boolean skipFirst = returnType.getSize() > 0; // restore stack //if (debug) { // insList.append(insFactory.createPrintln("restore stack")); //} final OperandStack os = frame.getStack(); for (int i = os.size() - 1; i >= (skipFirst ? 1 : 0); i--) { Type type = os.peek(i); if (type instanceof BasicType) { if (type.getSize() < 2 && !type.equals(Type.FLOAT)) { type = Type.INT; } insList.append(loadStackRecorder); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(type), type, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); } else if (type == null || type==Type.NULL) { insList.append(new ACONST_NULL()); } else if (type instanceof UninitializedObjectType) { // After the remove of new, there shouldn't be a // uninitialized object on the stack } else if (type instanceof ReferenceType) { insList.append(loadStackRecorder); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(Type.OBJECT), Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); if (!type.equals(Type.OBJECT)) insList.append(insFactory.createCast(Type.OBJECT, type)); } } // retrieve current object if (!(inv instanceof INVOKESTATIC)) { insList.append(loadStackRecorder); insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, POP_METHOD + "Reference", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); insList.append(insFactory.createCast(Type.OBJECT, objecttype)); } // Create null types for the parameters of the method invocation final Type[] paramTypes = getParamTypes(method.getConstantPool().getConstantPool(), inv.getIndex()); for (int j = 0; j < paramTypes.length; j++) { insList.append(InstructionFactory.createNull(paramTypes[j])); } // go to last invocation insList.append(new GOTO(handle)); return insList; } private Type[] getParamTypes(ConstantPool cp, int index) { final ConstantCP cmr = (ConstantCP) cp.getConstant(index); final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); final String sig = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); return Type.getArgumentTypes(sig); } private Type getReturnType(ConstantPool cp, int index) { final ConstantCP cmr = (ConstantCP) cp.getConstant(index); final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); final String sig = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); return Type.getReturnType(sig); } private String getPopMethod(Type type) { return POP_METHOD + getTypeSuffix(type); } private String getPushMethod(Type type) { return PUSH_METHOD + getTypeSuffix(type); } private String getTypeSuffix(Type type) { if (type.equals(Type.BOOLEAN)) return "Int"; else if (type.equals(Type.CHAR)) return "Int"; else if (type.equals(Type.FLOAT)) return "Float"; else if (type.equals(Type.DOUBLE)) return "Double"; else if (type.equals(Type.BYTE)) return "Int"; else if (type.equals(Type.SHORT)) return "Int"; else if (type.equals(Type.INT)) return "Int"; else if (type.equals(Type.LONG)) return "Long"; // VOID and OBJECT are "Object" return "Object"; } }././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000755000175000017500000000000011135725056033215 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/UninitializedObjectType.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000000405210276745044033224 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.*; import org.apache.bcel.generic.*; /** * This class represents an uninitialized object type; see The Java * Virtual Machine Specification, Second Edition, page 147: 4.9.4 for * more details. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: UninitializedObjectType.java 231525 2005-08-11 21:59:00Z tcurdt $ * @author Enver Haase */ public class UninitializedObjectType extends ReferenceType implements Constants { private static final long serialVersionUID = 1L; /** The "initialized" version. */ private ObjectType initialized; /** Creates a new instance. */ public UninitializedObjectType(ObjectType t){ super(T_UNKNOWN, ""); initialized = t; } /** * Returns the ObjectType of the same class as the one of the uninitialized object * represented by this UninitializedObjectType instance. */ public ObjectType getInitialized(){ return initialized; } /** * Returns true on equality of this and o. * Equality means the ObjectType instances of "initialized" * equal one another in this and the o instance. * */ public boolean equals(Object o){ if (! (o instanceof UninitializedObjectType)) return false; return initialized.equals(((UninitializedObjectType)o).initialized); } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ExceptionHandler.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000000347610276745044033235 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.generic.*; /** * This class represents an exception handler; that is, an ObjectType * representing a subclass of java.lang.Throwable and the instruction * the handler starts off (represented by an InstructionContext). * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: ExceptionHandler.java 231525 2005-08-11 21:59:00Z tcurdt $ * @author Enver Haase */ public class ExceptionHandler{ /** The type of the exception to catch. NULL means ANY. */ private ObjectType catchtype; /** The InstructionHandle where the handling begins. */ private InstructionHandle handlerpc; /** Leave instance creation to JustIce. */ ExceptionHandler(ObjectType catch_type, InstructionHandle handler_pc){ catchtype = catch_type; handlerpc = handler_pc; } /** * Returns the type of the exception that's handled. 'null' means 'ANY'. */ public ObjectType getExceptionType(){ return catchtype; } /** * Returns the InstructionHandle where the handler starts off. */ public InstructionHandle getHandlerStart(){ return handlerpc; } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ExecutionPath.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000000407110354613557033225 0ustar drazzibdrazzibpackage org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.generic.Instruction; import org.apache.bcel.generic.RET; import org.apache.bcel.generic.JsrInstruction; /** * List of {@link InstructionContext} that represents a sequence of an execution. * *

* This object is immutable. * The sequence is represented in left-associative style; that is, * a sequence of [a,b,c,d] is represented as prev=[a,b,c] and last=d. * * @author Kohsuke Kawaguchi */ public final class ExecutionPath { /** * Singleton {@link ExecutionPath} that represents an empty sequence []. */ public static final ExecutionPath EMPTY = new ExecutionPath(null,null); private final ExecutionPath prev; private final InstructionContext last; private ExecutionPath(ExecutionPath prev, InstructionContext last) { this.prev = prev; this.last = last; } /** * Creates a new {@link ExecutionPath} that has * [... list in this ExecutionPath ..., ins]. */ public ExecutionPath append(InstructionContext ins) { return new ExecutionPath(this,ins); } /** * Returns the InstructionContextImpl with an JSR/JSR_W * that was last in the ExecutionChain, without * a corresponding RET, i.e. * we were called by this one. * Returns null if we were called from the top level. */ public InstructionContext lastExecutionJSR(){ int retcount = 0; for( ExecutionPath ptr = this; ptr!=EMPTY; ptr=ptr.prev) { Instruction i = ptr.last.getInstruction().getInstruction(); if (i instanceof RET) retcount++; if (i instanceof JsrInstruction){ retcount--; if (retcount == -1) return ptr.last; } } return null; } /** * Returns a human readable representation. */ public String toString() { if(this==EMPTY) return ""; else { return prev.toString()+"\n"+last.toString(); } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ExecutionVisitor.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000010401310277504135033215 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Constant; import org.apache.bcel.classfile.ConstantDouble; import org.apache.bcel.classfile.ConstantFloat; import org.apache.bcel.classfile.ConstantInteger; import org.apache.bcel.classfile.ConstantLong; import org.apache.bcel.classfile.ConstantString; import org.apache.bcel.classfile.ConstantClass; import org.apache.bcel.generic.*; /** * This Visitor class may be used for a type-based Java Virtual Machine * simulation. * It does not check for correct types on the OperandStack or in the * LocalVariables; nor does it check their sizes are sufficiently big. * Thus, to use this Visitor for bytecode verifying, you have to make sure * externally that the type constraints of the Java Virtual Machine instructions * are satisfied. An InstConstraintVisitor may be used for this. * Anyway, this Visitor does not mandate it. For example, when you * visitIADD(IADD o), then there are two stack slots popped and one * stack slot containing a Type.INT is pushed (where you could also * pop only one slot if you know there are two Type.INT on top of the * stack). Monitor-specific behaviour is not simulated. * *

Conventions: * * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG * that would normally take up two stack slots (like Double_HIGH and * Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG * object on the stack here. * If a two-slot type is stored into a local variable, the next variable * is given the type Type.UNKNOWN. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: ExecutionVisitor.java 232547 2005-08-13 23:55:09Z kohsuke $ * @author Enver Haase * @see #visitDSTORE(DSTORE o) * @see org.apache.bcel.verifier.structurals.InstConstraintVisitor */ public class ExecutionVisitor extends EmptyVisitor implements Visitor{ /** * The executionframe we're operating on. */ private Frame frame = null; /** * The ConstantPoolGen we're working with. * @see #setConstantPoolGen(ConstantPoolGen) */ private ConstantPoolGen cpg = null; /** * Constructor. Constructs a new instance of this class. */ public ExecutionVisitor(){} /** * The OperandStack from the current Frame we're operating on. * @see #setFrame(Frame) */ private OperandStack stack(){ return frame.getStack(); } /** * The LocalVariables from the current Frame we're operating on. * @see #setFrame(Frame) */ private LocalVariables locals(){ return frame.getLocals(); } /** * Sets the ConstantPoolGen needed for symbolic execution. */ public void setConstantPoolGen(ConstantPoolGen cpg){ this.cpg = cpg; } /** * The only method granting access to the single instance of * the ExecutionVisitor class. Before actively using this * instance, SET THE ConstantPoolGen FIRST. * @see #setConstantPoolGen(ConstantPoolGen) */ public void setFrame(Frame f){ this.frame = f; } ///** Symbolically executes the corresponding Java Virtual Machine instruction. */ //public void visitWIDE(WIDE o){ // The WIDE instruction is modelled as a flag // of the embedded instructions in BCEL. // Therefore BCEL checks for possible errors // when parsing in the .class file: We don't // have even the possibilty to care for WIDE // here. //} /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitAALOAD(AALOAD o){ stack().pop(); // pop the index int //System.out.print(stack().peek()); Type t = stack().pop(); // Pop Array type if (t == Type.NULL){ stack().push(Type.NULL); } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time else{ ArrayType at = (ArrayType) t; stack().push(at.getElementType()); } } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitAASTORE(AASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitACONST_NULL(ACONST_NULL o){ stack().push(Type.NULL); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitALOAD(ALOAD o){ stack().push(locals().get(o.getIndex())); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitANEWARRAY(ANEWARRAY o){ stack().pop(); //count stack().push( new ArrayType(o.getType(cpg), 1) ); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitARETURN(ARETURN o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitARRAYLENGTH(ARRAYLENGTH o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitASTORE(ASTORE o){ locals().set(o.getIndex(), stack().pop()); //System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'."); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitATHROW(ATHROW o){ Type t = stack().pop(); stack().clear(); if (t.equals(Type.NULL)) stack().push(Type.getType("Ljava/lang/NullPointerException;")); else stack().push(t); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitBALOAD(BALOAD o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitBASTORE(BASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitBIPUSH(BIPUSH o){ stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitCALOAD(CALOAD o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitCASTORE(CASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitCHECKCAST(CHECKCAST o){ // It's possibly wrong to do so, but SUN's // ByteCode verifier seems to do (only) this, too. // TODO: One could use a sophisticated analysis here to check // if a type cannot possibly be cated to another and by // so doing predict the ClassCastException at run-time. stack().pop(); stack().push(o.getType(cpg)); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitD2F(D2F o){ stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitD2I(D2I o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitD2L(D2L o){ stack().pop(); stack().push(Type.LONG); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDADD(DADD o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDALOAD(DALOAD o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDASTORE(DASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDCMPG(DCMPG o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDCMPL(DCMPL o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDCONST(DCONST o){ stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDDIV(DDIV o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDLOAD(DLOAD o){ stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDMUL(DMUL o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDNEG(DNEG o){ stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDREM(DREM o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDRETURN(DRETURN o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDSTORE(DSTORE o){ locals().set(o.getIndex(), stack().pop()); locals().set(o.getIndex()+1, Type.UNKNOWN); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDSUB(DSUB o){ stack().pop(); stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP(DUP o){ Type t = stack().pop(); stack().push(t); stack().push(t); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP_X1(DUP_X1 o){ Type w1 = stack().pop(); Type w2 = stack().pop(); stack().push(w1); stack().push(w2); stack().push(w1); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP_X2(DUP_X2 o){ Type w1 = stack().pop(); Type w2 = stack().pop(); if (w2.getSize() == 2){ stack().push(w1); stack().push(w2); stack().push(w1); } else{ Type w3 = stack().pop(); stack().push(w1); stack().push(w3); stack().push(w2); stack().push(w1); } } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP2(DUP2 o){ Type t = stack().pop(); if (t.getSize() == 2){ stack().push(t); stack().push(t); } else{ // t.getSize() is 1 Type u = stack().pop(); stack().push(u); stack().push(t); stack().push(u); stack().push(t); } } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP2_X1(DUP2_X1 o){ Type t = stack().pop(); if (t.getSize() == 2){ Type u = stack().pop(); stack().push(t); stack().push(u); stack().push(t); } else{ //t.getSize() is1 Type u = stack().pop(); Type v = stack().pop(); stack().push(u); stack().push(t); stack().push(v); stack().push(u); stack().push(t); } } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitDUP2_X2(DUP2_X2 o){ Type t = stack().pop(); if (t.getSize() == 2){ Type u = stack().pop(); if (u.getSize() == 2){ stack().push(t); stack().push(u); stack().push(t); }else{ Type v = stack().pop(); stack().push(t); stack().push(v); stack().push(u); stack().push(t); } } else{ //t.getSize() is 1 Type u = stack().pop(); Type v = stack().pop(); if (v.getSize() == 2){ stack().push(u); stack().push(t); stack().push(v); stack().push(u); stack().push(t); }else{ Type w = stack().pop(); stack().push(u); stack().push(t); stack().push(w); stack().push(v); stack().push(u); stack().push(t); } } } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitF2D(F2D o){ stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitF2I(F2I o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitF2L(F2L o){ stack().pop(); stack().push(Type.LONG); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFADD(FADD o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFALOAD(FALOAD o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFASTORE(FASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFCMPG(FCMPG o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFCMPL(FCMPL o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFCONST(FCONST o){ stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFDIV(FDIV o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFLOAD(FLOAD o){ stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFMUL(FMUL o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFNEG(FNEG o){ stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFREM(FREM o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFRETURN(FRETURN o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFSTORE(FSTORE o){ locals().set(o.getIndex(), stack().pop()); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitFSUB(FSUB o){ stack().pop(); stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitGETFIELD(GETFIELD o){ stack().pop(); Type t = o.getFieldType(cpg); if ( t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT) ) t = Type.INT; stack().push(t); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitGETSTATIC(GETSTATIC o){ Type t = o.getFieldType(cpg); if ( t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT) ) t = Type.INT; stack().push(t); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitGOTO(GOTO o){ // no stack changes. } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitGOTO_W(GOTO_W o){ // no stack changes. } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2B(I2B o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2C(I2C o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2D(I2D o){ stack().pop(); stack().push(Type.DOUBLE); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2F(I2F o){ stack().pop(); stack().push(Type.FLOAT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2L(I2L o){ stack().pop(); stack().push(Type.LONG); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitI2S(I2S o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIADD(IADD o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIALOAD(IALOAD o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIAND(IAND o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIASTORE(IASTORE o){ stack().pop(); stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitICONST(ICONST o){ stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIDIV(IDIV o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ACMPEQ(IF_ACMPEQ o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ACMPNE(IF_ACMPNE o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPEQ(IF_ICMPEQ o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPGE(IF_ICMPGE o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPGT(IF_ICMPGT o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPLE(IF_ICMPLE o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPLT(IF_ICMPLT o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIF_ICMPNE(IF_ICMPNE o){ stack().pop(); stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFEQ(IFEQ o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFGE(IFGE o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFGT(IFGT o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFLE(IFLE o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFLT(IFLT o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFNE(IFNE o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFNONNULL(IFNONNULL o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIFNULL(IFNULL o){ stack().pop(); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIINC(IINC o){ // stack is not changed. } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitILOAD(ILOAD o){ stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitIMUL(IMUL o){ stack().pop(); stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitINEG(INEG o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitINSTANCEOF(INSTANCEOF o){ stack().pop(); stack().push(Type.INT); } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ stack().pop(); //objectref for (int i=0; iEnver Haase */ public class OperandStack{ /** We hold the stack information here. */ private ArrayList stack = new ArrayList(); /** The maximum number of stack slots this OperandStack instance may hold. */ private int maxStack; /** * Creates an empty stack with a maximum of maxStack slots. */ public OperandStack(int maxStack){ this.maxStack = maxStack; } /** * Creates an otherwise empty stack with a maximum of maxStack slots and * the ObjectType 'obj' at the top. */ public OperandStack(int maxStack, ObjectType obj){ this.maxStack = maxStack; this.push(obj); } /** * Returns a deep copy of this object; that means, the clone operates * on a new stack. However, the Type objects on the stack are * shared. */ protected Object clone(){ OperandStack newstack = new OperandStack(this.maxStack); newstack.stack = (ArrayList) this.stack.clone(); return newstack; } /** * Clears the stack. */ public void clear(){ stack = new ArrayList(); } /** * Returns true if and only if this OperandStack * equals another, meaning equal lengths and equal * objects on the stacks. */ public boolean equals(Object o){ if (!(o instanceof OperandStack)) return false; OperandStack s = (OperandStack) o; return this.stack.equals(s.stack); } /** * Returns a (typed!) clone of this. * * @see #clone() */ public OperandStack getClone(){ return (OperandStack) this.clone(); } /** * Returns true IFF this OperandStack is empty. */ public boolean isEmpty(){ return stack.isEmpty(); } /** * Returns the number of stack slots this stack can hold. */ public int maxStack(){ return this.maxStack; } /** * Returns the element on top of the stack. The element is not popped off the stack! */ public Type peek(){ return peek(0); } /** * Returns the element that's i elements below the top element; that means, * iff i==0 the top element is returned. The element is not popped off the stack! */ public Type peek(int i){ return (Type) stack.get(size()-i-1); } /** * Returns the element on top of the stack. The element is popped off the stack. */ public Type pop(){ Type e = (Type) stack.remove(size()-1); return e; } /** * Pops i elements off the stack. ALWAYS RETURNS "null"!!! */ public Type pop(int i){ for (int j=0; j= maxStack){ throw new AssertionViolatedException("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "+this); } stack.add(type); } /** * Returns the size of this OperandStack; that means, how many Type objects there are. */ public int size(){ return stack.size(); } /** * Returns the number of stack slots used. * @see #maxStack() */ public int slotsUsed(){ /* XXX change this to a better implementation using a variable that keeps track of the actual slotsUsed()-value monitoring all push()es and pop()s. */ int slots = 0; for (int i=0; iEnver Haase */ public class LocalVariables{ /** The Type[] containing the local variable slots. */ private Type[] locals; /** * Creates a new LocalVariables object. */ public LocalVariables(int maxLocals){ locals = new Type[maxLocals]; Arrays.fill(locals,Type.UNKNOWN); } /** * Returns a deep copy of this object; i.e. the clone * operates on a new local variable array. * However, the Type objects in the array are shared. */ protected Object clone(){ LocalVariables lvs = new LocalVariables(locals.length); System.arraycopy(this.locals, 0, lvs.locals, 0, locals.length); return lvs; } /** * Returns the type of the local variable slot i. */ public Type get(int i){ return locals[i]; } /** * Returns a (correctly typed) clone of this object. * This is equivalent to ((LocalVariables) this.clone()). */ public LocalVariables getClone(){ return (LocalVariables) this.clone(); } /** * Returns the number of local variable slots this * LocalVariables instance has. */ public int maxLocals(){ return locals.length; } /** * Sets a new Type for the given local variable slot. */ public void set(int i, Type type){ if (type == Type.BYTE || type == Type.SHORT || type == Type.BOOLEAN || type == Type.CHAR){ throw new AssertionViolatedException("LocalVariables do not know about '"+type+"'. Use Type.INT instead."); } locals[i] = type; } /* * Fulfills the general contract of Object.equals(). */ public boolean equals(Object o){ if (!(o instanceof LocalVariables)) return false; LocalVariables lv = (LocalVariables) o; return Arrays.equals(this.locals, lv.locals); } /** * Merges two local variables sets as described in the Java Virtual Machine Specification, * Second Edition, section 4.9.2, page 146. */ public void merge(LocalVariables that){ if (this.locals.length != that.locals.length){ throw new AssertionViolatedException("Merging LocalVariables of different size?!? From different methods or what?!?"); } for (int i=0; iEnver Haase */ public interface InstructionContext{ /** * This method symbolically executes the Instruction * held in the InstructionContext. * It "merges in" the incoming execution frame situation * (see The Java Virtual Machine Specification, 2nd * edition, page 146). * By so doing, the outgoing execution frame situation * is calculated. * * This method is JustIce-specific and is usually of * no sense for users of the ControlFlowGraph class. * They should use getInstruction().accept(Visitor), * possibly in conjunction with the ExecutionVisitor. * * WARNING! These classes are a fork of the bcel verifier. * * @see ControlFlowGraph * @see ExecutionVisitor * @see #getOutFrame(ArrayList) * @return true - if and only if the "outgoing" frame situation * changed from the one before execute()ing. */ boolean execute(Frame inFrame, ExecutionPath executionPredecessors, ExecutionVisitor ev); Frame getInFrame(); /** * This method returns the outgoing execution frame situation; * therefore it has to be calculated by execute(Frame, ArrayList) * first. * * @see #execute(Frame, ExecutionPath, ExecutionVisitor) */ Frame getOutFrame(ExecutionPath executionPredecessors); /** * Returns the InstructionHandle this InstructionContext is wrapped around. * * @return The InstructionHandle this InstructionContext is wrapped around. */ InstructionHandle getInstruction(); /** * Returns the usual control flow successors. * @see #getExceptionHandlers() */ InstructionContext[] getSuccessors(); /** * Returns the exception handlers that protect this instruction. * They are special control flow successors. */ ExceptionHandler[] getExceptionHandlers(); } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ExceptionHandlers.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000000442210276745044033225 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.generic.*; import java.util.HashSet; import java.util.Hashtable; /** * This class allows easy access to ExceptionHandler objects. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: ExceptionHandlers.java 231525 2005-08-11 21:59:00Z tcurdt $ * @author Enver Haase */ public class ExceptionHandlers{ /** * The ExceptionHandler instances. * Key: InstructionHandle objects, Values: HashSet instances. */ private Hashtable exceptionhandlers; /** * Constructor. Creates a new ExceptionHandlers instance. */ public ExceptionHandlers(MethodGen mg){ exceptionhandlers = new Hashtable(); CodeExceptionGen[] cegs = mg.getExceptionHandlers(); for (int i=0; iEnver Haase */ public class Frame{ /** * For instance initialization methods, it is important to remember * which instance it is that is not initialized yet. It will be * initialized invoking another constructor later. * NULL means the instance already *is* initialized. */ public static UninitializedObjectType _this; /** * */ private LocalVariables locals; /** * */ private OperandStack stack; /** * */ public Frame(int maxLocals, int maxStack){ locals = new LocalVariables(maxLocals); stack = new OperandStack(maxStack); } /** * */ public Frame(LocalVariables locals, OperandStack stack){ this.locals = locals; this.stack = stack; } /** * */ protected Object clone(){ Frame f = new Frame(locals.getClone(), stack.getClone()); return f; } /** * */ public Frame getClone(){ return (Frame) clone(); } /** * */ public LocalVariables getLocals(){ return locals; } /** * */ public OperandStack getStack(){ return stack; } /** * */ public boolean equals(Object o){ if (!(o instanceof Frame)) return false; // implies "null" is non-equal. Frame f = (Frame) o; return this.stack.equals(f.stack) && this.locals.equals(f.locals); } /** * Returns a String representation of the Frame instance. */ public String toString(){ String s="Local Variables:\n"; s += locals; s += "OperandStack:\n"; s += stack; return s; } /** * Merges two {@link Type}s into one. * * @param errorIfFailed * if true, attempting to merge two types that are incompatible causes an error. * if false, it yields {@link Type#UNKNOWN} value, indicating that value is unusable. */ /*package*/ static Type merge(Type lhs, Type rhs, boolean errorIfFailed) { try { // We won't accept an unitialized object if we know it was initialized; // compare vmspec2, 4.9.4, last paragraph. if ((!(lhs instanceof UninitializedObjectType)) && (rhs instanceof UninitializedObjectType)) { throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected."); } // Even harder, what about _different_ uninitialized object types?! if ((!(lhs.equals(rhs))) && (lhs instanceof UninitializedObjectType) && (rhs instanceof UninitializedObjectType)) { throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected."); } // If we just didn't know that it was initialized, we have now learned. if (lhs instanceof UninitializedObjectType) { if (! (rhs instanceof UninitializedObjectType)) { lhs = ((UninitializedObjectType) lhs).getInitialized(); } } if ((lhs instanceof ReferenceType) && (rhs instanceof ReferenceType)) { if(lhs.equals(rhs)) { return lhs; // same type } Type sup = ((ReferenceType) lhs).getFirstCommonSuperclass((ReferenceType) rhs); if (sup != null) { return sup; } else { // We should have checked this in Pass2! throw new AssertionViolatedException("Could not load all the super classes of '" + lhs + "' and '" + rhs + "'."); } } if ((lhs instanceof ReturnaddressType) && (rhs instanceof ReturnaddressType)) { // see 'FinallyFlow' test. return lhs; } if (!lhs.equals(rhs)) { if(errorIfFailed) { throw new StructuralCodeConstraintException("Cannot merge different types:"+lhs+" and "+rhs); } else { return Type.UNKNOWN; } } return lhs; } catch (ClassNotFoundException e) { // FIXME: maybe not the best way to handle this throw new AssertionViolatedException("Missing class: " + e.toString()); } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000003253010354613557033226 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import org.apache.bcel.generic.ATHROW; import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.GotoInstruction; import org.apache.bcel.generic.Instruction; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.JsrInstruction; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.RET; import org.apache.bcel.generic.ReturnInstruction; import org.apache.bcel.generic.Select; import org.apache.bcel.verifier.exc.AssertionViolatedException; import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; /** * This class represents a control flow graph of a method. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: ControlFlowGraph.java 359657 2005-12-28 22:53:35Z kohsuke $ * @author Enver Haase */ public class ControlFlowGraph{ /** * Objects of this class represent a node in a ControlFlowGraph. * These nodes are instructions, not basic blocks. */ private class InstructionContextImpl implements InstructionContext{ /** * The InstructionHandle this InstructionContext is wrapped around. */ private InstructionHandle instruction; /** * The 'incoming' execution Frames. */ private HashMap inFrames; // key: the last-executed JSR /** * The 'outgoing' execution Frames. */ private HashMap outFrames; // key: the last-executed JSR /** * The 'execution predecessors' - a list of {@link InstructionContext} * of those instances that have been execute()d before in that order. */ private ExecutionPath executionPredecessors = null; // Type: InstructionContext /** * Creates an InstructionHandleImpl object from an InstructionHandle. * Creation of one per InstructionHandle suffices. Don't create more. */ public InstructionContextImpl(InstructionHandle inst){ if (inst == null) throw new AssertionViolatedException("Cannot instantiate InstructionContextImpl from NULL."); instruction = inst; inFrames = new java.util.HashMap(); outFrames = new java.util.HashMap(); } /** * Returns the exception handlers of this instruction. */ public ExceptionHandler[] getExceptionHandlers(){ return exceptionhandlers.getExceptionHandlers(getInstruction()); } /** * Returns a clone of the "outgoing" frame situation with respect to the given ExecutionChain. */ public Frame getOutFrame(ExecutionPath execChain){ executionPredecessors = execChain; Frame org; InstructionContext jsr = lastExecutionJSR(); org = (Frame) outFrames.get(jsr); if (org == null){ throw new AssertionViolatedException("outFrame not set! This:\n"+this+"\nExecutionChain: "+getExecutionChain()+"\nOutFrames: '"+outFrames+"'."); } return org.getClone(); } public Frame getInFrame() { Frame org; InstructionContext jsr = lastExecutionJSR(); org = (Frame) inFrames.get(jsr); if (org == null){ throw new AssertionViolatedException("inFrame not set! This:\n"+this+"\nInFrames: '"+inFrames+"'."); } return org.getClone(); } /** * "Merges in" (vmspec2, page 146) the "incoming" frame situation; * executes the instructions symbolically * and therefore calculates the "outgoing" frame situation. * Returns: True iff the "incoming" frame situation changed after * merging with "inFrame". * The execPreds contain the InstructionContext * objects executed so far in the correct order. This is just * one execution path [out of many]. This is needed to correctly * "merge" in the special case of a RET's successor. * The InstConstraintVisitor and ExecutionVisitor instances * must be set up correctly. * @return true - if and only if the "outgoing" frame situation * changed from the one before execute()ing. */ public boolean execute(Frame inFrame, ExecutionPath execPreds, ExecutionVisitor ev){ // When merge failed, this is useful to see what are two passes ExecutionPath oldExecPreds = executionPredecessors; executionPredecessors = execPreds; //sanity check if ( (lastExecutionJSR() == null) && (subroutines.subroutineOf(getInstruction()) != subroutines.getTopLevel() ) ){ //throw new AssertionViolatedException("Huh?! Am I '"+this+"' part of a subroutine or not?"); return false; } if ( (lastExecutionJSR() != null) && (subroutines.subroutineOf(getInstruction()) == subroutines.getTopLevel() ) ){ //throw new AssertionViolatedException("Huh?! Am I '"+this+"' part of a subroutine or not?"); return false; } Frame inF = (Frame) inFrames.get(lastExecutionJSR()); if (inF == null){// no incoming frame was set, so set it. inFrames.put(lastExecutionJSR(), inFrame); inF = inFrame; } else{// if there was an "old" inFrame if (inF.equals(inFrame)){ //shortcut: no need to merge equal frames. return false; } if (! mergeInFrames(inFrame)){ return false; } } // Now we're sure the inFrame has changed! // new inFrame is already merged in, see above. Frame workingFrame = inF.getClone(); // This executes the Instruction. // Therefore the workingFrame object is modified. //ExecutionVisitor ev = ExecutionVisitor.getInstance(VerifierFactory.getVerifier(method_gen.getClassName())); ev.setFrame(workingFrame); getInstruction().accept(ev); //getInstruction().accept(ExecutionVisitor.withFrame(workingFrame)); outFrames.put(lastExecutionJSR(), workingFrame); return true; // new inFrame was different from old inFrame so merging them // yielded a different this.inFrame. } /** * Returns a simple String representation of this InstructionContext. */ public String toString(){ //TODO: Put information in the brackets, e.g. // Is this an ExceptionHandler? Is this a RET? Is this the start of // a subroutine? String ret = getInstruction().toString(false)+"\t[InstructionContext]"; return ret; } /** * Does the actual merging (vmspec2, page 146). * Returns true IFF this.inFrame was changed in course of merging with inFrame. */ private boolean mergeInFrames(Frame inFrame){ // TODO: Can be performance-improved. Frame inF = (Frame) inFrames.get(lastExecutionJSR()); OperandStack oldstack = inF.getStack().getClone(); LocalVariables oldlocals = inF.getLocals().getClone(); try{ inF.getStack().merge(inFrame.getStack()); inF.getLocals().merge(inFrame.getLocals()); } catch (StructuralCodeConstraintException sce){ extendMessageWithFlow(sce); throw sce; } if ( oldstack.equals(inF.getStack()) && oldlocals.equals(inF.getLocals()) ){ return false; } else{ return true; } } /** * Returns the control flow execution chain. This is built * while {@link #execute(Frame, ExecutionPath, ExecutionVisitor) executing} the code represented * by the surrounding ControlFlowGraph. */ private String getExecutionChain(){ return executionPredecessors.toString()+"\n"+this.toString(); } /** * Extends the StructuralCodeConstraintException ("e") object with an at-the-end-extended message. * This extended message will then reflect the execution flow needed to get to the constraint * violation that triggered the throwing of the "e" object. */ private void extendMessageWithFlow(StructuralCodeConstraintException e){ String s = "Execution flow:\n"; e.extendMessage("", s+getExecutionChain()); } /* * Fulfils the contract of InstructionContext.getInstruction(). */ public InstructionHandle getInstruction(){ return instruction; } private InstructionContext lastExecutionJSR(){ return executionPredecessors.lastExecutionJSR(); } /* Satisfies InstructionContext.getSuccessors(). */ public InstructionContext[] getSuccessors(){ return contextsOf(_getSuccessors()); } /** * A utility method that calculates the successors of a given InstructionHandle * That means, a RET does have successors as defined here. * A JsrInstruction has its target as its successor * (opposed to its physical successor) as defined here. */ // TODO: implement caching! private InstructionHandle[] _getSuccessors(){ final InstructionHandle[] empty = new InstructionHandle[0]; final InstructionHandle[] single = new InstructionHandle[1]; final InstructionHandle[] pair = new InstructionHandle[2]; Instruction inst = getInstruction().getInstruction(); if (inst instanceof RET){ Subroutine s = subroutines.subroutineOf(getInstruction()); if (s==null){ //return empty; // RET in dead code. "empty" would be the correct answer, but we know something about the surrounding project... throw new AssertionViolatedException("Asking for successors of a RET in dead code?!"); } //TODO: remove throw new AssertionViolatedException("DID YOU REALLY WANT TO ASK FOR RET'S SUCCS?"); /* InstructionHandle[] jsrs = s.getEnteringJsrInstructions(); InstructionHandle[] ret = new InstructionHandle[jsrs.length]; for (int i=0; i(NOT ORDERED!). */ public InstructionContext[] getInstructionContexts(){ InstructionContext[] ret = new InstructionContext[instructionContexts.values().size()]; return (InstructionContext[]) instructionContexts.values().toArray(ret); } /** * Returns true, if and only if the said instruction is not reachable; that means, * if it is not part of this ControlFlowGraph. */ public boolean isDead(InstructionHandle i){ return subroutines.subroutineOf(i) == null; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000005240210354572327033225 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.generic.ASTORE; import org.apache.bcel.generic.ATHROW; import org.apache.bcel.generic.BranchInstruction; import org.apache.bcel.generic.CodeExceptionGen; import org.apache.bcel.generic.GotoInstruction; import org.apache.bcel.generic.IndexedInstruction; import org.apache.bcel.generic.Instruction; import org.apache.bcel.generic.InstructionHandle; import org.apache.bcel.generic.JsrInstruction; import org.apache.bcel.generic.LocalVariableInstruction; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.RET; import org.apache.bcel.generic.ReturnInstruction; import org.apache.bcel.generic.Select; import org.apache.bcel.verifier.exc.AssertionViolatedException; import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; /** * Instances of this class contain information about the subroutines * found in a code array of a method. * This implementation considers the top-level (the instructions * reachable without a JSR or JSR_W starting off from the first * instruction in a code array of a method) being a special subroutine; * see getTopLevel() for that. * Please note that the definition of subroutines in the Java Virtual * Machine Specification, Second Edition is somewhat incomplete. * Therefore, JustIce uses an own, more rigid notion. * Basically, a subroutine is a piece of code that starts at the target * of a JSR of JSR_W instruction and ends at a corresponding RET * instruction. Note also that the control flow of a subroutine * may be complex and non-linear; and that subroutines may be nested. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: Subroutines.java 359623 2005-12-28 20:25:59Z kohsuke $ * @author Enver Haase * @see #getTopLevel() */ public class Subroutines{ /** * This inner class implements the Subroutine interface. */ private class SubroutineImpl implements Subroutine{ /** * UNSET, a symbol for an uninitialized localVariable * field. This is used for the "top-level" Subroutine; * i.e. no subroutine. */ private final int UNSET = -1; /** * The Local Variable slot where the first * instruction of this subroutine (an ASTORE) stores * the JsrInstruction's ReturnAddress in and * the RET of this subroutine operates on. */ private int localVariable = UNSET; /** The instructions that belong to this subroutine. */ private Set instructions; /* * Refer to the Subroutine interface for documentation. */ public boolean contains(InstructionHandle inst){ return instructions.contains(inst); } /** * The JSR or JSR_W instructions that define this * subroutine by targeting it. */ private HashSet theJSRs = new HashSet(); /** * The RET instruction that leaves this subroutine. */ private InstructionHandle theRET; /** * Returns a String representation of this object, merely * for debugging purposes. * (Internal) Warning: Verbosity on a problematic subroutine may cause * stack overflow errors due to recursive subSubs() calls. * Don't use this, then. */ public String toString(){ String ret = "Subroutine: Local variable is '"+localVariable+"', JSRs are '"+theJSRs+"', RET is '"+theRET+"', Instructions: '"+instructions.toString()+"'."; ret += " Accessed local variable slots: '"; int[] alv = getAccessedLocalsIndices(); for (int i=0; inot a * subroutine, the top-level, is also modeled as a Subroutine * object. * It is a special Subroutine object where you must not invoke * getEnteringJsrInstructions() or getLeavingRET(). * * @see Subroutine#getEnteringJsrInstructions() * @see Subroutine#getLeavingRET() */ public Subroutine getTopLevel(){ return TOPLEVEL; } static final InstructionHandle[] empty = new InstructionHandle[0]; /** * A utility method that calculates the successors of a given InstructionHandle * in the same subroutine. That means, a RET does not have any successors * as defined here. A JsrInstruction has its physical successor as its successor * (opposed to its target) as defined here. */ private static InstructionHandle[] getSuccessors(InstructionHandle instruction){ Instruction inst = instruction.getInstruction(); if (inst instanceof RET){ return empty; } // Terminates method normally. if (inst instanceof ReturnInstruction){ return empty; } // Terminates method abnormally, because JustIce mandates // subroutines not to be protected by exception handlers. if (inst instanceof ATHROW){ return empty; } final InstructionHandle[] single = new InstructionHandle[1]; // See method comment. if (inst instanceof JsrInstruction){ single[0] = instruction.getNext(); return single; } if (inst instanceof GotoInstruction){ single[0] = ((GotoInstruction) inst).getTarget(); return single; } if (inst instanceof BranchInstruction){ if (inst instanceof Select){ // BCEL's getTargets() returns only the non-default targets, // thanks to Eli Tilevich for reporting. InstructionHandle[] matchTargets = ((Select) inst).getTargets(); InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1]; ret[0] = ((Select) inst).getTarget(); System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length); return ret; } else{ final InstructionHandle[] pair = new InstructionHandle[2]; pair[0] = instruction.getNext(); pair[1] = ((BranchInstruction) inst).getTarget(); return pair; } } // default case: Fall through. single[0] = instruction.getNext(); return single; } /** * Returns a String representation of this object; merely for debugging puposes. */ public String toString(){ return "---\n"+subroutines.toString()+"\n---\n"; } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutine.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/a0000644000175000017500000000603110276745044033223 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; import org.apache.bcel.generic.*; /** * This interface defines properties of JVM bytecode subroutines. * Note that it is 'abused' to maintain the top-level code in a * consistent fashion, too. * * WARNING! These classes are a fork of the bcel verifier. * * @version $Id: Subroutine.java 231525 2005-08-11 21:59:00Z tcurdt $ * @author Enver Haase */ public interface Subroutine{ /** * Returns all the JsrInstructions that have the * first instruction of this subroutine as their target. * Must not be invoked on the 'top-level subroutine'. */ public InstructionHandle[] getEnteringJsrInstructions(); /** * Returns the one and only RET that leaves the subroutine. * Note that JustIce has a pretty rigid notion of a subroutine. * Must not be invoked on the 'top-level subroutine'. * * @see org.apache.bcel.verifier.structurals.Subroutines */ public InstructionHandle getLeavingRET(); /** * Returns all instructions that together form this subroutine. * Note that an instruction is part of exactly one subroutine * (the top-level code is considered to be a special subroutine) - * else it is not reachable at all (dead code). */ public InstructionHandle[] getInstructions(); /** * Returns if the given InstructionHandle refers to an instruction * that is part of this subroutine. This is a convenience method * that saves iteration over the InstructionHandle objects returned * by getInstructions(). * * @see #getInstructions() */ public boolean contains(InstructionHandle inst); /** * Returns an int[] containing the indices of the local variable slots * accessed by this Subroutine (read-accessed, write-accessed or both); * local variables referenced by subroutines of this subroutine are * not included. * * @see #getRecursivelyAccessedLocalsIndices() */ public int[] getAccessedLocalsIndices(); /** * Returns an int[] containing the indices of the local variable slots * accessed by this Subroutine (read-accessed, write-accessed or both); * local variables referenced by subroutines of this subroutine are * included. * * @see #getAccessedLocalsIndices() */ public int[] getRecursivelyAccessedLocalsIndices(); /** * Returns the subroutines that are directly called from this subroutine. */ public Subroutine[] subSubs(); } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/ResourceTransformer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/Resour0000644000175000017500000000236310313475743033357 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation; import org.apache.commons.javaflow.Continuation; import org.apache.commons.javaflow.bytecode.transformation.asm.AsmClassTransformer; import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer; /** * Byte-code transformer that enhances the class files for javaflow. * *

* When {@link Continuation#suspend()} is called, all the methods * in the stack frame needs to be enhanced. * * @author tcurdt * @see BcelClassTransformer * @see AsmClassTransformer */ public interface ResourceTransformer { byte[] transform( final byte[] original ); } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/0000755000175000017500000000000011135725055032726 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAnalyzer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/Co0000644000175000017500000002537610356676126033237 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.asm; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.analysis.Analyzer; import org.objectweb.asm.tree.analysis.AnalyzerException; import org.objectweb.asm.tree.analysis.DataflowInterpreter; import org.objectweb.asm.tree.analysis.DataflowValue; import org.objectweb.asm.tree.analysis.Frame; import org.objectweb.asm.tree.analysis.SimpleVerifier; /** * ContinuationMethodAdapter * * @author Evgueni Koulechov */ public class ContinuationMethodAnalyzer extends MethodNode implements Opcodes { protected final String className; protected final ClassVisitor cv; protected final MethodVisitor mv; protected final List labels = new ArrayList(); protected final List nodes = new ArrayList(); protected final List methods = new ArrayList(); protected Analyzer analyzer; public int stackRecorderVar; public ContinuationMethodAnalyzer(String className, ClassVisitor cv, MethodVisitor mv, int access, String name, String desc, String signature, String[] exceptions) { super(access, name, desc, signature, exceptions); this.className = className; this.cv = cv; this.mv = mv; } public void visitMethodInsn(int opcode, String owner, String name, String desc) { MethodInsnNode mnode = new MethodInsnNode(opcode, owner, name, desc); if (opcode == INVOKESPECIAL || "".equals(name)) { methods.add(mnode); } if (needsFrameGuard(opcode, owner, name, desc) /* && transformer.inScope(owner, name)*/) { Label label = new Label(); super.visitLabel(label); labels.add(label); nodes.add(mnode); } instructions.add(mnode); } public void visitEnd() { if (instructions.size() == 0 || labels.size() == 0) { accept(mv); return; } this.stackRecorderVar = maxLocals; try { moveNew(); // TraceMethodVisitor mv = new TraceMethodVisitor(); // System.err.println(name + desc); // for (int j = 0; j < instructions.size(); ++j) { // ((AbstractInsnNode) instructions.get(j)).accept(mv); // System.err.print(" " + mv.text.get(j)); // mv.text.get(j)); // } // System.err.println(); // analyzer = new Analyzer(new BasicVerifier()); analyzer = new Analyzer(new SimpleVerifier() { protected Class getClass(Type t) { try { if (t.getSort() == Type.ARRAY) { return Class.forName(t.getDescriptor().replace('/', '.'), true, Thread.currentThread().getContextClassLoader()); } return Class.forName(t.getClassName(), true, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { throw new RuntimeException(e.toString()); } } }); analyzer.analyze(className, this); accept(new ContinuationMethodAdapter(this)); } catch (AnalyzerException ex) { // TODO log the error or fail? ex.printStackTrace(); accept(mv); } } void moveNew() throws AnalyzerException { DataflowInterpreter i = new DataflowInterpreter(); Analyzer a = new Analyzer(i); a.analyze(className, this); HashMap movable = new HashMap(); Frame[] frames = a.getFrames(); for (int j = 0; j < methods.size(); j++) { MethodInsnNode mnode = (MethodInsnNode) methods.get(j); // require to move NEW instruction int n = a.getIndex(mnode); Frame f = frames[n]; Type[] args = Type.getArgumentTypes(mnode.desc); DataflowValue v = (DataflowValue) f.getStack(f.getStackSize() - args.length - 1); Set insns = v.insns; for (Iterator it = insns.iterator(); it.hasNext();) { AbstractInsnNode ins = (AbstractInsnNode) it.next(); if (ins.getOpcode() == NEW) { movable.put(ins, mnode); } else { // other known patterns int n1 = a.getIndex(ins); if (ins.getOpcode() == DUP) { // with params AbstractInsnNode ins1 = (AbstractInsnNode) instructions.get(n1 - 1); if (ins1.getOpcode() == NEW) { movable.put(ins1, mnode); } } else if (ins.getOpcode() == SWAP) { // in exception handler AbstractInsnNode ins1 = (AbstractInsnNode) instructions.get(n1 - 1); AbstractInsnNode ins2 = (AbstractInsnNode) instructions.get(n1 - 2); if (ins1.getOpcode() == DUP_X1 && ins2.getOpcode() == NEW) { movable.put(ins2, mnode); } } } } } int updateMaxStack = 0; for (Iterator it = movable.entrySet().iterator(); it.hasNext();) { Map.Entry e = (Map.Entry) it.next(); AbstractInsnNode node1 = (AbstractInsnNode) e.getKey(); int n1 = instructions.indexOf(node1); AbstractInsnNode node2 = (AbstractInsnNode) instructions.get(n1 + 1); AbstractInsnNode node3 = (AbstractInsnNode) instructions.get(n1 + 2); int producer = node2.getOpcode(); instructions.remove(node1); // NEW boolean requireDup = false; if (producer == DUP) { instructions.remove(node2); // DUP requireDup = true; } else if (producer == DUP_X1) { instructions.remove(node2); // DUP_X1 instructions.remove(node3); // SWAP requireDup = true; } MethodInsnNode mnode = (MethodInsnNode) e.getValue(); int nm = instructions.indexOf(mnode); int varOffset = stackRecorderVar + 1; Type[] args = Type.getArgumentTypes(mnode.desc); // optimizations for some common cases if (args.length == 0) { instructions.add(nm++, node1); // NEW if (requireDup) { instructions.add(nm++, new InsnNode(DUP)); } continue; } if (args.length == 1 && args[0].getSize() == 1) { instructions.add(nm++, node1); // NEW if (requireDup) { instructions.add(nm++, new InsnNode(DUP)); instructions.add(nm++, new InsnNode(DUP2_X1)); instructions.add(nm++, new InsnNode(POP2)); updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values } else { instructions.add(nm++, new InsnNode(SWAP)); } continue; } // TODO this one untested! if ((args.length == 1 && args[0].getSize() == 2) || (args.length == 2 && args[0].getSize() == 1 && args[1].getSize() == 1)) { instructions.add(nm++, node1); // NEW if (requireDup) { instructions.add(nm++, new InsnNode(DUP)); instructions.add(nm++, new InsnNode(DUP2_X2)); instructions.add(nm++, new InsnNode(POP2)); updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values } else { instructions.add(nm++, new InsnNode(DUP_X2)); instructions.add(nm++, new InsnNode(POP)); updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for temp value } continue; } // generic code using temporary locals // save stack for (int j = args.length - 1; j >= 0; j--) { Type type = args[j]; instructions.add(nm++, new VarInsnNode(type.getOpcode(ISTORE), varOffset)); varOffset += type.getSize(); } if (varOffset > maxLocals) { maxLocals = varOffset; } instructions.add(nm++, node1); // NEW if (requireDup) { instructions.add(nm++, new InsnNode(DUP)); } // restore stack for (int j = 0; j < args.length; j++) { Type type = args[j]; varOffset -= type.getSize(); instructions.add(nm++, new VarInsnNode(type.getOpcode(ILOAD), varOffset)); // clean up store to avoid memory leak? if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for ACONST_NULL instructions.add(nm++, new InsnNode(ACONST_NULL)); instructions.add(nm++, new VarInsnNode(type.getOpcode(ISTORE), varOffset)); } } } maxStack += updateMaxStack; } // TODO boolean needsFrameGuard(int opcode, String owner, String name, String desc) { if (opcode == Opcodes.INVOKEINTERFACE || (opcode == Opcodes.INVOKESPECIAL && !"".equals(name)) || opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKEVIRTUAL) { return true; } return false; } }././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/AsmClassTransformer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/As0000644000175000017500000000525110356676126033227 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.asm; import java.io.IOException; import java.io.InputStream; import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.util.CheckClassAdapter; /** * AsmClassTransformer * * @author Eugene Kuleshov */ public final class AsmClassTransformer implements ResourceTransformer { private final static Log log = LogFactory.getLog(AsmClassTransformer.class); public byte[] transform(InputStream is) throws IOException { return transform(new ClassReader(is)); } public byte[] transform(final byte[] original) { return transform(new ClassReader(original)); } private byte[] transform(ClassReader cr) { // final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); final ClassWriter cw = new ClassWriter(true, false); // print bytecode before transformation // cr.accept(new TraceClassVisitor(new ContinuationClassAdapter(this, cw), new PrintWriter(System.out)), false); // prints bytecode after transformation // cr.accept(new ContinuationClassAdapter(this, new TraceClassVisitor(cw, new PrintWriter(System.err))), 0); // cr.accept(new ContinuationClassAdapter(this, new TraceClassVisitor(cw, new PrintWriter(System.err))), false); cr.accept(new ContinuationClassAdapter(new CheckClassAdapter(cw)), false); byte[] bytecode = cw.toByteArray(); // CheckClassAdapter.verify(new ClassReader(bytecode), true); // new ClassReader(bytecode).accept(new ASMifierClassVisitor(new PrintWriter(System.err)), false); // ClassWriter cww = new ClassWriter(ClassWriter.COMPUTE_FRAMES); // new ClassReader(bytecode).accept(cww, ClassReader.SKIP_DEBUG); // new ClassReader(cww.toByteArray()).accept(new TraceClassVisitor(new PrintWriter(System.err)), 0); return bytecode; } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationClassAdapter.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/Co0000644000175000017500000000332410353415567033221 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.asm; import org.objectweb.asm.ClassAdapter; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; /** * ContinuationClassAdapter * * @author Evgueni Koulechov */ public class ContinuationClassAdapter extends ClassAdapter { private String className; public ContinuationClassAdapter(ClassVisitor cv) { super(cv); } public void visit( int version, int access, String name, String signature, String superName, String[] interfaces ) { cv.visit(version, access, name, signature, superName, interfaces); className = name; } public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions ) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); // TODO skip native and abstract methods? if (!"".equals(name) && mv!=null) { return new ContinuationMethodAnalyzer(className, this.cv, mv, access, name, desc, signature, exceptions); } return mv; } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/asm/Co0000644000175000017500000003111510356676126033223 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation.asm; import java.util.List; import org.apache.commons.javaflow.bytecode.StackRecorder; import org.objectweb.asm.Label; import org.objectweb.asm.MethodAdapter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.analysis.Analyzer; import org.objectweb.asm.tree.analysis.BasicValue; import org.objectweb.asm.tree.analysis.Frame; /** * ContinuationMethodAdapter * * @author Evgueni Koulechov */ public final class ContinuationMethodAdapter extends MethodAdapter implements Opcodes { private static final String STACK_RECORDER = Type.getInternalName(StackRecorder.class); private static final String POP_METHOD = "pop"; private static final String PUSH_METHOD = "push"; private final Analyzer analyzer; private Label startLabel = new Label(); private final List labels; private final List nodes; private final int stackRecorderVar; private final boolean isStatic; private final String methodDesc; private int currentIndex = 0; private Frame currentFrame = null; public ContinuationMethodAdapter(ContinuationMethodAnalyzer a) { super(a.mv); this.analyzer = a.analyzer; this.labels = a.labels; this.nodes = a.nodes; this.stackRecorderVar = a.stackRecorderVar; this.isStatic = (a.access & ACC_STATIC) > 0; this.methodDesc = a.desc; } public void visitCode() { mv.visitCode(); int fsize = labels.size(); Label[] restoreLabels = new Label[fsize]; for (int i = 0; i < restoreLabels.length; i++) { restoreLabels[i] = new Label(); } // verify if restoring Label l0 = new Label(); mv.visitMethodInsn(INVOKESTATIC, STACK_RECORDER, "get", "()L" + STACK_RECORDER + ";"); mv.visitInsn(DUP); mv.visitVarInsn(ASTORE, stackRecorderVar); mv.visitLabel(startLabel); mv.visitJumpInsn(IFNULL, l0); mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitFieldInsn(GETFIELD, STACK_RECORDER, "isRestoring", "Z"); mv.visitJumpInsn(IFEQ, l0); mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Int", "()I"); mv.visitTableSwitchInsn(0, fsize - 1, l0, restoreLabels); // switch cases for (int i = 0; i < fsize; i++) { Label frameLabel = (Label) labels.get(i); mv.visitLabel(restoreLabels[i]); MethodInsnNode mnode = (MethodInsnNode) nodes.get(i); Frame frame = analyzer.getFrames()[analyzer.getIndex(mnode)]; // locals int lsize = frame.getLocals(); for (int j = lsize - 1; j >= 0; j--) { BasicValue value = (BasicValue) frame.getLocal(j); if (value == null) { mv.visitInsn(ACONST_NULL); mv.visitVarInsn(ASTORE, j); } else if (value == BasicValue.UNINITIALIZED_VALUE) { // TODO ?? } else if (value == BasicValue.RETURNADDRESS_VALUE) { // TODO ?? } else { mv.visitVarInsn(ALOAD, stackRecorderVar); Type type = value.getType(); if (value.isReference()) { mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object", "()Ljava/lang/Object;"); Type t = value.getType(); String desc = t.getDescriptor(); if (desc.charAt(0) == '[') { mv.visitTypeInsn(CHECKCAST, desc); } else { mv.visitTypeInsn(CHECKCAST, t.getInternalName()); } mv.visitVarInsn(ASTORE, j); } else { mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type), "()" + type.getDescriptor()); mv.visitVarInsn(type.getOpcode(ISTORE), j); } } } // stack int argSize = Type.getArgumentTypes(mnode.desc).length; int ownerSize = mnode.getOpcode() == INVOKESTATIC ? 0 : 1; // TODO int initSize = mnode.name.equals("") ? 2 : 0; int ssize = frame.getStackSize(); for (int j = 0; j < ssize - argSize - ownerSize - initSize; j++) { BasicValue value = (BasicValue) frame.getStack(j); if (value == null) { mv.visitInsn(ACONST_NULL); } else if (value == BasicValue.UNINITIALIZED_VALUE) { // TODO ?? } else if (value == BasicValue.RETURNADDRESS_VALUE) { // TODO ?? } else if (value.isReference()) { mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Object", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName()); } else { Type type = value.getType(); mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPopMethod(type), "()" + type.getDescriptor()); } } if (mnode.getOpcode() != INVOKESTATIC) { mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Reference", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, ((BasicValue) frame.getStack(ssize - argSize - 1)).getType().getInternalName()); } // Create null types for the parameters of the method invocation Type[] paramTypes = Type.getArgumentTypes(mnode.desc); for (int j = 0; j < paramTypes.length; j++) { pushDefault(paramTypes[j]); } // continue to the next method mv.visitJumpInsn(GOTO, frameLabel); } // end of start block mv.visitLabel(l0); } public void visitLabel(Label label) { if (currentIndex < labels.size() && label == labels.get(currentIndex)) { int i = analyzer.getIndex(nodes.get(currentIndex)); currentFrame = analyzer.getFrames()[i]; } mv.visitLabel(label); } public void visitMethodInsn(int opcode, String owner, String name, String desc) { mv.visitMethodInsn(opcode, owner, name, desc); if (currentFrame != null) { Label fl = new Label(); mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitJumpInsn(IFNULL, fl); mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitFieldInsn(GETFIELD, STACK_RECORDER, "isCapturing", "Z"); mv.visitJumpInsn(IFEQ, fl); // save stack Type returnType = Type.getReturnType(desc); boolean hasReturn = returnType != Type.VOID_TYPE; if (hasReturn) { mv.visitInsn(returnType.getSize() == 1 ? POP : POP2); } Type[] params = Type.getArgumentTypes(desc); int argSize = params.length; int ownerSize = opcode == INVOKESTATIC ? 0 : 1; // TODO int ssize = currentFrame.getStackSize() - argSize - ownerSize; for (int i = 0; i < ssize; i++) { BasicValue value = (BasicValue) currentFrame.getStack(i); if (value == null) { mv.visitInsn(POP); } else if (value == BasicValue.UNINITIALIZED_VALUE) { // TODO ?? } else if (value.isReference()) { mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitInsn(SWAP); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Object", "(Ljava/lang/Object;)V"); } else { Type type = value.getType(); mv.visitVarInsn(ALOAD, stackRecorderVar); if (type.getSize() > 1) { mv.visitInsn(DUP); // dummy stack entry mv.visitInsn(DUP2_X2); // swap2 for long/double mv.visitInsn(POP2); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type), "(" + type.getDescriptor() + ")V"); mv.visitInsn(POP); // remove dummy stack entry } else { mv.visitInsn(SWAP); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type), "(" + type.getDescriptor() + ")V"); } } } if (!isStatic) { mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Reference", "(Ljava/lang/Object;)V"); } // save locals int fsize = currentFrame.getLocals(); for (int j = 0; j < fsize; j++) { BasicValue value = (BasicValue) currentFrame.getLocal(j); if (value == null) { // no need to save null } else if (value == BasicValue.UNINITIALIZED_VALUE) { // no need to save uninitialized objects } else if (value.isReference()) { mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitVarInsn(ALOAD, j); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, PUSH_METHOD + "Object", "(Ljava/lang/Object;)V"); } else { mv.visitVarInsn(ALOAD, stackRecorderVar); Type type = value.getType(); mv.visitVarInsn(type.getOpcode(ILOAD), j); mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, getPushMethod(type), "(" + type.getDescriptor() + ")V"); } } mv.visitVarInsn(ALOAD, stackRecorderVar); mv.visitIntInsn(BIPUSH, currentIndex); // TODO optimize to iconst_0... mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, "pushInt", "(I)V"); Type methodReturnType = Type.getReturnType(methodDesc); pushDefault(methodReturnType); mv.visitInsn(methodReturnType.getOpcode(IRETURN)); mv.visitLabel(fl); currentIndex++; currentFrame = null; } } public void visitMaxs(int maxStack, int maxLocals) { Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("__stackRecorder", "L" + STACK_RECORDER + ";", null, startLabel, endLabel, stackRecorderVar); mv.visitMaxs(0, 0); } void pushDefault(Type type) { switch (type.getSort()) { case Type.VOID: break; case Type.DOUBLE: mv.visitInsn(DCONST_0); break; case Type.LONG: mv.visitInsn(LCONST_0); break; case Type.FLOAT: mv.visitInsn(FCONST_0); break; case Type.OBJECT: case Type.ARRAY: mv.visitInsn(ACONST_NULL); break; default: mv.visitInsn(ICONST_0); break; } } private static String[] SUFFIXES = { "Object", // 0 void "Int", // 1 boolean "Int", // 2 char "Int", // 3 byte "Int", // 4 short "Int", // 5 int "Float", // 6 float "Long", // 7 long "Double", // 8 double "Object", // 9 array "Object", // 10 object }; String getPopMethod(Type type) { return POP_METHOD + SUFFIXES[type.getSort()]; } String getPushMethod(Type type) { return PUSH_METHOD + SUFFIXES[type.getSort()]; } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/NopResourceTransformer.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/transformation/NopRes0000644000175000017500000000164710313475743033312 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode.transformation; public final class NopResourceTransformer implements ResourceTransformer { public static final NopResourceTransformer INSTANCE = new NopResourceTransformer(); public byte[] transform( byte[] original ) { return original; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootcommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/EmptyStackException.javacommons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/EmptyStackException.j0000644000175000017500000000157610210074047033216 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode; /** * @author tcurdt * */ public class EmptyStackException extends RuntimeException { private static final long serialVersionUID = 1L; public EmptyStackException(String message) { super(message); } } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/Continuable.java0000644000175000017500000000176610274322413032212 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode; /** * Marker interface to mark classes, which are transformed by the * ContinuationClassLoader. * * @author Torsten Curdt * @author Stephan Michels * @version CVS $Id: Continuable.java 227306 2005-08-04 05:18:03Z kohsuke $ */ public interface Continuable { } commons-javaflow-0.0~svn20060411/src/java/org/apache/commons/javaflow/bytecode/Stack.java0000644000175000017500000002667010353415567031030 0ustar drazzibdrazzib/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.javaflow.bytecode; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import org.apache.commons.javaflow.utils.ReflectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Stack to store the frame information along the invocation trace. * * @author Torsten Curdt * @author Stephan Michels * @version CVS $Id: Stack.java 358963 2005-12-25 04:09:27Z tcurdt $ */ public class Stack implements Serializable { private static final Log log = LogFactory.getLog(Stack.class); private static final long serialVersionUID = 2L; private int[] istack; private float[] fstack; private double[] dstack; private long[] lstack; private Object[] ostack; private Object[] rstack; private int iTop, fTop, dTop, lTop, oTop, rTop; protected Runnable runnable; public Stack(Runnable pRunnable) { istack = new int[10]; lstack = new long[5]; dstack = new double[5]; fstack = new float[5]; ostack = new Object[10]; rstack = new Object[5]; runnable = pRunnable; } public Stack(final Stack pParent) { istack = new int[pParent.istack.length]; lstack = new long[pParent.lstack.length]; dstack = new double[pParent.dstack.length]; fstack = new float[pParent.fstack.length]; ostack = new Object[pParent.ostack.length]; rstack = new Object[pParent.rstack.length]; iTop = pParent.iTop; fTop = pParent.fTop; dTop = pParent.dTop; lTop = pParent.lTop; oTop = pParent.oTop; rTop = pParent.rTop; System.arraycopy(pParent.istack, 0, istack, 0, iTop); System.arraycopy(pParent.fstack, 0, fstack, 0, fTop); System.arraycopy(pParent.dstack, 0, dstack, 0, dTop); System.arraycopy(pParent.lstack, 0, lstack, 0, lTop); System.arraycopy(pParent.ostack, 0, ostack, 0, oTop); System.arraycopy(pParent.rstack, 0, rstack, 0, rTop); runnable = pParent.runnable; } public boolean hasDouble() { return dTop > 0; } public double popDouble() { if (dTop == 0) { throw new EmptyStackException("pop double"); } final double d = dstack[--dTop]; log.debug("pop double " + d + " " + getStats()); return d; } public boolean hasFloat() { return fTop > 0; } public float popFloat() { if (fTop == 0) { throw new EmptyStackException("pop float"); } final float f = fstack[--fTop]; log.debug("pop float " + f + " " + getStats()); return f; } public boolean hasInt() { return iTop > 0; } public int popInt() { if (iTop == 0) { throw new EmptyStackException("pop int"); } final int i = istack[--iTop]; log.debug("pop int " + i + " " + getStats()); return i; } public boolean hasLong() { return lTop > 0; } public long popLong() { if (lTop == 0) { throw new EmptyStackException("pop long"); } final long l = lstack[--lTop]; log.debug("pop long " + l + " " + getStats()); return l; } public boolean hasObject() { return oTop > 0; } public Object popObject() { if (oTop == 0) { throw new EmptyStackException("pop object"); } final Object o = ostack[--oTop]; ostack[oTop] = null; // avoid unnecessary reference to object if(log.isDebugEnabled()) { final String clazz = ReflectionUtils.getClassName(o); final String clazzLoader = ReflectionUtils.getClassLoaderName(o); log.debug("pop object "+ clazz + "/" + clazzLoader + " [" + o + "] "); } return o; } public boolean hasReference() { return rTop > 0; } public Object popReference() { if (rTop == 0) { throw new EmptyStackException("pop reference"); } final Object o = rstack[--rTop]; rstack[rTop] = null; // avoid unnecessary reference to object if(log.isDebugEnabled()) { final String clazz = ReflectionUtils.getClassName(o); final String clazzLoader = ReflectionUtils.getClassLoaderName(o); log.debug("pop reference "+ clazz + "/" + clazzLoader + " [" + o + "] " + getStats()); } return o; } public void pushDouble(double d) { log.debug("push double " + d + " " + getStats()); if (dTop == dstack.length) { double[] hlp = new double[Math.max(8,dstack.length*2)]; System.arraycopy(dstack, 0, hlp, 0, dstack.length); dstack = hlp; } dstack[dTop++] = d; } public void pushFloat(float f) { log.debug("push float " + f + " " + getStats()); if (fTop == fstack.length) { float[] hlp = new float[Math.max(8,fstack.length*2)]; System.arraycopy(fstack, 0, hlp, 0, fstack.length); fstack = hlp; } fstack[fTop++] = f; } public void pushInt(int i) { log.debug("push int " + i + " " + getStats()); if (iTop == istack.length) { int[] hlp = new int[Math.max(8,istack.length*2)]; System.arraycopy(istack, 0, hlp, 0, istack.length); istack = hlp; } istack[iTop++] = i; } public void pushLong(long l) { log.debug("push long " + l + " " + getStats()); if (lTop == lstack.length) { long[] hlp = new long[Math.max(8,lstack.length*2)]; System.arraycopy(lstack, 0, hlp, 0, lstack.length); lstack = hlp; } lstack[lTop++] = l; } public void pushObject(Object o) { if (log.isDebugEnabled()) { final String clazz = ReflectionUtils.getClassName(o); final String clazzLoader = ReflectionUtils.getClassLoaderName(o); log.debug("push object " + clazz + "/" + clazzLoader + " [" + o + "] " + getStats()); } if (oTop == ostack.length) { Object[] hlp = new Object[Math.max(8,ostack.length*2)]; System.arraycopy(ostack, 0, hlp, 0, ostack.length); ostack = hlp; } ostack[oTop++] = o; } public void pushReference(Object o) { if (log.isDebugEnabled()) { final String clazz = ReflectionUtils.getClassName(o); final String clazzLoader = ReflectionUtils.getClassLoaderName(o); log.debug("push reference " + clazz + "/" + clazzLoader + " [" + o + "] " + getStats()); } if (rTop == rstack.length) { Object[] hlp = new Object[Math.max(8,rstack.length*2)]; System.arraycopy(rstack, 0, hlp, 0, rstack.length); rstack = hlp; } rstack[rTop++] = o; } public boolean isSerializable() { for (int i = 0; i < rTop; i++) { final Object r = rstack[i]; if (!(r instanceof Serializable)) { return false; } } for (int i = 0; i < oTop; i++) { final Object o = ostack[i]; if (!(o instanceof Serializable)) { return false; } } return true; } public boolean isEmpty() { return iTop==0 && lTop==0 && dTop==0 && fTop==0 && oTop==0 && rTop==0; } private String getStats() { final StringBuffer sb = new StringBuffer(); sb.append("i[").append(iTop).append("],"); sb.append("l[").append(lTop).append("],"); sb.append("d[").append(dTop).append("],"); sb.append("f[").append(fTop).append("],"); sb.append("o[").append(oTop).append("],"); sb.append("r[").append(rTop).append("]"); return sb.toString(); } private String getContent() { final StringBuffer sb = new StringBuffer(); sb.append("i[").append(iTop).append("]\n"); sb.append("l[").append(lTop).append("]\n"); sb.append("d[").append(dTop).append("]\n"); sb.append("f[").append(fTop).append("]\n"); sb.append("o[").append(oTop).append("]\n"); for(int i=0; i Downloads Commons Documentation Team $Id: downloads.xml 155451 2005-02-26 13:22:47Z dirkv $

There are no releases available.

Access to the source tree to see the latest and greatest code is possible through anonymous SVN access.

commons-javaflow-0.0~svn20060411/xdocs/navigation.xml0000644000175000017500000000131510325366476022307 0ustar drazzibdrazzib Commons Javaflow &common-menus; commons-javaflow-0.0~svn20060411/xdocs/tutorial.xml0000644000175000017500000001622210325366476022016 0ustar drazzibdrazzib Tutorial Commons Documentation Team $Id: downloads.xml 155451 2005-02-26 13:22:47Z dirkv $

This document shows the basic usage of the javaflow API.

First, consider the following program:

class MyRunnable implements Runnable { public void run() { System.out.println("started!"); for( int i=0; i<10; i++ ) echo(i); } private void echo(int x) { System.out.println(x); Continuation.suspend(); } } Continuation c = Continuation.startWith(new MyRunnable()); System.out.println("returned a continuation");

When the startWith method is invoked, Javaflow sets up the "environment", then invoke the run method of the object it received. It's not very important for users to know what this environment is, but that is what enables all the magics we'll see in this document.

As a result of this, you'll see the "started!" message printed in the console. The thread then goes into a for loop, calls the echo method, prints "0", then calls the Continuation.suspend().

This is where an interesting thing happens. In this method, the stack frames that are leading up to the Continuation.suspend() and all local variables are captured into a Continuation object, and then the execution resumes by returning from the startWith method (instead of returning from the suspend method.) So the next message you'll see on the console is "returned a continuation". This all happens by using just one thread.

You can then do something else, and eventually you'll do the following:

Continuation d = Continuation.continueWith(c); System.out.println("returned another continuation");

When the continueWith method is invoked, javaflow sets up the environment again, and restores stack frames and local variables. Instead of returning from the continueWith method, the execution resumes by returning from the suspend method that never returned before.

Now what happens? The echo method returns, then you'll go another iteration of the for loop. So the next message you'll see is "1". Then, the suspend method is called again.

At this point, the stack frames and the local variables are captured into a new Continuation object, and then the execution resumes by returning from the continueWith method. So the next message you'll see is "returned another continuation".

If you think of two threads, the execution flow so far would be probably easier to understand, although with javaflow all of this happens in one thread. We can repeatedly continue the returned Continuation object so that it will print 2,3,...,9 as shown in the following code:

while(d!=null) { d = Continuation.continueWith(d); }

Eventually, the for loop exits and the run method returns. At that point, there's nothing left to execute. So the continueWith method returns null.

Now, so far the things we did can be easily done if you are to use two threads. So let's do something more interesting. Remember the 'c' object we captured earlier? We've already continued it once, but we can do it again:

Continuation.continueWith(c);

This restores the stack frames and local variables captured in 'c'. Then the execution resumes by returning from the suspend method. When 'c' was captured, the value of 'i' was 0. So the next number you'll see printed is "1". Then it executes suspend method, then the execution returns from the continueWith method.

Isn't this interesting? In a way, we went back the time and re-run the same code again. The continueWith method doesn't have to be invoked from the same method.

A Continuation can be serialized if all objects it captured is also serializable. In other words, all the local variables (including all this objects) need to be marked as Serializable. In this example, you need to mark the MyRunnable class as Serializable. A serialized continuation can be sent over to another machine or used later.

For these to work, javaflow needs to enhance the byte code of your program that runs inside the continuation-enabled environment. When the Continuation.suspend runs, all the methods on the stack frames (down to Continuation.startWith or Continuation.continueWith) need to be enhanced.

There are two ways to instrument bytecode. One way is to do it statically. This means using the javaflow Ant task as a part of your build process, to enhance the classes that run inside continuation-enabled environment. Since the byte-code enhancement increases the class file size and slow down the execution, you might want to consider avoiding unnecessary class files enhancement.

Alternatively, you can do this dynamically at runtime, by using javaflow's ContinuationClassLoader. This works like a URLClassLoader with the byte-code enhancement. To use this, you need to separate your application into two parts; one for classes that don't need enhancement, and the other that do need enhancement. You can then configure the first portion to be loaded by the system class loader, and then load the second portion by a ContinuationClassLoader. The following code shows how to do this:

// this class lives in the system class loader public class Foo { public static void main(String[] args) { ClassLoader cl = new ContinuationClassLoader( new URL[]{new URL("latter.jar")}, Foo.class.getClassLoader()); // parent class loader cl.loadClass(...); } }
commons-javaflow-0.0~svn20060411/xdocs/images/0000755000175000017500000000000011135725051020657 5ustar drazzibdrazzibcommons-javaflow-0.0~svn20060411/xdocs/images/javaflow-logo-white.png0000644000175000017500000003040210172544102025245 0ustar drazzibdrazzibPNG  IHDRP bKGD pHYs  tIME'tEXtCommentCreated with The GIMPd%n IDATx}ytUE-$(8*Hpаd ( "Hd8"9:(8"ePF4 A4(,XB[{orϹ%Z]nBM^ͬTmj^|vU\ ir_xi󯡍ߒhq ;v|4inݺ!55':xc=zk֬1Tt͑vu?wyݻwGjj;wbǎعstSݺwŮ]pQSTU۽sNY/5k`ΝFȰG]vh-&%%jn|emdzN0R)H####ñ>;R ޽AGy/Vxo-9s戤$MOO" jP($B"*QUU%^xWu$%%I&UH$"VZ%222VZ%"" m۶nݺi֭8t矷m[YYiWYY)*++M/HMM5ʐm={m?@ <(~a[:˼JKrv;֭[E04Ǎ{vv*obb(//YYY ւ[Bߙ3g;sLW'j۪e(?ISSSŪU ~͵}ĈcrJDr,?sWx7 ;wζIIIb۶m& ֭[- (K~8Y`_2~25$ we˖goYY/5bK=iiiz&N(F!F̊+D~~D1a|rl2CO.N:%,Yb|7|ptRl2#/ӧӧO3gΈgϊ]#Fb ܮ]3fuv҅ͷ~q)1|pǏ77--MkK&^ZWo 9bDZ4X$&&SN?ɫNuP 6*T&eRRaBц?^21c K7n,JKKEII(--ԩSFǗ/_n!,0st;|pYӧ|:M!ޥKyfqiQRR"[o-СCŞ={Daabo>ѸqcK^Pt յԩS>3|ƍCĴiضŋy{C9d,++3rҥ,m[xRpZ֟&rrr "QTT$:wlɷh"mٲd-IiYY)='TS49v؁=zÇqB "ϣG}I… 1tP`Ϟ=8pk׮OL ʺۡC?~:$^/^/<^/*K%K}ϴiӰpBK!C^3M+5m4Sףcǎ^>ׯǽksɒ%6l]t^{5 2ĶÆ _miԨvmCۚcǎi 'F履~7sСXp]Nǣŋ1tPR~ڳgCZԩSҐ cQY's=ذa-Z6[F2 r@@ʿ[nmo JYF6m,y7nܨeJ-0-BW۶m-yׯo|vYnذRl ,ND`2YmD"qqq]#(Oxr-Xx{ȑ#D  >`bj|>D"oO?4(?Lf:B`ԩ,)Ed?i![nFeTG$߲}dU@RR0}M\o` LfHP(d7^$0uSJt uΣWW j.J'l׮pIy7[ڪԦ:`z<ׯ{9SSbÆ x'M6æUA2x^f_*OLLdAIJkqj")3&j'8 كmZC1Z`>S{^wҘTI&̣jʼ*@G AUT#]ڷoo)o޽馛LczY4c)0%mh=Ƥc!i"-z;@ffF:`Μ97sZ|>K_8vHu$>&j^7|j LeG(6lBSyǏG-,4&&IQ@cAUtZAȱ}ʩ*H(JK`,@8 jܰaCKY'O4@CukMPU59]CI&ɓؼy%޽{ѯ_?;cƌA||ۮ rm !L' L2V\vt9[]%*`JJ >c[ZAh?~@-2;-WӘғVnVN*HѨ1=RcT "KIIh%@ۙT[~Jp8rƌhذ!VX{ʕؼy3?bkܪR-O/Wї_~iјwI9n>7ofWg"鲎rdtc cӼԄVj~*?,o 6;MyPŁˎ8A>-`ҤIXt)CZZ;f|3G;՘j jPM -^3)9&4ݣln j8XԪᴙӪB[V4l"hF'hpڶ.M6ظq#L-Ǐǖ-[k*OsUn:S-9?2~ 4gͬl6mX]7ɸtbTnEHS-CKͱr7md LHHnZ *;s^ !0sLᩧO`U^z!--"daYL8]K3gN8ۨkǏGNйsgsθ-|g,0uk뮻ШQ# t2ܘ:dݠr涽@ m\3[-鳳D1Ɲ;"ޱ&3m6G8ڍ1BL|Gݴ\2qDVknٲ<rrrf4ҥK'N`ūjcFdPa kԨq-0 [3:'gi> 2ɦذa LnMT ?ɂBsK׬YÎ9uvz^Shv Ñt@b5'bر?>>sdeeO?ܹsq-hԨV5n/g}.e˖Ӎ52;ɭGǭ5'ֹ{;eI|ri{I0͛믿^/mrYTT* SNݵ3k2ɴ4,ZH%%%Xnf̘g}SNŪUиsbkƋ/h̙3J!6mdFa͚5hԨxx*̯oW9/P:O%%%l{u $%KW~}̘1'|$A9f#+s9:L;p[I+bњRSJ`{Fn4 , ڨÇvysϡ$f4lw}ذaiPpFիW#!!uPp|>KVy<|g`fee9jիW 5,tZ>++˒O?e@O?Q(ԯ_3gDM&㑙|c,sss/cȐ!(,,DBB^~e 4H J >҆;9+8zqOVV>#h^u(О={'LC@p8,hܐ?b„ omѣG#)) 1111-՝\p|(›oUV9jvGEN i%;B7IalٲEEEغu+{ e˖ѣx!cݻ7nFԫW^{- //Dvv6o||>zBrr2qW8|ۼmڴA^pWyꪫ,Ò%K 0 ;{+4n ߷oߏkjiӠAɆ(--šC_ ;;[֭ۖ[gϞѣ7ǃٳgz6lhlB`˖-Fn69Ҳ.[ժU 111] H8|0k|'v_>ѫW/~XS@T5W_(¾}cbh׋n )))hҤ L5/ 駟n̫ÇZϠAnѢ !6l؀<ǼSec[NBG56{l*H}nޡCk}m-**2 -M6h߾=:vhK)c[o!77u#<!<_OEsA$$$qF[8bSQQP4ZT(ȼ\1EU%1mye?9W4.B,m u&mjFRкhd=TVR^|(-ӯ4QЩG_ll`S̮Fp[T GSݮ%Yv2['vʫrnYtmr߮E]6sK2O.̓m+Tdg~7nImEbǯ Rv~֙CQ~d-Xp*?:Fk5N۫Y.u774/ TnRzP*3j+Dž"qUr]NNu:WXMCW'%I?.?7T[JPP?u jc:'YuΟ9kYXS^:fmxcUP *@%MjZjln1NbgU؝B مƥÙ*AQtV:8:LCC2[U8IpjH2}UnK:n," 痔wTJƔ,Xp~R %ʏ*0U紙$ z蓪52mB awj9fp+uު:`@_RQ;OjZδS:28zت}, 'sVKP4v6Zn$L8g MXV5yXg'QwU~unE5jb7r U2_QU2&.U '_nI nSJTlX5Ū*~<[G )̅Vr˭qTRXt9`ڝ8e{)y7䘄Vngȹ -7NWMF/uD 2-=ց'wB9E2wh[SBh_U ǩ;G.?|f,9=~S .UPq/KlWز|:UmRw&7L;NJ"KƕA{\.ݜY2ʬnk(ڛN3]U niI2Z7wSJ]^T]ݩGI 伿~*KL6Po g4٭A: :tNU@p==nޢSwl 'Tי: .Pw~BZ?TH:݉N[tkvwjeR'ל1 gfe#/:7j.Av]#Diݑ&+-t (ݸBNz ;)i|;SVKUrSZ9mf7.ԍ:)t'bۙ9PPIͬ^f缓f*yi/k/v);KG}nd{<n1n;`ōUNvMܬ.Na䵣..c'p2Ntq;nI 8pځƉQsJ&7v nbgqx7}wjouhD{;Z]xrf,hfZq!-65X7簓|vK7Wt;:ڼNtad7:c9n]<m &PuʮC;Y]\H۪{fu7h op_3?f 8w! M/[Vw|:U$NZݭfT֧۽ᶮ_v~ȑ#߿? tŝ^jeeexѷo_4l+ѳgOYtJ< !66V6|y_\*o߾-[T3pd϶m0j(LUVe˖СfرXt̷ZIDATr%oyyC 4o:xH 0/nݺ8:up̙ ^X;.g0ɧUV) au-iDo _nݺ֭GºƋM& !O@)UUU:u7Շ^+O_ȩ|/y/^}/G>}`tʀ 0-O.Cf,MZl)7|#Zj1{lQVVf-++7nD=Dnn@@̟?_\yb"''G?^߿_ :RE [}Dnnoݻ46m2ޏ?Xl޼Yddd7o\lٲEl߾]nZ>Ooeee\?^ݻWtR~LL(((СCb4@rqIqm:uut`PA D85x-Zf݊+裏 -[D&MFѤIcFf͚aѢESyLkEݺud$%%!7qpYk͚54m/mpgϞř3g~7]za„ sixg PӦMtR˜7 aÈ+/ܔ& "''ɓ'㦛n2ѓUڸ4LZ[)2Ek0ٕW^i_ZjѣG[͛7@tʕ+1n84hxܹطoQvz,Jm@J_'l^^֮]kiӦ2J֭M͙30йkpmYXp޺u3|^gϞ|!c@`^`SL~qy8GIyyi 1i$rJx 5'/;v̴^ALu?{ݺu4]vE-ZԦRFVV:P(#Gn޼?*++SN5%U5ϥ)H$ӧ#11?.]  =qqqȰ}饗P^^Jl޼M6E B!KkРA̚5 7x#BSO? ڂOR |^G?TG-жm[KLTVV"33w}7Zjeߊ+PQQc-A!TYKܔڵ+֮]>z+L2cǎE=l>,i)=~Xj,fejj*{n5 v]w݅AO>귛7rɼ?}iL|~g M-ya͚5[1rH6MII v؁ݻB Ni1%5|L2?v؁9ss\uUHKKcLGŞ={p 7;> /FJJcvԅKCF 0py^߿?j׮mJWTTiӦW\>}X@'OѾ}{x<cGS׵8owOB͵f ;ֲxIL4 {F42 bɒ%1bn xѲeKvC7:i8NNP(dىr;Jχ~YҮ[C A a-M6nЂRkʱ%E醴}ښ}*(gݺu1dK<|ͬ\v-̙c̭X4J>2e˖*** `={{vLր{ h׮4111HII1ї3ez@@U _LiCQ9Ң55kk䴑ٲe~NK j(UAxзo_Kӧ6Z8 kޔ[n1-$%%y4ҌJ-'Hkx)Y\\l}ڵ8s .\駟, oݺu1h S~"< gff̙3>|mU{QS]4E%0tPB8?`mذaHLL,HF5M7d_~lΝ-[Ш7ғؙ3jElvԉ N0M6ERRcf6lbcc ׳gO6</YGFrrEq|rμ[d P\\B{ĨQLѳgOck׮+,u.]јiTTѝBSNui GGSg}elH۷GQQ xЬY3 2<?UV8~8Ξ= χMb̘1߿VX!55{z<;uSN^ɸ׿͛7Gvp9s>͛7رc1`9'O ++ iiizx 6-KmڴA֭DPRR7O>ALL zs=q'cbbp19r{/LR9u>tU{iw^Z~٦W={ r^ M3~sRPjSmcdsKT搻;L=?j:Sh;~?[vm\veƧf?E J9C]^¤iTv7 YnO; ;XLw!˔+:MQoC{[@iݙCkӋW_qiyW`|_ϔn4nBy;79^SݳjW&sNs7ҩٕK34; ykLًGqq1bbbc5Ԩ;bMtZH5I+UsVZUuPIdkN@Y:Г ]vڨ]6bbbjLًd2fK}UsOe:<ՄTUə4֙|NXssS]^N;tjQ\|ɓ'㩧B(W_}sY@)#pguCҗsĨ9/ txj:l9`ڝwZԂp:Ԛ1e/Nϒ%KpBcnBBZlo7xڥzd))p893e#3euN-Uc~[0innVM- N)0܅Q)j_4uC{4sLZn9A= vMw'nLTWM{\{)9gQ){c|ÁUߩLN⫚G'L\#TAzu;脆n3aUmsqVմy[٨2 uu7LH`݂:yoՅ;й17N氪Cn֠u&2`^&*P[rkiEPb7kIA0u~Un{uc'`Lk4%5u(zJQpkwe .BN::vS-i%u8i{."9$#MX8Qsts6ܽPG猱iJ7UnhZn-.ԯƔ@sPPJm1uUjwi;Z&GWѮTWpIENDB`commons-javaflow-0.0~svn20060411/xdocs/images/javaflow-logo-white.xcf0000644000175000017500000005445210172544102025254 0ustar drazzibdrazzibgimp xcf filePBBT/ gimp-commentCreated with The GIMPS gimp-commentCreated with The GIMPgimp-image-grid(style intersections) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) ):LBWGcommons      8qU8Uq8q8q q UU88UU8qUqUUUqUUUqUUq8U8 UU 8q8U8 q   8U 8U UU UU UU 8UU U 8 88 U q 8888 q8 q8qUUUUUqU UUUU U 8qUq q8UqUU8qU 8q8U8 8UqU8qqq88qqUUqUUUqƪUqUUUU8Uqq q8UUU 88UUqq UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU UUUU qUq qUqU8qU88qU8UƍUUUU8q qq q8  8qUU88qU 88 8UU UUUU8U8UUUUUUUUU8q 8UqUUU UUUUU 8UUUU UUUUU UUUU UUUU UUUUUU UUUUUU UUUUU UUUUUU UUUUU8 UUUU qUUUUq UUUUq8UUUUUUUUqUqU88UUqqU8q8qUU 8Uq8 q 8VVV UU ⪪88888Uqqq88  q 8 qU  qU qq8qƪq888UUk 58 Drop-Shadow     98:4:@8 Y'1U                    !#$%%$# !"##$%%$"   "$&')*+,,+*'%"!#$&'())*+,,*(&#! !$&(*+-.01221.,)&#! !#$'(*+,--./0234431.,)  #'),-/01346787642/,)(''(*,./11223568:;;9752 !&*-/12334679:;<;9742/..0245677665668:=?ABCB@=: "',02456678:<=>>=;97544579;<==<:9878:>=;:99:<>ABCCB@=;988:=@EIMOPONK &-38;==<:8655679;<=>==>@BEGIIHFC?;9779<@FKPSUVTR $+29=@AA>;853223579:;<==?ADGKMOOMJE@;7556:?EKQVZ[ZX  (08>CEED@<830..024689;=@CGLPSTSQLGA;63237=CKRX\__] $,5=CGJIGB=72.+))*,.1369<@EJOTWXWTOHA:40/04:AJRY^aba '09AHLNMID>71+(%%'),/26:@FLRW[\[WQIA93.,-17?HQY_cdd  )3=ELPRPLF?70*%"!!"$'*.38?FMTZ^_^YSJA92-*+/5=FOX_dfe ",6@HOTUSOIA81*$!!#'+06>ENU\`a`[TKB91,))-3;DNW^cff #-8BKSWYWRLC;2+% !$(.55-'" #'-471,)&%&'*.3:AJRZ_bc`ZSJA93/-/28@HOUY[[ !+6ALV]bdd`[TME>83/,*)*+.38?GOV\`a_ZTLC<610149@FMRUWW (3>IS[aeec_ZSLE?:52/--/27=DKRX\]\YSME>94336:?EJOQRR %/:EOX_ceeb^XRLFA<741/./149?FMSWYYWSMF@;7557;?CGKLML !+5@JS[`dec`\WQLFA<741/./15:@FLQTUSPLGB=9778;>ADFGGF &0:DMU\`bba]YTOID?:51.-,.04:?EJMOOMJFA=:88:<>@AA@? !*3=FNUZ]_^\YUPJE?:50-*))+.27=AEHIHFC@=:87789:;;:98 $-5>FMRVYYXVRNIC>83.*'%$%(+059=@BBA?=:8755421 &-5=DINPRQPMID?:4/*%" !$(,048:;;:875321100/.,+* %,3:?CFHIHEB>94/*%! $(,/13310/.-,+*('%$# $*059<>?><:62.)$  #&)+,,+*)('&%#"  !&+.134431.*&"!#$%%$$#"!  !$')**)'%"                    "                              !!"#$$%%$#"!  !"##! !!"#$%!$&'))*+,-.//.-,*))()*+,,*(%!"$&())**+,-. #&*-/123345789987642112345531-*&" #'*-012334567'%%&(+/369;<==<<=>@ACCDCB@><::;=>>=:62.)&$$%'+/37:;<=<<=>@/--.037<@CEFFEDDFGIKMMKIGECAABCDFGFEC?:51-+*,.27<@CEFFEDDEFH86558;@DILNOOMLKJJLNPSUVVTROMJHGGIJLMNMKGB=841125:?DILNONMKJJKLN@>==?CHLQTVWVTRPOOPRUX[\]\YVSPMLLMOQSTTRNID?:778;@FKPTVVUSQOOQSHEDDFJNSX[]][YVSRQRUX\_aba_\XTQONOQTVXXWTPJE@=<=@EKQWZ\\ZXUSQQSVOLKJLOTY]`ba_\XUSRSUY^adfec_[VRPOPRUX[\[YUOJEA@ADJPV[_``^ZWTRRTWUSQPQTY]adedb^YURQRUY^bfhgea\WSONOQUY\^^\XSNHECDHMSY_bcb`\WTQQSV[XUU;X\`dggfc^YTPOPSW]bfhhfb\WRNLMPTX\_`_[VQLHFGJOU\aded`[WRPOQT_\YXY[^bfhhfb]WRNLMPU[`ehhfb\VPLJKNRW\_a`]YSNJHHKPW]befd`[UPMLNRb_\[[]`dgiifb\UPKIJMRY_dggea[TNJHHKPU[_ba_ZUPKIJLQW]beec_YSNJIKOca^\\^adgiheaZTMIGGJPV]befd`YSLHEFINTZ_ab`\VQLJJMRX]beeb^WQKHGHLda_]]^adghhe`YRKGDEHMT[`dec^XQKFCDGLRY^ab`\WQMJJMRW]bdda\VOIFDFJda_]]^adghgd^XPJEBCFLRY_cdb]WPIDBBEKQX^aba]XRNKKMRW]adc`[UNHDBDHc`^\\^`cfgfc^WOICAAEJQX^bca\VOHCAADJPW]aba]XSNKKMRW]acc`ZTMFBABG`^\[[]_cegfc]VNHC@@DJQX^aba\UNHB@@DIPW]aba^YSOLLNRW]acc_ZSLFB@BF][YXY[^befeb\UNGB?@CIPW]ab`\UNGB@@CIPW]aba^YSOLLNRW\`cb_YRKEA@AEZXVVWY]`deea\UNGB?@CIPW]ab`[UNGB@@CIOW]aba^YTOLLNRW\`bb_YRKEA?AEUTRRTW[_bdda[UMGB?@CIPW\`a`[UNGB@@CIOV\`ba^YTOMLNRW\`ba^YRKEA?AEPONNPTX]acb_[TMFB?@CHOV\_`_ZTMGB@@CHOV\`a`]YTPMMNRW\_a`]XQJEA?AEJIIJLPUZ^``^YSLFA??CHNU[^_^YTMGB@@CHNU[_`_\XSOMLNRV[^`_\WQJD@?ADD2EHMRW[^^\WQKEA>?BGMSY\]\XRLFA??BGMSY]^][WRNLLMQUY]^]ZUOIC@>@D>=>@CHMSWZZXTNHC?==@EKQVYZXUOJD@>>AEKQVY[ZXTPLJIKNRVY[ZWRLFA>=>B778:>CHNRUUTPKE@=;;>BHMRUVTQLGB><<>CHMRUWVTPLIGGHKOSUVVSOID?<;CHLOPNKGB>:88;>CHLOPPNKHECCDFJMOPPMID?;878;))+.27BFHIHEA=96446:>BFHJIGEB?>>?ADGIIGC?:64347"#$'+059=?@?<952/..037;>@A@>:731//147;>@AA@=;9878:=?AA?<841/./1!$(-146641.+)((*,/2578752/,*))*-035788753100134688630-*)()+!%(+-.-+)'$#""#%(*-./.,*(%$##$&(+-.//.-+*))+,.//-+)&$""$!#$%$#!  #$%&%$" !#$&&%$#"!!"#$%&&%#!                         9 ,                     %%$#"!  !""##"    !"#//.,+*)(()*+,,+)&# !"#$%%$#!"$')+,,89987532112245542/+'" "$%&'()*+,--,+*(&#"!!"$'*.13566BCDCCA?=;::;<=>><84/*&" "%')*+,-./01234420.,*))*-037;=?@@JLMMLKIFDBAABCEFGFDA=83.)&%%&(*,.0112234689;<<;975321358=AEGIJJQSUVUTQNLIHGHIKMNNLJE@;61.,,-/24567665679<>ABCCB@><::;>AFJNQSSVY[\\[XUROMLLMORSTSQMHC>964468:;==<;9889;>BEHJKJIGECBCFINRVY[[ZZ]`bba^ZVRPNNPRUWYYWTOJEA><=>@ACCB@>;9889;?CHLOQQPOMKJKMQUY]`aa_[_cefeb^YUQOOQSWZ\]\ZVQLHFDEFGIIGD@=9778;?DIOSVWWVTRQRTW[_cefebZ_dghgd`ZUQONPSV[^``^[WSOMLLMOPONKGB=86458=CIPUZ\]\ZYWWY\_cghigdY^cghhe`ZUPMLNQUZ^acb_\XUSRSTUVURNIC=74236;AIPW\`aa`^\\]`cfikjhdW]bfhhe`ZTOKJLOTY_bdec`][YXYZ[[ZVQJC<61/028?GOW^bdedb``acehklkhcT[`eggd_XRMIHIMRX^cfgfda_^^=`a`^ZTLD<50--055.*(*.5>HQZaeggfeddegijjhc]LSZ_bb_ZSLFA@AFLS[bgijjhggijkkid]TJ@70+)+/5>GPX_ceedcbbdfhiigb\LSY_bb_YSLEA@AELS[afijihffhijjid^ULB92-+,/5=FNV\`bba``bdghhfb\KRY^aa^YRKEA?AEKSZafhihfeddeghigd^VMD<50-.16=EMTY]^^]]^`ceggea[KRY^aa^YRKEA@AEKSZ`eghfdbaabdefeb^WOF>830037=DKQVXZYYXYZ]`cefd`ZKQX]``]XRKEA@AEKRY_dffdb_^]^_abb`\WPHA:63358>CINRTTUWZ]addc_ZJQW\__\WQKEA@AEJQX^bcca^[YXYZ\]^]ZUOIC=86569=BGJMNONNPRVZ^aba^XIOUZ]]ZVPJDA?@DIPV[_``]ZWTSRSUWXXVSNIC>:878:=@DFHIHHJMRV[^_^[WGMRWYYWSMHB?>?BGMSX[\[XUQNLLNPQRQOLGC?;9889;>@ABBABDHLQVY[ZXSDJOSUUSOJE@=<=@DJOSVWVSOKHEDEFHIKKJGDA>;97789:;<<;::<>BGLPTVVSO@EIMOOMJE@<989<@EIMPPOLHD@><<=?ABCCB@>;976556543357;@EJMOOMJ;?CGHIGD@;85457;?CFHIGDA=9654568:;<;:9754221100/.-,+,.049>BFHHFC48?@><-14677641.+*))+.13677530,)&%$$%'(*+,,+*)('&%$"!  "&*.256764&)+-./.,)'%##$&)+-..,*(%" "#$%%$#"! #&),-.-+!#$%%#" !#$%%$" !#$%$#                        !   *                  #$$%$"  -.-,)&"  678753/+'"!#$%&&%$#! @?@AA@?<84/*%" !#%(*,--,+*(&# IHGGHIIGEA<71,)&%&'*-/1344321/-*'# QPNNOPPOMJE?94/-,,.1479:;::8641.*&! WUSRRSTUVVTQLF@;632247;>@AA?=;851-(# \YVUUWYZ[ZWRMGA<978:=ADFHHGEB?<840*% _[XVUVX[]^^\XRLFA><=?BFJLNNMKHD@<72,'! _[WUTUX[^`a_\VPJEB@ACGKNQSSRPMID@:5/(" _ZVSRSVZ^aba^YTMHDCCFINRUWXWURNID>81*$ ^XSPOQTX]acc`\VPJFDEGKPTXZ\[YWSNHB<4-& \VQNMNRV\`cca]WQKGEEGKPUY\^^][WSMG@91)" ZTNKJKOTZ_bcb^XRLGEDFJOTY]`aa_\XSLE=5-% YRLIGIMSY^bcb^XRLGDCDHMRW\_bcb`\XRKC:1)  WPJGFGLQX^bcb^XRKFBABEJOUZ^acdc`\WPH?6-$ VOIEDFJPW]acb^XQKEA?@BFKQV[_bddc`[UMD;1( UNHDCEJPV]acb^XQJD@==?CGMRW\`bdcb^XQH?5+" UNHDCEIPV\acb^XQJD?<;;:;=@EINSX\_aa_[UMD:0& TMGDCEIOV\`bb^XQJD>;99;>AEJNSW[]^]ZUNE;1( SMGDCEIOU[`ba^XQJD>;98:<>BFJNRVYZZXSMD;1( RLGCCDINUZ_a`]WQJD>;989::8789:@CFIJJIE@:2*" JEA?>?CHMRUWVSOJD?;75445678:<>@BCCB?:4-& EA=;:BFHJIGC?;630/../0123455430,'" 95311247;>@AA?<840.+*))*+,--..-+)%! 1.,**+-025787630-*'%$$%&'&%$! )'%$$&(*-./.-+(&#!  ! !"$%&%$#!                    z=y& javaflow     e$R.gimp-text-layer(text "javaflow") (font "Times New Roman Bold") (font-size 32.000000) (font-size-unit pixels) (hinting yes) (antialias yes) (language "nl-be") (base-direction ltr) (color (color-rgba 0.000000 0.000000 0.000000 1.000000)) (justify left) (box-mode dynamic) (box-unit pixels) <;y&EJNONLIEB?=<<=>??>?@><:741/--./135 &/9BJPTVUSPMJHGFFGHIJJIHIJJIFC@=:7545679KWbkquwwvuttvwy{|{zwsojfcbbcdefec_[WSQPQTX]ci (3@MYdmswxxwvutuvwyzzxuqlgc_]]_`aa_\XTQONORW\bh )5ANZemswxxwutssuvwwvtqlgb]YWVWXZ[[YWTPMKKMPTZ`e  +6CO[ensvwwusqpoopqqpmje`[VRONOPQRSRPMJHFFHKPU[` ",8DP\fmruutqoljiiheb]XRMIGFFGHIJIHECA@@BEJOTZ $.9EQ\elprrplifca``_][WSNID@><<=>?@@?=;:99;?CGLQ %0;FQ\djmnmjfb^[XWVUTSROLHD?;7433456654311247:?CG '1;FQZbgiigc_ZUQNLJIHGEC@=951-+*)*+,,+*))*,.269= (183/,)'&%#"  &.6=DJMONKFA;4.)%"   #*28>BEFEB=71+&!     &,27:<<;84.)#   !&+/2331.*&!    $')**(%"   !!     #  %  '+/5*,(#  !        "$&''&%#    #&*,/1221/,)$   #(-158;=>??=;83.("   &,17<@DGIJKKIGC=70)"    "(/5DLU]djosvxyz{zyvrld\SJB;51-+*((''()+,./1223320/,-/13468:=AGNU]elrvy{|}~~|xrkcZRJD>:754321124579;<>??><:77:<>?ACEGKPV]elrw{}~{wpiaZSMHEB@>==<<;<<=>@BEGIJKLLKIFCBDGIKLNOQUY^ekrw|~ŀ~zuohb[VROLKIHHGGFFGHIKMPRUVXXYYXWURNLORTVWYZ[^afkqv{}ytnid_[YWUTSRRQQPQQSUXZ]`bcdeedca^YUY\^`bbcdehlpuz}~~|xtokgdb`_^]\[[ZYYZ[]`cfikmnoomkhc]aehjkklnptx{~~}||}~|xuqnljiggfedcbaabdgjmpsuvwwvspjdiloqrrqrtvy|~~|zyyz|~~{yvtrponmlkjihffhknqtwz{|}}{yupinruwxxwvuuvwy|}~}{ywvvwy|~}{ywvtsrqponmkjhhjlosvy|~~|xsmrvy{{zxwvvwxz{{zxusrrsvy{}~}{zywvuutsqpnljihhiknqux{}~}{xsotx{|}|zxvuuvwwvsqonnoruxz||{zyxwvutsrqomkifedegjmqtwyz{{zxupnswy{{zxvtrrqrssrqnljiijmpsvwxxwvuutsrrqonljgdb`_`adgknqstuutrokkpsvwwvtrpnmllmmljhfdbcdgjmoqqponnmmlkigda^\YXXY\_behjlljhdfjnpqqpnkigffeca^]\\]_begiihgfecb`]ZWSQOOPRUX[^`abb`^[_cfhiigeca_^]]\[YWUTTUWZ\^``_^^]]\ZYWTQMJGFEFHKMPRTUVVUSPVY\^^][YWUTTSRQOMLKKLNPRTUUTSSRQPOMJGC@><;<>@BEGHIJJIHEKNQRSRQPNLKJJIIHGFDCBBCDFHIJJIHGFEDB?<9642123579;<=>>=<:@CEFFEDBA@?>>=<;:889:;=>>=<;:9752/,*)(()+,.01221/579::98765443210//012343322110/.,*(&#!  !#$%&''%*,-..-,+**))('&%%&'())('&%$#!!"##$##""!                 !@666       *&# 40+'" ?:4.(" ID=6/(! SME=5-% ]UMD:1(  d\SI?4+" i`WLA7-# lcYNC8-$ lcYNC8-# iaWMA6," e]TI?4)  ^WNE:0& VOG>5,# LF?7/' B=70)" 73.(" -*&! $!        'K%,d Background     W,dXYYY,dXBX`XpXXXXXXX:        &>>Q            00002K% commons-javaflow-0.0~svn20060411/xdocs/index.xml0000644000175000017500000000314110325366476021256 0ustar drazzibdrazzib Overview Commons Documentation Team

Sometimes it is usefull if we can capture the state of the application, its stack of function calls, which includes local variables, the global variables and the program counter, and save them into an object. If this object would give us the ability to restart the processing from the point stored in it.

A continuation is exactly the type of object that we need. Think of a continuation as an object that, for a given point in your program, contains a snapshot of the stack trace, including all the local variables, and the program counter. You can not only store these things in the continuation object, but also restore the execution of the program from a continuation object. This means that the stack trace and the program counter of the running program become the ones stored in a continuation.

Continuations are powerful concepts from the world of functional languages, like Scheme, but they are becoming popular in other languages as well.

See the downloads page for information on obtaining releases.

Starts with the tutorial. The JavaDoc API documents are also available.

commons-javaflow-0.0~svn20060411/xdocs/antTask.xml0000644000175000017500000000455410325366476021565 0ustar drazzibdrazzib Ant Task Commons Documentation Team $Id: downloads.xml 155451 2005-02-26 13:22:47Z dirkv $

commons-javaflow.jar contains an Ant task implementation that instruments class files for javaflow. To use this task in your build script, first declare it as follows:

... ]]>

The javaflow task forms an implicit FileSet and supports all attributes of <fileset> (dir becomes srcdir) as well as the nested <include>, <exclude> and <patternset> elements.

Attribute Description Required?
srcdir directory from which the instrumented class files will be read. This is used as the base directory for the implicit FileSet that the javaflow task forms. yes
destdir directory to which the instrumented class files will be placed. This can be the same directory as the source directory. yes

When srcdir==destdir, class files are touched only when they are not yet instrumented.

]]>

Instrument all the class files in the build/classes directory in-place.

commons-javaflow-0.0~svn20060411/TODO0000644000175000017500000000203110354562056016764 0ustar drazzibdrazzibIn no particular order: o integrate just4log into the build system o testcases!!!! o documentation of the rewriting process o fix rewriting bugs/limitations: o fix unintialized objects for method/constructor calls o inner classes o try/catch/finally o synchronized(obj) o accessing .class o new Object() without assignment o only wrap the function calls that may lead to a suspend (control flow analysis) requires 2-pass analysing/rewriting o maybe: evaluate making the Stack class use a hierarchical approach to support differential continuations o maybe: asm implementation instead of BCEL o BCEL o commit bug fixes in BCEL http://issues.apache.org/bugzilla/show_bug.cgi?id=27646 http://issues.apache.org/bugzilla/show_bug.cgi?id=27854 http://issues.apache.org/bugzilla/show_bug.cgi?id=27855 o get rid of the static repository approach http://issues.apache.org/bugzilla/show_bug.cgi?id=38057 o talk to the RIFE guys about joining forces o talk to the aspectwerkz and aspectj folks about working together