├── .gitignore ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── benchmark ├── README.md ├── saker.build └── src │ └── benchmark │ └── sipka │ └── jvm │ └── tailrec │ └── TailRecursionBenchmark.java ├── resources └── META-INF │ ├── BUNDLED-LICENSES │ └── nest │ ├── dependencies │ └── tasks ├── saker.build ├── secret └── readme.md ├── src └── sipka │ └── jvm │ └── tailrec │ ├── MainCommand.java │ ├── TailRecursionOptimizer.java │ ├── saker │ └── build │ │ ├── OptimizedContentDescriptor.java │ │ ├── OptimizedSakerFile.java │ │ ├── OptimizerTaskFactory.java │ │ ├── OptimizerWorkerTaskFactory.java │ │ ├── OptimizerWorkerTaskIdentifier.java │ │ └── zip │ │ ├── OptimizerZipResourceTransformerFactory.java │ │ └── OptimizerZipTransformerTaskFactory.java │ └── thirdparty │ └── org │ └── objectweb │ └── asm │ ├── AnnotationVisitor.java │ ├── AnnotationWriter.java │ ├── Attribute.java │ ├── ByteVector.java │ ├── ClassReader.java │ ├── ClassTooLargeException.java │ ├── ClassVisitor.java │ ├── ClassWriter.java │ ├── ConstantDynamic.java │ ├── Constants.java │ ├── Context.java │ ├── CurrentFrame.java │ ├── Edge.java │ ├── FieldVisitor.java │ ├── FieldWriter.java │ ├── Frame.java │ ├── Handle.java │ ├── Handler.java │ ├── Label.java │ ├── MethodTooLargeException.java │ ├── MethodVisitor.java │ ├── MethodWriter.java │ ├── ModuleVisitor.java │ ├── ModuleWriter.java │ ├── Opcodes.java │ ├── RecordComponentVisitor.java │ ├── RecordComponentWriter.java │ ├── Symbol.java │ ├── SymbolTable.java │ ├── Type.java │ ├── TypePath.java │ ├── TypeReference.java │ ├── package.html │ ├── signature │ ├── SignatureReader.java │ ├── SignatureVisitor.java │ ├── SignatureWriter.java │ └── package.html │ └── tree │ ├── AbstractInsnNode.java │ ├── AnnotationNode.java │ ├── ClassNode.java │ ├── FieldInsnNode.java │ ├── FieldNode.java │ ├── FrameNode.java │ ├── IincInsnNode.java │ ├── InnerClassNode.java │ ├── InsnList.java │ ├── InsnNode.java │ ├── IntInsnNode.java │ ├── InvokeDynamicInsnNode.java │ ├── JumpInsnNode.java │ ├── LabelNode.java │ ├── LdcInsnNode.java │ ├── LineNumberNode.java │ ├── LocalVariableAnnotationNode.java │ ├── LocalVariableNode.java │ ├── LookupSwitchInsnNode.java │ ├── MethodInsnNode.java │ ├── MethodNode.java │ ├── ModuleExportNode.java │ ├── ModuleNode.java │ ├── ModuleOpenNode.java │ ├── ModuleProvideNode.java │ ├── ModuleRequireNode.java │ ├── MultiANewArrayInsnNode.java │ ├── ParameterNode.java │ ├── RecordComponentNode.java │ ├── TableSwitchInsnNode.java │ ├── TryCatchBlockNode.java │ ├── TypeAnnotationNode.java │ ├── TypeInsnNode.java │ ├── UnsupportedClassVersionException.java │ ├── Util.java │ ├── VarInsnNode.java │ └── package.html └── test ├── resources └── testcontents │ └── testing │ └── saker │ └── sipka │ └── jvm │ └── tailrec │ ├── OptimizerTaskSakerTest │ ├── saker.build │ └── src │ │ └── test │ │ └── Main.java │ ├── RepackageArchiveOptimizeSakerTest │ ├── saker.build │ └── src │ │ └── test │ │ └── Main.java │ ├── SimpleJarOptimizeSakerTest │ ├── saker.build │ └── src │ │ └── test │ │ └── Main.java │ └── SimpleZipOptimizeSakerTest │ ├── saker.build │ └── src │ └── test │ └── Main.java ├── src-jdk8 └── testing │ └── sipka │ └── jvm │ └── tailrec │ ├── InterfaceDefaultMethodTest.java │ ├── InterfaceStaticMethodTest.java │ └── LambdaCountTest.java └── src └── testing ├── saker └── sipka │ └── jvm │ └── tailrec │ ├── OptimizerTaskSakerTest.java │ ├── RepackageArchiveOptimizeSakerTest.java │ ├── SimpleJarOptimizeSakerTest.java │ └── SimpleZipOptimizeSakerTest.java └── sipka └── jvm └── tailrec ├── AfterTryCatchTest.java ├── ArrayAccessReturnPathTest.java ├── BeforeTryCatchTest.java ├── CollectInterfacesTest.java ├── ConditionReturnPathTest.java ├── CountTest.java ├── FactorialTest.java ├── GetFieldReturnPathTest.java ├── GetStaticReturnPathTest.java ├── IfElseFalseBranchTest.java ├── IfElseTrueBranchTest.java ├── IfEndCountTest.java ├── InstanceCountTest.java ├── InstanceOfModifyReturnPathTest.java ├── InstanceOfReturnPathTest.java ├── LookupSwitchReturnPathTest.java ├── LoopReturnPathTest.java ├── MiscMethodsTest.java ├── MultiVariableCounterFactorialTest.java ├── NewArrayReturnPathTest.java ├── NumberConcatTest.java ├── OptimizationImplEdgeCasesTest.java ├── OutsideSynchronizedCountTest.java ├── TableSwitchReturnPathTest.java ├── TailRecOptimizerTestCase.java ├── TypeCastCountTest.java └── VariableCounterTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /bin/ 3 | /.classpath 4 | /.project 5 | /.saker.build.ideconfigs 6 | /.saker.project.lock 7 | secret/** 8 | !secret/readme.md 9 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - master 3 | 4 | pool: 5 | vmImage: 'ubuntu-latest' 6 | 7 | jobs: 8 | - job: Build 9 | steps: 10 | - script: curl -L https://api.nest.saker.build/bundle/download/saker.build-v$(curl -s https://mirror.nest.saker.build/badges/saker.build/latest.txt) -o saker.build.jar 11 | displayName: 'Download saker.build' 12 | 13 | - script: $(JAVA_HOME_8_X64)/bin/java -jar saker.build.jar -bd build -trace pwd://build/build_test.trace test 14 | displayName: 'Test' 15 | - task: PublishBuildArtifacts@1 16 | condition: always() 17 | displayName: 'Publish test trace' 18 | inputs: 19 | pathtoPublish: build/build_test.trace 20 | artifactName: trace 21 | 22 | - script: $(JAVA_HOME_8_X64)/bin/java -jar saker.build.jar -bd build -trace pwd://build/build_export.trace -trace-artifacts-embed export 23 | displayName: 'Export library JAR' 24 | - task: PublishBuildArtifacts@1 25 | condition: always() 26 | displayName: 'Publish export trace' 27 | inputs: 28 | pathtoPublish: build/build_export.trace 29 | artifactName: trace 30 | -------------------------------------------------------------------------------- /benchmark/README.md: -------------------------------------------------------------------------------- 1 | # Benchmarks 2 | 3 | This directory contains benchmarks for the library. \ 4 | You can run it by first building the `export` target in the `saker.build` file of this directory: 5 | 6 | ```plaintext 7 | # in the project root directory 8 | java -jar saker.build.jar -build-directory build export benchmark/saker.build 9 | ``` 10 | 11 | And then running the benchmarks with: 12 | 13 | ```plaintext 14 | # in the project root directory 15 | java -jar build\saker.jar.create\benchmark-optimized.jar 16 | java -jar build\saker.jar.create\benchmark-unoptimized.jar 17 | ``` 18 | 19 | ## Results 20 | 21 | These are our benchmark results. See the [benchmarked class](src/benchmark/sipka/jvm/tailrec/TailRecursionBenchmark.java) for information about the cases. 22 | 23 | **Higher values are better.** 24 | 25 | ### Optimized 26 | 27 | ```plaintext 28 | Benchmark Mode Cnt Score Error Units 29 | TailRecursionBenchmark.countTest thrpt 25 436354,616 ? 2208,882 ops/s 30 | TailRecursionBenchmark.factTest thrpt 25 1201126,490 ? 8081,594 ops/s 31 | TailRecursionBenchmark.numbersTest thrpt 25 2183,977 ? 62,684 ops/s 32 | ``` 33 | 34 | ### Unoptimized 35 | 36 | ```plaintext 37 | Benchmark Mode Cnt Score Error Units 38 | TailRecursionBenchmark.countTest thrpt 25 257429,802 ? 1501,296 ops/s 39 | TailRecursionBenchmark.factTest thrpt 25 831008,693 ? 9108,785 ops/s 40 | TailRecursionBenchmark.numbersTest thrpt 25 2083,716 ? 14,563 ops/s 41 | ``` 42 | 43 | ### Conclusion 44 | 45 | We can see that the tail recursion optimization always comes with some advantage. However, as the workload for each call grows bigger, this advantage grows smaller. This is due to the fact that the cost of the extra function call starts to diminish when compared to the work that is performed by each method. 46 | 47 | I think the advantage of the tail recursion optimization lies in avoiding stack overflows rather than the actual performance benefits of it. 48 | -------------------------------------------------------------------------------- /benchmark/saker.build: -------------------------------------------------------------------------------- 1 | static(JMH_DEPS) = saker.maven.resolve([ 2 | "org.openjdk.jmh:jmh-core:jar:1.23" 3 | ]) 4 | compile( 5 | out javac 6 | ){ 7 | $javac = saker.java.compile( 8 | src 9 | ClassPath: saker.maven.classpath(static(JMH_DEPS)) 10 | AnnotationProcessors: [ 11 | saker.java.processor( 12 | ClassPath: saker.maven.classpath(saker.maven.resolve( 13 | "org.openjdk.jmh:jmh-generator-annprocess:jar:1.23" 14 | )) 15 | Class: org.openjdk.jmh.generators.BenchmarkProcessor 16 | ) 17 | ] 18 | Identifier: benchmark 19 | ) 20 | } 21 | export( 22 | in compile = include(compile), 23 | ){ 24 | $javac = $compile[javac] 25 | include(_export_jar, name: benchmark-unoptimized.jar, classdir: $javac[ClassDirectory]) 26 | include( 27 | _export_jar, 28 | name: benchmark-optimized.jar, 29 | classdir: sipka.jvm.tailrec.optimize($javac[ClassDirectory]), 30 | ) 31 | } 32 | 33 | _export_jar( 34 | in name, 35 | in classdir, 36 | 37 | out jar, 38 | ) { 39 | $jar = saker.jar.create( 40 | Output: $name, 41 | Includes: foreach $apath in saker.maven.download(static(JMH_DEPS))[ArtifactPaths] : [ 42 | { 43 | Archive: $apath 44 | Resources: **/*.class 45 | } 46 | ] 47 | Resources: [ 48 | { 49 | Directory: $classdir 50 | Resources: ** 51 | } 52 | ] 53 | Manifest: { 54 | MainAttributes: { 55 | Main-Class: org.openjdk.jmh.Main 56 | } 57 | } 58 | ) 59 | } -------------------------------------------------------------------------------- /benchmark/src/benchmark/sipka/jvm/tailrec/TailRecursionBenchmark.java: -------------------------------------------------------------------------------- 1 | package benchmark.sipka.jvm.tailrec; 2 | 3 | import org.openjdk.jmh.annotations.Benchmark; 4 | import org.openjdk.jmh.infra.Blackhole; 5 | 6 | public class TailRecursionBenchmark { 7 | @Benchmark 8 | public void countTest(Blackhole bh) throws InterruptedException { 9 | count(1000, bh); 10 | } 11 | 12 | @Benchmark 13 | public void factTest(Blackhole bh) throws InterruptedException { 14 | bh.consume(fact(1000)); 15 | } 16 | 17 | @Benchmark 18 | public void numbersTest(Blackhole bh) throws InterruptedException { 19 | bh.consume(numbers(1000, "")); 20 | } 21 | 22 | public static void count(int n, Blackhole bh) { 23 | bh.consume(n); 24 | if (n == 0) { 25 | return; 26 | } 27 | count(n - 1,bh); 28 | } 29 | 30 | public static int fact(int n) { 31 | return factImpl(n, 1); 32 | } 33 | 34 | private static int factImpl(int n, int acc) { 35 | if (n == 0) { 36 | return acc; 37 | } 38 | return factImpl(n - 1, acc * n); 39 | } 40 | 41 | public static String numbers(int n, String s) { 42 | if (n == 0) { 43 | return s + "0"; 44 | } 45 | return numbers(n - 1, s + n + ","); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /resources/META-INF/BUNDLED-LICENSES: -------------------------------------------------------------------------------- 1 | ASM: a very small and fast Java bytecode manipulation framework 2 | Copyright (c) 2000-2011 INRIA, France Telecom 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the copyright holders nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /resources/META-INF/nest/dependencies: -------------------------------------------------------------------------------- 1 | saker.zip-api 2 | classpath: [0.8) -------------------------------------------------------------------------------- /resources/META-INF/nest/tasks: -------------------------------------------------------------------------------- 1 | sipka.jvm.tailrec.zip.transformer=sipka.jvm.tailrec.saker.build.zip.OptimizerZipTransformerTaskFactory 2 | sipka.jvm.tailrec.optimize=sipka.jvm.tailrec.saker.build.OptimizerTaskFactory 3 | -------------------------------------------------------------------------------- /secret/readme.md: -------------------------------------------------------------------------------- 1 | # sipka.jvm.tailrec secrets 2 | 3 | This directory contains maintainer-private details for the sipka.jvm.tailrec package. 4 | 5 | In order to upload the exported bundles to the saker.nest repository, there must be a `secrets.build` file with the following contents: 6 | 7 | ``` 8 | global(sipka.jvm.tailrec.UPLOAD_API_KEY) = 9 | global(sipka.jvm.tailrec.UPLOAD_API_SECRET) = 10 | ``` 11 | 12 | It is used by the `upload` target in `saker.build` build script. -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/OptimizedContentDescriptor.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build; 2 | 3 | import java.io.Externalizable; 4 | import java.io.IOException; 5 | import java.io.ObjectInput; 6 | import java.io.ObjectOutput; 7 | 8 | import saker.build.file.content.ContentDescriptor; 9 | import saker.build.thirdparty.saker.util.io.SerialUtils; 10 | 11 | public class OptimizedContentDescriptor implements ContentDescriptor, Externalizable { 12 | private static final long serialVersionUID = 1L; 13 | 14 | private ContentDescriptor inputContents; 15 | 16 | /** 17 | * For {@link Externalizable}. 18 | */ 19 | public OptimizedContentDescriptor() { 20 | } 21 | 22 | public OptimizedContentDescriptor(ContentDescriptor inputContents) { 23 | this.inputContents = inputContents; 24 | } 25 | 26 | @Override 27 | public boolean isChanged(ContentDescriptor previouscontent) { 28 | if (!(previouscontent instanceof OptimizedContentDescriptor)) { 29 | return true; 30 | } 31 | OptimizedContentDescriptor ocd = (OptimizedContentDescriptor) previouscontent; 32 | return this.inputContents.isChanged(ocd.inputContents); 33 | } 34 | 35 | @Override 36 | public void writeExternal(ObjectOutput out) throws IOException { 37 | out.writeObject(inputContents); 38 | } 39 | 40 | @Override 41 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 42 | inputContents = SerialUtils.readExternalObject(in); 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | final int prime = 31; 48 | int result = 1; 49 | result = prime * result + ((inputContents == null) ? 0 : inputContents.hashCode()); 50 | return result; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) 56 | return true; 57 | if (obj == null) 58 | return false; 59 | if (getClass() != obj.getClass()) 60 | return false; 61 | OptimizedContentDescriptor other = (OptimizedContentDescriptor) obj; 62 | if (inputContents == null) { 63 | if (other.inputContents != null) 64 | return false; 65 | } else if (!inputContents.equals(other.inputContents)) 66 | return false; 67 | return true; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "OptimizedContentDescriptor[inputContents=" + inputContents + "]"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/OptimizedSakerFile.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import saker.build.exception.InvalidPathFormatException; 8 | import saker.build.file.SakerFile; 9 | import saker.build.file.SakerFileBase; 10 | import saker.build.file.content.ContentDescriptor; 11 | import saker.build.thirdparty.saker.util.io.ByteArrayRegion; 12 | import saker.build.thirdparty.saker.util.io.ByteSource; 13 | import saker.build.thirdparty.saker.util.io.UnsyncByteArrayInputStream; 14 | import sipka.jvm.tailrec.TailRecursionOptimizer; 15 | 16 | public class OptimizedSakerFile extends SakerFileBase { 17 | private SakerFile subject; 18 | 19 | public OptimizedSakerFile(SakerFile subject) throws NullPointerException, InvalidPathFormatException { 20 | super(subject.getName()); 21 | this.subject = subject; 22 | } 23 | 24 | @Override 25 | public ContentDescriptor getContentDescriptor() { 26 | return new OptimizedContentDescriptor(subject.getContentDescriptor()); 27 | } 28 | 29 | @Override 30 | public void writeToStreamImpl(OutputStream os) throws IOException, NullPointerException { 31 | byte[] optimized = getOptimizedBytes(); 32 | os.write(optimized); 33 | } 34 | 35 | @Override 36 | public ByteArrayRegion getBytesImpl() throws IOException { 37 | byte[] optimized = getOptimizedBytes(); 38 | return ByteArrayRegion.wrap(optimized); 39 | } 40 | 41 | private byte[] getOptimizedBytes() throws IOException { 42 | ByteArrayRegion inbytes = subject.getBytes(); 43 | byte[] inarray = inbytes.getArray(); 44 | byte[] optimized = TailRecursionOptimizer.optimizeMethods(inarray, inbytes.getOffset(), inbytes.getLength()); 45 | return optimized; 46 | } 47 | 48 | @Override 49 | public InputStream openInputStreamImpl() throws IOException { 50 | return new UnsyncByteArrayInputStream(getOptimizedBytes()); 51 | } 52 | 53 | @Override 54 | public ByteSource openByteSourceImpl() throws IOException { 55 | return new UnsyncByteArrayInputStream(getOptimizedBytes()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/OptimizerTaskFactory.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build; 2 | 3 | import saker.build.file.path.SakerPath; 4 | import saker.build.file.provider.SakerPathFiles; 5 | import saker.build.runtime.execution.ExecutionContext; 6 | import saker.build.task.ParameterizableTask; 7 | import saker.build.task.TaskContext; 8 | import saker.build.task.utils.SimpleStructuredObjectTaskResult; 9 | import saker.build.task.utils.annot.SakerInput; 10 | import saker.build.task.utils.dependencies.EqualityTaskOutputChangeDetector; 11 | import saker.build.thirdparty.saker.util.StringUtils; 12 | import saker.build.thirdparty.saker.util.io.FileUtils; 13 | import saker.build.trace.BuildTrace; 14 | import saker.nest.scriptinfo.reflection.annot.NestInformation; 15 | import saker.nest.scriptinfo.reflection.annot.NestParameterInformation; 16 | import saker.nest.scriptinfo.reflection.annot.NestTaskInformation; 17 | import saker.nest.scriptinfo.reflection.annot.NestTypeUsage; 18 | import saker.nest.utils.FrontendTaskFactory; 19 | 20 | @NestTaskInformation(returnType = @NestTypeUsage(SakerPath.class)) 21 | @NestInformation("Performs tail recursion optimizations on the specified class directory.\n" 22 | + "The task will optimize all Java .class bytecode files for tail recursions and write the " 23 | + "output to another build directory location with the same hierarchy.\n" 24 | + "The Input for the task must be a class directory.\n" + "The output is the path to the output directory.") 25 | 26 | @NestParameterInformation(value = "Directory", 27 | aliases = { "", "Input" }, 28 | required = true, 29 | type = @NestTypeUsage(SakerPath.class), 30 | info = @NestInformation("The path to the input class directory.")) 31 | public class OptimizerTaskFactory extends FrontendTaskFactory { 32 | private static final long serialVersionUID = 1L; 33 | 34 | public static final String TASK_NAME = "sipka.jvm.tailrec.optimize"; 35 | 36 | @Override 37 | public ParameterizableTask createTask(ExecutionContext executioncontext) { 38 | return new ParameterizableTask() { 39 | 40 | @SakerInput(value = { "", "Directory", "Input" }, required = true) 41 | public SakerPath inputOption; 42 | 43 | @Override 44 | public Object run(TaskContext taskcontext) throws Exception { 45 | if (saker.build.meta.Versions.VERSION_FULL_COMPOUND >= 8_006) { 46 | BuildTrace.classifyTask(BuildTrace.CLASSIFICATION_FRONTEND); 47 | } 48 | SakerPath input = taskcontext.getTaskWorkingDirectoryPath().tryResolve(inputOption); 49 | 50 | SakerPath builddirpath = SakerPathFiles.requireBuildDirectoryPath(taskcontext); 51 | SakerPath outputrelpath; 52 | if (input.startsWith(builddirpath)) { 53 | outputrelpath = builddirpath.relativize(input); 54 | } else { 55 | outputrelpath = SakerPath.valueOf(StringUtils.toHexString(FileUtils.hashString(input.toString()))); 56 | } 57 | 58 | OptimizerWorkerTaskIdentifier workertaskid = new OptimizerWorkerTaskIdentifier(outputrelpath); 59 | taskcontext.startTask(workertaskid, new OptimizerWorkerTaskFactory(input), null); 60 | 61 | SimpleStructuredObjectTaskResult result = new SimpleStructuredObjectTaskResult(workertaskid); 62 | taskcontext.reportSelfTaskOutputChangeDetector(new EqualityTaskOutputChangeDetector(result)); 63 | return result; 64 | } 65 | }; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/OptimizerWorkerTaskFactory.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build; 2 | 3 | import java.io.Externalizable; 4 | import java.io.IOException; 5 | import java.io.ObjectInput; 6 | import java.io.ObjectOutput; 7 | import java.nio.file.NoSuchFileException; 8 | import java.nio.file.NotDirectoryException; 9 | import java.util.Map.Entry; 10 | import java.util.NavigableMap; 11 | import java.util.TreeMap; 12 | 13 | import saker.build.file.DelegateSakerFile; 14 | import saker.build.file.SakerDirectory; 15 | import saker.build.file.SakerFile; 16 | import saker.build.file.content.ContentDescriptor; 17 | import saker.build.file.path.SakerPath; 18 | import saker.build.file.provider.SakerPathFiles; 19 | import saker.build.runtime.execution.ExecutionContext; 20 | import saker.build.task.CommonTaskContentDescriptors; 21 | import saker.build.task.Task; 22 | import saker.build.task.TaskContext; 23 | import saker.build.task.TaskFactory; 24 | import saker.build.task.utils.dependencies.RecursiveFileCollectionStrategy; 25 | import saker.build.thirdparty.saker.util.io.SerialUtils; 26 | import saker.build.trace.BuildTrace; 27 | 28 | public class OptimizerWorkerTaskFactory implements TaskFactory, Task, Externalizable { 29 | private static final long serialVersionUID = 1L; 30 | 31 | private SakerPath input; 32 | 33 | /** 34 | * For {@link Externalizable}. 35 | */ 36 | public OptimizerWorkerTaskFactory() { 37 | } 38 | 39 | public OptimizerWorkerTaskFactory(SakerPath input) { 40 | this.input = input; 41 | } 42 | 43 | @Override 44 | public Task createTask(ExecutionContext executioncontext) { 45 | return this; 46 | } 47 | 48 | @Override 49 | public SakerPath run(TaskContext taskcontext) throws Exception { 50 | if (saker.build.meta.Versions.VERSION_FULL_COMPOUND >= 8_006) { 51 | BuildTrace.classifyTask(BuildTrace.CLASSIFICATION_WORKER); 52 | BuildTrace.setDisplayInformation("opt.tailrec", OptimizerTaskFactory.TASK_NAME + ":" + input.getFileName()); 53 | } 54 | OptimizerWorkerTaskIdentifier workertaskid = (OptimizerWorkerTaskIdentifier) taskcontext.getTaskId(); 55 | 56 | NavigableMap inputfiles = taskcontext.getTaskUtilities() 57 | .collectFilesReportInputFileAndAdditionDependency(null, RecursiveFileCollectionStrategy.create(input)); 58 | if (inputfiles.isEmpty()) { 59 | //check that it is a directory. if not, throw an appropriate exception 60 | SakerFile inputfile = taskcontext.getTaskUtilities().resolveAtPath(input); 61 | if (inputfile == null) { 62 | taskcontext.reportInputFileDependency(null, input, CommonTaskContentDescriptors.NOT_PRESENT); 63 | taskcontext.abortExecution(new NoSuchFileException(input.toString())); 64 | return null; 65 | } 66 | if (!(inputfile instanceof SakerDirectory)) { 67 | taskcontext.reportInputFileDependency(null, input, CommonTaskContentDescriptors.IS_NOT_DIRECTORY); 68 | taskcontext.abortExecution(new NotDirectoryException(input.toString())); 69 | return null; 70 | } 71 | } 72 | 73 | SakerDirectory outputbuilddir = taskcontext.getTaskUtilities().resolveDirectoryAtRelativePathCreate( 74 | taskcontext.getTaskBuildDirectory(), 75 | SakerPath.valueOf(OptimizerTaskFactory.TASK_NAME).append(workertaskid.getOutputRelativePath())); 76 | SakerPath outputdirpath = outputbuilddir.getSakerPath(); 77 | 78 | NavigableMap relativeinputfiles = SakerPathFiles.relativizeSubPath(inputfiles, input); 79 | NavigableMap outputcontents = new TreeMap<>(); 80 | 81 | //TODO make incremental (although the directory synchronization provides necessary incrementality) 82 | outputbuilddir.clear(); 83 | for (Entry entry : relativeinputfiles.entrySet()) { 84 | SakerFile f = entry.getValue(); 85 | if (f instanceof SakerDirectory) { 86 | //just resolve the path to have the directory created 87 | taskcontext.getTaskUtilities().resolveDirectoryAtRelativePathCreate(outputbuilddir, entry.getKey()); 88 | continue; 89 | } 90 | SakerDirectory outdir = taskcontext.getTaskUtilities().resolveDirectoryAtRelativePathCreate(outputbuilddir, 91 | entry.getKey().getParent()); 92 | SakerFile outfile; 93 | if (f.getName().endsWith(".class")) { 94 | outfile = new OptimizedSakerFile(f); 95 | } else { 96 | outfile = new DelegateSakerFile(f); 97 | } 98 | outdir.add(outfile); 99 | outputcontents.put(outputdirpath.resolve(entry.getKey()), outfile.getContentDescriptor()); 100 | } 101 | 102 | outputbuilddir.synchronize(); 103 | taskcontext.getTaskUtilities().reportOutputFileDependency(null, outputcontents); 104 | 105 | return outputdirpath; 106 | } 107 | 108 | @Override 109 | public void writeExternal(ObjectOutput out) throws IOException { 110 | out.writeObject(input); 111 | } 112 | 113 | @Override 114 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 115 | input = SerialUtils.readExternalObject(in); 116 | } 117 | 118 | @Override 119 | public int hashCode() { 120 | final int prime = 31; 121 | int result = 1; 122 | result = prime * result + ((input == null) ? 0 : input.hashCode()); 123 | return result; 124 | } 125 | 126 | @Override 127 | public boolean equals(Object obj) { 128 | if (this == obj) 129 | return true; 130 | if (obj == null) 131 | return false; 132 | if (getClass() != obj.getClass()) 133 | return false; 134 | OptimizerWorkerTaskFactory other = (OptimizerWorkerTaskFactory) obj; 135 | if (input == null) { 136 | if (other.input != null) 137 | return false; 138 | } else if (!input.equals(other.input)) 139 | return false; 140 | return true; 141 | } 142 | 143 | @Override 144 | public String toString() { 145 | return "OptimizerWorkerTaskFactory[input=" + input + "]"; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/OptimizerWorkerTaskIdentifier.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build; 2 | 3 | import java.io.Externalizable; 4 | import java.io.IOException; 5 | import java.io.ObjectInput; 6 | import java.io.ObjectOutput; 7 | 8 | import saker.build.file.path.SakerPath; 9 | import saker.build.task.identifier.TaskIdentifier; 10 | import saker.build.thirdparty.saker.util.io.SerialUtils; 11 | 12 | public class OptimizerWorkerTaskIdentifier implements TaskIdentifier, Externalizable { 13 | private static final long serialVersionUID = 1L; 14 | 15 | private SakerPath outputRelativePath; 16 | 17 | /** 18 | * For {@link Externalizable}. 19 | */ 20 | public OptimizerWorkerTaskIdentifier() { 21 | } 22 | 23 | public OptimizerWorkerTaskIdentifier(SakerPath outputRelativePath) { 24 | this.outputRelativePath = outputRelativePath; 25 | } 26 | 27 | public SakerPath getOutputRelativePath() { 28 | return outputRelativePath; 29 | } 30 | 31 | @Override 32 | public void writeExternal(ObjectOutput out) throws IOException { 33 | out.writeObject(outputRelativePath); 34 | } 35 | 36 | @Override 37 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 38 | outputRelativePath = SerialUtils.readExternalObject(in); 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | final int prime = 31; 44 | int result = 1; 45 | result = prime * result + ((outputRelativePath == null) ? 0 : outputRelativePath.hashCode()); 46 | return result; 47 | } 48 | 49 | @Override 50 | public boolean equals(Object obj) { 51 | if (this == obj) 52 | return true; 53 | if (obj == null) 54 | return false; 55 | if (getClass() != obj.getClass()) 56 | return false; 57 | OptimizerWorkerTaskIdentifier other = (OptimizerWorkerTaskIdentifier) obj; 58 | if (outputRelativePath == null) { 59 | if (other.outputRelativePath != null) 60 | return false; 61 | } else if (!outputRelativePath.equals(other.outputRelativePath)) 62 | return false; 63 | return true; 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return getClass().getSimpleName() + "[outputRelativePath=" + outputRelativePath + "]"; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/zip/OptimizerZipResourceTransformerFactory.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build.zip; 2 | 3 | import java.io.Externalizable; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.ObjectInput; 7 | import java.io.ObjectOutput; 8 | import java.io.OutputStream; 9 | 10 | import saker.build.file.path.SakerPath; 11 | import saker.build.thirdparty.saker.util.ObjectUtils; 12 | import saker.build.thirdparty.saker.util.io.ByteArrayRegion; 13 | import saker.build.thirdparty.saker.util.io.StreamUtils; 14 | import saker.zip.api.create.ZipResourceTransformationContext; 15 | import saker.zip.api.create.ZipResourceTransformer; 16 | import saker.zip.api.create.ZipResourceTransformerFactory; 17 | import sipka.jvm.tailrec.TailRecursionOptimizer; 18 | 19 | public class OptimizerZipResourceTransformerFactory implements ZipResourceTransformerFactory, Externalizable { 20 | private static final long serialVersionUID = 1L; 21 | 22 | public static final OptimizerZipResourceTransformerFactory INSTANCE = new OptimizerZipResourceTransformerFactory(); 23 | 24 | /** 25 | * For {@link Externalizable}. 26 | */ 27 | public OptimizerZipResourceTransformerFactory() { 28 | } 29 | 30 | @Override 31 | public ZipResourceTransformer createTransformer() { 32 | return new ZipResourceTransformer() { 33 | @Override 34 | public boolean process(ZipResourceTransformationContext context, SakerPath resourcepath, 35 | InputStream resourceinput) throws IOException { 36 | if (!resourcepath.getFileName().endsWith(".class")) { 37 | return false; 38 | } 39 | ByteArrayRegion contents = StreamUtils.readStreamFully(resourceinput); 40 | byte[] array = contents.copyOptionally(); 41 | byte[] optimized = TailRecursionOptimizer.optimizeMethods(array); 42 | if (array == optimized) { 43 | //not optimized 44 | return false; 45 | } 46 | try (OutputStream out = context.appendFile(resourcepath, null)) { 47 | out.write(optimized); 48 | } 49 | return true; 50 | } 51 | }; 52 | } 53 | 54 | @Override 55 | public void writeExternal(ObjectOutput out) throws IOException { 56 | } 57 | 58 | @Override 59 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return getClass().getName().hashCode(); 65 | } 66 | 67 | @Override 68 | public boolean equals(Object obj) { 69 | return ObjectUtils.isSameClass(this, obj); 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return getClass().getSimpleName() + "[]"; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/saker/build/zip/OptimizerZipTransformerTaskFactory.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.saker.build.zip; 2 | 3 | import java.io.Externalizable; 4 | import java.io.IOException; 5 | import java.io.ObjectInput; 6 | import java.io.ObjectOutput; 7 | import java.util.NavigableSet; 8 | import java.util.Set; 9 | 10 | import saker.build.runtime.execution.ExecutionContext; 11 | import saker.build.task.Task; 12 | import saker.build.task.TaskContext; 13 | import saker.build.task.TaskFactory; 14 | import saker.build.thirdparty.saker.util.ImmutableUtils; 15 | import saker.build.thirdparty.saker.util.ObjectUtils; 16 | import saker.build.trace.BuildTrace; 17 | import saker.nest.scriptinfo.reflection.annot.NestInformation; 18 | 19 | @NestInformation( 20 | value = "Creates a ZIP resource transformer that performs tail recursion optimization on Java class files.\n" 21 | + "The output of this task can be used as the Transformer inputs to ZIP archive creation tasks. " 22 | + "(saker.zip.create and related tasks.)") 23 | public class OptimizerZipTransformerTaskFactory 24 | implements TaskFactory, Externalizable { 25 | private static final long serialVersionUID = 1L; 26 | 27 | private static final NavigableSet CAPABILITIES = ImmutableUtils 28 | .singletonNavigableSet(CAPABILITY_SHORT_TASK); 29 | 30 | public static final String TASK_NAME = "sipka.jvm.tailrec.zip.transformer"; 31 | 32 | @Override 33 | public Task createTask(ExecutionContext executioncontext) { 34 | return new Task() { 35 | @Override 36 | public OptimizerZipResourceTransformerFactory run(TaskContext taskcontext) throws Exception { 37 | if (saker.build.meta.Versions.VERSION_FULL_COMPOUND >= 8_006) { 38 | BuildTrace.classifyTask(BuildTrace.CLASSIFICATION_CONFIGURATION); 39 | } 40 | return OptimizerZipResourceTransformerFactory.INSTANCE; 41 | } 42 | }; 43 | } 44 | 45 | @Override 46 | public Set getCapabilities() { 47 | return CAPABILITIES; 48 | } 49 | 50 | @Override 51 | public void writeExternal(ObjectOutput out) throws IOException { 52 | } 53 | 54 | @Override 55 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 56 | } 57 | 58 | @Override 59 | public int hashCode() { 60 | return getClass().getName().hashCode(); 61 | } 62 | 63 | @Override 64 | public boolean equals(Object obj) { 65 | return ObjectUtils.isSameClass(this, obj); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return getClass().getSimpleName() + "[]"; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/AnnotationVisitor.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * A visitor to visit a Java annotation. The methods of this class must be called in the following 32 | * order: ( {@code visit} | {@code visitEnum} | {@code visitAnnotation} | {@code visitArray} )* 33 | * {@code visitEnd}. 34 | * 35 | * @author Eric Bruneton 36 | * @author Eugene Kuleshov 37 | */ 38 | public abstract class AnnotationVisitor { 39 | 40 | /** 41 | * The ASM API version implemented by this visitor. The value of this field must be one of {@link 42 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. 43 | */ 44 | protected final int api; 45 | 46 | /** 47 | * The annotation visitor to which this visitor must delegate method calls. May be {@literal 48 | * null}. 49 | */ 50 | protected AnnotationVisitor av; 51 | 52 | /** 53 | * Constructs a new {@link AnnotationVisitor}. 54 | * 55 | * @param api the ASM API version implemented by this visitor. Must be one of {@link 56 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. 57 | */ 58 | public AnnotationVisitor(final int api) { 59 | this(api, null); 60 | } 61 | 62 | /** 63 | * Constructs a new {@link AnnotationVisitor}. 64 | * 65 | * @param api the ASM API version implemented by this visitor. Must be one of {@link 66 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. 67 | * @param annotationVisitor the annotation visitor to which this visitor must delegate method 68 | * calls. May be {@literal null}. 69 | */ 70 | public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { 71 | if (api != Opcodes.ASM8 72 | && api != Opcodes.ASM7 73 | && api != Opcodes.ASM6 74 | && api != Opcodes.ASM5 75 | && api != Opcodes.ASM4 76 | && api != Opcodes.ASM9_EXPERIMENTAL) { 77 | throw new IllegalArgumentException("Unsupported api " + api); 78 | } 79 | if (api == Opcodes.ASM9_EXPERIMENTAL) { 80 | Constants.checkAsmExperimental(this); 81 | } 82 | this.api = api; 83 | this.av = annotationVisitor; 84 | } 85 | 86 | /** 87 | * Visits a primitive value of the annotation. 88 | * 89 | * @param name the value name. 90 | * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link 91 | * Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double}, 92 | * {@link String} or {@link Type} of {@link Type#OBJECT} or {@link Type#ARRAY} sort. This 93 | * value can also be an array of byte, boolean, short, char, int, long, float or double values 94 | * (this is equivalent to using {@link #visitArray} and visiting each array element in turn, 95 | * but is more convenient). 96 | */ 97 | public void visit(final String name, final Object value) { 98 | if (av != null) { 99 | av.visit(name, value); 100 | } 101 | } 102 | 103 | /** 104 | * Visits an enumeration value of the annotation. 105 | * 106 | * @param name the value name. 107 | * @param descriptor the class descriptor of the enumeration class. 108 | * @param value the actual enumeration value. 109 | */ 110 | public void visitEnum(final String name, final String descriptor, final String value) { 111 | if (av != null) { 112 | av.visitEnum(name, descriptor, value); 113 | } 114 | } 115 | 116 | /** 117 | * Visits a nested annotation value of the annotation. 118 | * 119 | * @param name the value name. 120 | * @param descriptor the class descriptor of the nested annotation class. 121 | * @return a visitor to visit the actual nested annotation value, or {@literal null} if this 122 | * visitor is not interested in visiting this nested annotation. The nested annotation 123 | * value must be fully visited before calling other methods on this annotation visitor. 124 | */ 125 | public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { 126 | if (av != null) { 127 | return av.visitAnnotation(name, descriptor); 128 | } 129 | return null; 130 | } 131 | 132 | /** 133 | * Visits an array value of the annotation. Note that arrays of primitive types (such as byte, 134 | * boolean, short, char, int, long, float or double) can be passed as value to {@link #visit 135 | * visit}. This is what {@link ClassReader} does. 136 | * 137 | * @param name the value name. 138 | * @return a visitor to visit the actual array value elements, or {@literal null} if this visitor 139 | * is not interested in visiting these values. The 'name' parameters passed to the methods of 140 | * this visitor are ignored. All the array values must be visited before calling other 141 | * methods on this annotation visitor. 142 | */ 143 | public AnnotationVisitor visitArray(final String name) { 144 | if (av != null) { 145 | return av.visitArray(name); 146 | } 147 | return null; 148 | } 149 | 150 | /** Visits the end of the annotation. */ 151 | public void visitEnd() { 152 | if (av != null) { 153 | av.visitEnd(); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/ClassTooLargeException.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * Exception thrown when the constant pool of a class produced by a {@link ClassWriter} is too 32 | * large. 33 | * 34 | * @author Jason Zaugg 35 | */ 36 | public final class ClassTooLargeException extends IndexOutOfBoundsException { 37 | private static final long serialVersionUID = 160715609518896765L; 38 | 39 | private final String className; 40 | private final int constantPoolCount; 41 | 42 | /** 43 | * Constructs a new {@link ClassTooLargeException}. 44 | * 45 | * @param className the internal name of the class. 46 | * @param constantPoolCount the number of constant pool items of the class. 47 | */ 48 | public ClassTooLargeException(final String className, final int constantPoolCount) { 49 | super("Class too large: " + className); 50 | this.className = className; 51 | this.constantPoolCount = constantPoolCount; 52 | } 53 | 54 | /** 55 | * Returns the internal name of the class. 56 | * 57 | * @return the internal name of the class. 58 | */ 59 | public String getClassName() { 60 | return className; 61 | } 62 | 63 | /** 64 | * Returns the number of constant pool items of the class. 65 | * 66 | * @return the number of constant pool items of the class. 67 | */ 68 | public int getConstantPoolCount() { 69 | return constantPoolCount; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/Context.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 30 | 31 | /** 32 | * Information about a class being parsed in a {@link ClassReader}. 33 | * 34 | * @author Eric Bruneton 35 | */ 36 | final class Context { 37 | 38 | /** The prototypes of the attributes that must be parsed in this class. */ 39 | Attribute[] attributePrototypes; 40 | 41 | /** 42 | * The options used to parse this class. One or more of {@link ClassReader#SKIP_CODE}, {@link 43 | * ClassReader#SKIP_DEBUG}, {@link ClassReader#SKIP_FRAMES}, {@link ClassReader#EXPAND_FRAMES} or 44 | * {@link ClassReader#EXPAND_ASM_INSNS}. 45 | */ 46 | int parsingOptions; 47 | 48 | /** The buffer used to read strings in the constant pool. */ 49 | char[] charBuffer; 50 | 51 | // Information about the current method, i.e. the one read in the current (or latest) call 52 | // to {@link ClassReader#readMethod()}. 53 | 54 | /** The access flags of the current method. */ 55 | int currentMethodAccessFlags; 56 | 57 | /** The name of the current method. */ 58 | String currentMethodName; 59 | 60 | /** The descriptor of the current method. */ 61 | String currentMethodDescriptor; 62 | 63 | /** 64 | * The labels of the current method, indexed by bytecode offset (only bytecode offsets for which a 65 | * label is needed have a non null associated Label). 66 | */ 67 | Label[] currentMethodLabels; 68 | 69 | // Information about the current type annotation target, i.e. the one read in the current 70 | // (or latest) call to {@link ClassReader#readAnnotationTarget()}. 71 | 72 | /** 73 | * The target_type and target_info of the current type annotation target, encoded as described in 74 | * {@link TypeReference}. 75 | */ 76 | int currentTypeAnnotationTarget; 77 | 78 | /** The target_path of the current type annotation target. */ 79 | TypePath currentTypeAnnotationTargetPath; 80 | 81 | /** The start of each local variable range in the current local variable annotation. */ 82 | Label[] currentLocalVariableAnnotationRangeStarts; 83 | 84 | /** The end of each local variable range in the current local variable annotation. */ 85 | Label[] currentLocalVariableAnnotationRangeEnds; 86 | 87 | /** 88 | * The local variable index of each local variable range in the current local variable annotation. 89 | */ 90 | int[] currentLocalVariableAnnotationRangeIndices; 91 | 92 | // Information about the current stack map frame, i.e. the one read in the current (or latest) 93 | // call to {@link ClassReader#readFrame()}. 94 | 95 | /** The bytecode offset of the current stack map frame. */ 96 | int currentFrameOffset; 97 | 98 | /** 99 | * The type of the current stack map frame. One of {@link Opcodes#F_FULL}, {@link 100 | * Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or {@link Opcodes#F_SAME1}. 101 | */ 102 | int currentFrameType; 103 | 104 | /** 105 | * The number of local variable types in the current stack map frame. Each type is represented 106 | * with a single array element (even long and double). 107 | */ 108 | int currentFrameLocalCount; 109 | 110 | /** 111 | * The delta number of local variable types in the current stack map frame (each type is 112 | * represented with a single array element - even long and double). This is the number of local 113 | * variable types in this frame, minus the number of local variable types in the previous frame. 114 | */ 115 | int currentFrameLocalCountDelta; 116 | 117 | /** 118 | * The types of the local variables in the current stack map frame. Each type is represented with 119 | * a single array element (even long and double), using the format described in {@link 120 | * MethodVisitor#visitFrame}. Depending on {@link #currentFrameType}, this contains the types of 121 | * all the local variables, or only those of the additional ones (compared to the previous frame). 122 | */ 123 | Object[] currentFrameLocalTypes; 124 | 125 | /** 126 | * The number stack element types in the current stack map frame. Each type is represented with a 127 | * single array element (even long and double). 128 | */ 129 | int currentFrameStackCount; 130 | 131 | /** 132 | * The types of the stack elements in the current stack map frame. Each type is represented with a 133 | * single array element (even long and double), using the format described in {@link 134 | * MethodVisitor#visitFrame}. 135 | */ 136 | Object[] currentFrameStackTypes; 137 | } 138 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/CurrentFrame.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 30 | 31 | /** 32 | * Information about the input stack map frame at the "current" instruction of a method. This is 33 | * implemented as a Frame subclass for a "basic block" containing only one instruction. 34 | * 35 | * @author Eric Bruneton 36 | */ 37 | final class CurrentFrame extends Frame { 38 | 39 | CurrentFrame(final Label owner) { 40 | super(owner); 41 | } 42 | 43 | /** 44 | * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the 45 | * instruction just after the given one. It is assumed that the value of this object when this 46 | * method is called is the stack map frame status just before the given instruction is executed. 47 | */ 48 | @Override 49 | void execute( 50 | final int opcode, final int arg, final Symbol symbolArg, final SymbolTable symbolTable) { 51 | super.execute(opcode, arg, symbolArg, symbolTable); 52 | Frame successor = new Frame(null); 53 | merge(symbolTable, successor, 0); 54 | copyFrom(successor); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/Edge.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * An edge in the control flow graph of a method. Each node of this graph is a basic block, 32 | * represented with the Label corresponding to its first instruction. Each edge goes from one node 33 | * to another, i.e. from one basic block to another (called the predecessor and successor blocks, 34 | * respectively). An edge corresponds either to a jump or ret instruction or to an exception 35 | * handler. 36 | * 37 | * @see Label 38 | * @author Eric Bruneton 39 | */ 40 | final class Edge { 41 | 42 | /** 43 | * A control flow graph edge corresponding to a jump or ret instruction. Only used with {@link 44 | * ClassWriter#COMPUTE_FRAMES}. 45 | */ 46 | static final int JUMP = 0; 47 | 48 | /** 49 | * A control flow graph edge corresponding to an exception handler. Only used with {@link 50 | * ClassWriter#COMPUTE_MAXS}. 51 | */ 52 | static final int EXCEPTION = 0x7FFFFFFF; 53 | 54 | /** 55 | * Information about this control flow graph edge. 56 | * 57 | *
    58 | *
  • If {@link ClassWriter#COMPUTE_MAXS} is used, this field contains either a stack size 59 | * delta (for an edge corresponding to a jump instruction), or the value EXCEPTION (for an 60 | * edge corresponding to an exception handler). The stack size delta is the stack size just 61 | * after the jump instruction, minus the stack size at the beginning of the predecessor 62 | * basic block, i.e. the one containing the jump instruction. 63 | *
  • If {@link ClassWriter#COMPUTE_FRAMES} is used, this field contains either the value JUMP 64 | * (for an edge corresponding to a jump instruction), or the index, in the {@link 65 | * ClassWriter} type table, of the exception type that is handled (for an edge corresponding 66 | * to an exception handler). 67 | *
68 | */ 69 | final int info; 70 | 71 | /** The successor block of this control flow graph edge. */ 72 | final Label successor; 73 | 74 | /** 75 | * The next edge in the list of outgoing edges of a basic block. See {@link Label#outgoingEdges}. 76 | */ 77 | Edge nextEdge; 78 | 79 | /** 80 | * Constructs a new Edge. 81 | * 82 | * @param info see {@link #info}. 83 | * @param successor see {@link #successor}. 84 | * @param nextEdge see {@link #nextEdge}. 85 | */ 86 | Edge(final int info, final Label successor, final Edge nextEdge) { 87 | this.info = info; 88 | this.successor = successor; 89 | this.nextEdge = nextEdge; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/FieldVisitor.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * A visitor to visit a Java field. The methods of this class must be called in the following order: 32 | * ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code 33 | * visitEnd}. 34 | * 35 | * @author Eric Bruneton 36 | */ 37 | public abstract class FieldVisitor { 38 | 39 | /** 40 | * The ASM API version implemented by this visitor. The value of this field must be one of {@link 41 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link 42 | * Opcodes#ASM8}. 43 | */ 44 | protected final int api; 45 | 46 | /** The field visitor to which this visitor must delegate method calls. May be {@literal null}. */ 47 | protected FieldVisitor fv; 48 | 49 | /** 50 | * Constructs a new {@link FieldVisitor}. 51 | * 52 | * @param api the ASM API version implemented by this visitor. Must be one of {@link 53 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link 54 | * Opcodes#ASM8}. 55 | */ 56 | public FieldVisitor(final int api) { 57 | this(api, null); 58 | } 59 | 60 | /** 61 | * Constructs a new {@link FieldVisitor}. 62 | * 63 | * @param api the ASM API version implemented by this visitor. Must be one of {@link 64 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link 65 | * Opcodes#ASM8}. 66 | * @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be 67 | * null. 68 | */ 69 | public FieldVisitor(final int api, final FieldVisitor fieldVisitor) { 70 | if (api != Opcodes.ASM8 71 | && api != Opcodes.ASM7 72 | && api != Opcodes.ASM6 73 | && api != Opcodes.ASM5 74 | && api != Opcodes.ASM4 75 | && api != Opcodes.ASM9_EXPERIMENTAL) { 76 | throw new IllegalArgumentException("Unsupported api " + api); 77 | } 78 | if (api == Opcodes.ASM9_EXPERIMENTAL) { 79 | Constants.checkAsmExperimental(this); 80 | } 81 | this.api = api; 82 | this.fv = fieldVisitor; 83 | } 84 | 85 | /** 86 | * Visits an annotation of the field. 87 | * 88 | * @param descriptor the class descriptor of the annotation class. 89 | * @param visible {@literal true} if the annotation is visible at runtime. 90 | * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not 91 | * interested in visiting this annotation. 92 | */ 93 | public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { 94 | if (fv != null) { 95 | return fv.visitAnnotation(descriptor, visible); 96 | } 97 | return null; 98 | } 99 | 100 | /** 101 | * Visits an annotation on the type of the field. 102 | * 103 | * @param typeRef a reference to the annotated type. The sort of this type reference must be 104 | * {@link TypeReference#FIELD}. See {@link TypeReference}. 105 | * @param typePath the path to the annotated type argument, wildcard bound, array element type, or 106 | * static inner type within 'typeRef'. May be {@literal null} if the annotation targets 107 | * 'typeRef' as a whole. 108 | * @param descriptor the class descriptor of the annotation class. 109 | * @param visible {@literal true} if the annotation is visible at runtime. 110 | * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not 111 | * interested in visiting this annotation. 112 | */ 113 | public AnnotationVisitor visitTypeAnnotation( 114 | final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { 115 | if (api < Opcodes.ASM5) { 116 | throw new UnsupportedOperationException("This feature requires ASM5"); 117 | } 118 | if (fv != null) { 119 | return fv.visitTypeAnnotation(typeRef, typePath, descriptor, visible); 120 | } 121 | return null; 122 | } 123 | 124 | /** 125 | * Visits a non standard attribute of the field. 126 | * 127 | * @param attribute an attribute. 128 | */ 129 | public void visitAttribute(final Attribute attribute) { 130 | if (fv != null) { 131 | fv.visitAttribute(attribute); 132 | } 133 | } 134 | 135 | /** 136 | * Visits the end of the field. This method, which is the last one to be called, is used to inform 137 | * the visitor that all the annotations and attributes of the field have been visited. 138 | */ 139 | public void visitEnd() { 140 | if (fv != null) { 141 | fv.visitEnd(); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/MethodTooLargeException.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * Exception thrown when the Code attribute of a method produced by a {@link ClassWriter} is too 32 | * large. 33 | * 34 | * @author Jason Zaugg 35 | */ 36 | public final class MethodTooLargeException extends IndexOutOfBoundsException { 37 | private static final long serialVersionUID = 6807380416709738314L; 38 | 39 | private final String className; 40 | private final String methodName; 41 | private final String descriptor; 42 | private final int codeSize; 43 | 44 | /** 45 | * Constructs a new {@link MethodTooLargeException}. 46 | * 47 | * @param className the internal name of the owner class. 48 | * @param methodName the name of the method. 49 | * @param descriptor the descriptor of the method. 50 | * @param codeSize the size of the method's Code attribute, in bytes. 51 | */ 52 | public MethodTooLargeException( 53 | final String className, 54 | final String methodName, 55 | final String descriptor, 56 | final int codeSize) { 57 | super("Method too large: " + className + "." + methodName + " " + descriptor); 58 | this.className = className; 59 | this.methodName = methodName; 60 | this.descriptor = descriptor; 61 | this.codeSize = codeSize; 62 | } 63 | 64 | /** 65 | * Returns the internal name of the owner class. 66 | * 67 | * @return the internal name of the owner class. 68 | */ 69 | public String getClassName() { 70 | return className; 71 | } 72 | 73 | /** 74 | * Returns the name of the method. 75 | * 76 | * @return the name of the method. 77 | */ 78 | public String getMethodName() { 79 | return methodName; 80 | } 81 | 82 | /** 83 | * Returns the descriptor of the method. 84 | * 85 | * @return the descriptor of the method. 86 | */ 87 | public String getDescriptor() { 88 | return descriptor; 89 | } 90 | 91 | /** 92 | * Returns the size of the method's Code attribute, in bytes. 93 | * 94 | * @return the size of the method's Code attribute, in bytes. 95 | */ 96 | public int getCodeSize() { 97 | return codeSize; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/RecordComponentVisitor.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm; 29 | 30 | /** 31 | * A visitor to visit a record component. The methods of this class must be called in the following 32 | * order: ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code visitAttribute} )* {@code 33 | * visitEnd}. 34 | * 35 | * @author Remi Forax 36 | * @author Eric Bruneton 37 | */ 38 | public abstract class RecordComponentVisitor { 39 | /** 40 | * The ASM API version implemented by this visitor. The value of this field must be {@link 41 | * Opcodes#ASM8}. 42 | */ 43 | protected final int api; 44 | 45 | /** 46 | * The record visitor to which this visitor must delegate method calls. May be {@literal null}. 47 | */ 48 | /*package-private*/ RecordComponentVisitor delegate; 49 | 50 | /** 51 | * Constructs a new {@link RecordComponentVisitor}. 52 | * 53 | * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}. 54 | */ 55 | public RecordComponentVisitor(final int api) { 56 | this(api, null); 57 | } 58 | 59 | /** 60 | * Constructs a new {@link RecordComponentVisitor}. 61 | * 62 | * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM8}. 63 | * @param recordComponentVisitor the record component visitor to which this visitor must delegate 64 | * method calls. May be null. 65 | */ 66 | public RecordComponentVisitor( 67 | final int api, final RecordComponentVisitor recordComponentVisitor) { 68 | if (api != Opcodes.ASM8 69 | && api != Opcodes.ASM7 70 | && api != Opcodes.ASM6 71 | && api != Opcodes.ASM5 72 | && api != Opcodes.ASM4 73 | && api != Opcodes.ASM9_EXPERIMENTAL) { 74 | throw new IllegalArgumentException("Unsupported api " + api); 75 | } 76 | if (api == Opcodes.ASM9_EXPERIMENTAL) { 77 | Constants.checkAsmExperimental(this); 78 | } 79 | this.api = api; 80 | this.delegate = recordComponentVisitor; 81 | } 82 | 83 | /** 84 | * The record visitor to which this visitor must delegate method calls. May be {@literal null}. 85 | * 86 | * @return the record visitor to which this visitor must delegate method calls or {@literal null}. 87 | */ 88 | public RecordComponentVisitor getDelegate() { 89 | return delegate; 90 | } 91 | 92 | /** 93 | * Visits an annotation of the record component. 94 | * 95 | * @param descriptor the class descriptor of the annotation class. 96 | * @param visible {@literal true} if the annotation is visible at runtime. 97 | * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not 98 | * interested in visiting this annotation. 99 | */ 100 | public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { 101 | if (delegate != null) { 102 | return delegate.visitAnnotation(descriptor, visible); 103 | } 104 | return null; 105 | } 106 | 107 | /** 108 | * Visits an annotation on a type in the record component signature. 109 | * 110 | * @param typeRef a reference to the annotated type. The sort of this type reference must be 111 | * {@link TypeReference#CLASS_TYPE_PARAMETER}, {@link 112 | * TypeReference#CLASS_TYPE_PARAMETER_BOUND} or {@link TypeReference#CLASS_EXTENDS}. See 113 | * {@link TypeReference}. 114 | * @param typePath the path to the annotated type argument, wildcard bound, array element type, or 115 | * static inner type within 'typeRef'. May be {@literal null} if the annotation targets 116 | * 'typeRef' as a whole. 117 | * @param descriptor the class descriptor of the annotation class. 118 | * @param visible {@literal true} if the annotation is visible at runtime. 119 | * @return a visitor to visit the annotation values, or {@literal null} if this visitor is not 120 | * interested in visiting this annotation. 121 | */ 122 | public AnnotationVisitor visitTypeAnnotation( 123 | final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { 124 | if (delegate != null) { 125 | return delegate.visitTypeAnnotation(typeRef, typePath, descriptor, visible); 126 | } 127 | return null; 128 | } 129 | 130 | /** 131 | * Visits a non standard attribute of the record component. 132 | * 133 | * @param attribute an attribute. 134 | */ 135 | public void visitAttribute(final Attribute attribute) { 136 | if (delegate != null) { 137 | delegate.visitAttribute(attribute); 138 | } 139 | } 140 | 141 | /** 142 | * Visits the end of the record component. This method, which is the last one to be called, is 143 | * used to inform the visitor that everything have been visited. 144 | */ 145 | public void visitEnd() { 146 | if (delegate != null) { 147 | delegate.visitEnd(); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | 33 | Package org.objectweb.asm 34 | 35 | 36 | Provides a small and fast bytecode manipulation framework. 37 | 38 |

39 | The ASM framework is organized 40 | around the {@link org.objectweb.asm.ClassVisitor ClassVisitor}, 41 | {@link org.objectweb.asm.FieldVisitor FieldVisitor}, 42 | {@link org.objectweb.asm.MethodVisitor MethodVisitor} and 43 | {@link org.objectweb.asm.AnnotationVisitor AnnotationVisitor} abstract classes, 44 | which allow one to visit the fields, methods and annotations of a class, 45 | including the bytecode instructions of each method. 46 | 47 |

48 | In addition to these main abstract classes, ASM provides a {@link 49 | org.objectweb.asm.ClassReader ClassReader} class, that can parse an 50 | existing class and make a given visitor visit it. ASM also provides 51 | a {@link org.objectweb.asm.ClassWriter ClassWriter} class, which is 52 | a visitor that generates Java class files. 53 | 54 |

55 | In order to generate a class from scratch, only the {@link 56 | org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed, 57 | in order to generate a class, one must just call its visitXxx 58 | methods with the appropriate arguments to generate the desired fields 59 | and methods. 60 | 61 |

62 | In order to modify existing classes, one must use a {@link 63 | org.objectweb.asm.ClassReader ClassReader} class to analyze 64 | the original class, a class modifier, and a {@link org.objectweb.asm.ClassWriter 65 | ClassWriter} to construct the modified class. The class modifier 66 | is just a {@link org.objectweb.asm.ClassVisitor ClassVisitor} 67 | that delegates most of the work to another {@link org.objectweb.asm.ClassVisitor 68 | ClassVisitor}, but that sometimes changes some parameter values, 69 | or call additional methods, in order to implement the desired 70 | modification process. In order to make it easier to implement such 71 | class modifiers, the {@link org.objectweb.asm.ClassVisitor 72 | ClassVisitor} and {@link org.objectweb.asm.MethodVisitor MethodVisitor} 73 | classes delegate by default all the method calls they receive to an 74 | optional visitor. 75 | 76 | @since ASM 1.3 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/signature/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | 33 | Package org.objectweb.asm.signature 34 | 35 | 36 | Provides support for type signatures. 37 | 38 | @since ASM 2.0 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/FieldInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a field instruction. A field instruction is an instruction that loads or 36 | * stores the value of a field of an object. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class FieldInsnNode extends AbstractInsnNode { 41 | 42 | /** 43 | * The internal name of the field's owner class (see {@link 44 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName}). 45 | */ 46 | public String owner; 47 | 48 | /** The field's name. */ 49 | public String name; 50 | 51 | /** The field's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). */ 52 | public String desc; 53 | 54 | /** 55 | * Constructs a new {@link FieldInsnNode}. 56 | * 57 | * @param opcode the opcode of the type instruction to be constructed. This opcode must be 58 | * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. 59 | * @param owner the internal name of the field's owner class (see {@link 60 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName}). 61 | * @param name the field's name. 62 | * @param descriptor the field's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 63 | */ 64 | public FieldInsnNode( 65 | final int opcode, final String owner, final String name, final String descriptor) { 66 | super(opcode); 67 | this.owner = owner; 68 | this.name = name; 69 | this.desc = descriptor; 70 | } 71 | 72 | /** 73 | * Sets the opcode of this instruction. 74 | * 75 | * @param opcode the new instruction opcode. This opcode must be GETSTATIC, PUTSTATIC, GETFIELD or 76 | * PUTFIELD. 77 | */ 78 | public void setOpcode(final int opcode) { 79 | this.opcode = opcode; 80 | } 81 | 82 | @Override 83 | public int getType() { 84 | return FIELD_INSN; 85 | } 86 | 87 | @Override 88 | public void accept(final MethodVisitor methodVisitor) { 89 | methodVisitor.visitFieldInsn(opcode, owner, name, desc); 90 | acceptAnnotations(methodVisitor); 91 | } 92 | 93 | @Override 94 | public AbstractInsnNode clone(final Map clonedLabels) { 95 | return new FieldInsnNode(opcode, owner, name, desc).cloneAnnotations(this); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/IincInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 34 | 35 | /** 36 | * A node that represents an IINC instruction. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class IincInsnNode extends AbstractInsnNode { 41 | 42 | /** Index of the local variable to be incremented. */ 43 | public int var; 44 | 45 | /** Amount to increment the local variable by. */ 46 | public int incr; 47 | 48 | /** 49 | * Constructs a new {@link IincInsnNode}. 50 | * 51 | * @param var index of the local variable to be incremented. 52 | * @param incr increment amount to increment the local variable by. 53 | */ 54 | public IincInsnNode(final int var, final int incr) { 55 | super(Opcodes.IINC); 56 | this.var = var; 57 | this.incr = incr; 58 | } 59 | 60 | @Override 61 | public int getType() { 62 | return IINC_INSN; 63 | } 64 | 65 | @Override 66 | public void accept(final MethodVisitor methodVisitor) { 67 | methodVisitor.visitIincInsn(var, incr); 68 | acceptAnnotations(methodVisitor); 69 | } 70 | 71 | @Override 72 | public AbstractInsnNode clone(final Map clonedLabels) { 73 | return new IincInsnNode(var, incr).cloneAnnotations(this); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/InnerClassNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.ClassVisitor; 31 | 32 | /** 33 | * A node that represents an inner class. 34 | * 35 | * @author Eric Bruneton 36 | */ 37 | public class InnerClassNode { 38 | 39 | /** The internal name of an inner class (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). */ 40 | public String name; 41 | 42 | /** 43 | * The internal name of the class to which the inner class belongs (see {@link 44 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 45 | */ 46 | public String outerName; 47 | 48 | /** 49 | * The (simple) name of the inner class inside its enclosing class. May be {@literal null} for 50 | * anonymous inner classes. 51 | */ 52 | public String innerName; 53 | 54 | /** The access flags of the inner class as originally declared in the enclosing class. */ 55 | public int access; 56 | 57 | /** 58 | * Constructs a new {@link InnerClassNode}. 59 | * 60 | * @param name the internal name of an inner class (see {@link 61 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). 62 | * @param outerName the internal name of the class to which the inner class belongs (see {@link 63 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). May be {@literal null}. 64 | * @param innerName the (simple) name of the inner class inside its enclosing class. May be 65 | * {@literal null} for anonymous inner classes. 66 | * @param access the access flags of the inner class as originally declared in the enclosing 67 | * class. 68 | */ 69 | public InnerClassNode( 70 | final String name, final String outerName, final String innerName, final int access) { 71 | this.name = name; 72 | this.outerName = outerName; 73 | this.innerName = innerName; 74 | this.access = access; 75 | } 76 | 77 | /** 78 | * Makes the given class visitor visit this inner class. 79 | * 80 | * @param classVisitor a class visitor. 81 | */ 82 | public void accept(final ClassVisitor classVisitor) { 83 | classVisitor.visitInnerClass(name, outerName, innerName, access); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/InsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a zero operand instruction. 36 | * 37 | * @author Eric Bruneton 38 | */ 39 | public class InsnNode extends AbstractInsnNode { 40 | 41 | /** 42 | * Constructs a new {@link InsnNode}. 43 | * 44 | * @param opcode the opcode of the instruction to be constructed. This opcode must be NOP, 45 | * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, 46 | * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, 47 | * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE, 48 | * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, 49 | * SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, 50 | * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR, 51 | * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, 52 | * D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, 53 | * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT. 54 | */ 55 | public InsnNode(final int opcode) { 56 | super(opcode); 57 | } 58 | 59 | @Override 60 | public int getType() { 61 | return INSN; 62 | } 63 | 64 | @Override 65 | public void accept(final MethodVisitor methodVisitor) { 66 | methodVisitor.visitInsn(opcode); 67 | acceptAnnotations(methodVisitor); 68 | } 69 | 70 | @Override 71 | public AbstractInsnNode clone(final Map clonedLabels) { 72 | return new InsnNode(opcode).cloneAnnotations(this); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/IntInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents an instruction with a single int operand. 36 | * 37 | * @author Eric Bruneton 38 | */ 39 | public class IntInsnNode extends AbstractInsnNode { 40 | 41 | /** The operand of this instruction. */ 42 | public int operand; 43 | 44 | /** 45 | * Constructs a new {@link IntInsnNode}. 46 | * 47 | * @param opcode the opcode of the instruction to be constructed. This opcode must be BIPUSH, 48 | * SIPUSH or NEWARRAY. 49 | * @param operand the operand of the instruction to be constructed. 50 | */ 51 | public IntInsnNode(final int opcode, final int operand) { 52 | super(opcode); 53 | this.operand = operand; 54 | } 55 | 56 | /** 57 | * Sets the opcode of this instruction. 58 | * 59 | * @param opcode the new instruction opcode. This opcode must be BIPUSH, SIPUSH or NEWARRAY. 60 | */ 61 | public void setOpcode(final int opcode) { 62 | this.opcode = opcode; 63 | } 64 | 65 | @Override 66 | public int getType() { 67 | return INT_INSN; 68 | } 69 | 70 | @Override 71 | public void accept(final MethodVisitor methodVisitor) { 72 | methodVisitor.visitIntInsn(opcode, operand); 73 | acceptAnnotations(methodVisitor); 74 | } 75 | 76 | @Override 77 | public AbstractInsnNode clone(final Map clonedLabels) { 78 | return new IntInsnNode(opcode, operand).cloneAnnotations(this); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/InvokeDynamicInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Handle; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 34 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 35 | 36 | /** 37 | * A node that represents an invokedynamic instruction. 38 | * 39 | * @author Remi Forax 40 | */ 41 | public class InvokeDynamicInsnNode extends AbstractInsnNode { 42 | 43 | /** The method's name. */ 44 | public String name; 45 | 46 | /** The method's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). */ 47 | public String desc; 48 | 49 | /** The bootstrap method. */ 50 | public Handle bsm; 51 | 52 | /** The bootstrap method constant arguments. */ 53 | public Object[] bsmArgs; 54 | 55 | /** 56 | * Constructs a new {@link InvokeDynamicInsnNode}. 57 | * 58 | * @param name the method's name. 59 | * @param descriptor the method's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 60 | * @param bootstrapMethodHandle the bootstrap method. 61 | * @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be 62 | * an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link 63 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type} or {@link Handle} value. This method is allowed to modify the 64 | * content of the array so a caller should expect that this array may change. 65 | */ 66 | public InvokeDynamicInsnNode( 67 | final String name, 68 | final String descriptor, 69 | final Handle bootstrapMethodHandle, 70 | final Object... bootstrapMethodArguments) { // NOPMD(ArrayIsStoredDirectly): public field. 71 | super(Opcodes.INVOKEDYNAMIC); 72 | this.name = name; 73 | this.desc = descriptor; 74 | this.bsm = bootstrapMethodHandle; 75 | this.bsmArgs = bootstrapMethodArguments; 76 | } 77 | 78 | @Override 79 | public int getType() { 80 | return INVOKE_DYNAMIC_INSN; 81 | } 82 | 83 | @Override 84 | public void accept(final MethodVisitor methodVisitor) { 85 | methodVisitor.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); 86 | acceptAnnotations(methodVisitor); 87 | } 88 | 89 | @Override 90 | public AbstractInsnNode clone(final Map clonedLabels) { 91 | return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs).cloneAnnotations(this); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/JumpInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a jump instruction. A jump instruction is an instruction that may jump to 36 | * another instruction. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class JumpInsnNode extends AbstractInsnNode { 41 | 42 | /** 43 | * The operand of this instruction. This operand is a label that designates the instruction to 44 | * which this instruction may jump. 45 | */ 46 | public LabelNode label; 47 | 48 | /** 49 | * Constructs a new {@link JumpInsnNode}. 50 | * 51 | * @param opcode the opcode of the type instruction to be constructed. This opcode must be IFEQ, 52 | * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, 53 | * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. 54 | * @param label the operand of the instruction to be constructed. This operand is a label that 55 | * designates the instruction to which the jump instruction may jump. 56 | */ 57 | public JumpInsnNode(final int opcode, final LabelNode label) { 58 | super(opcode); 59 | this.label = label; 60 | } 61 | 62 | /** 63 | * Sets the opcode of this instruction. 64 | * 65 | * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, 66 | * IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, 67 | * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. 68 | */ 69 | public void setOpcode(final int opcode) { 70 | this.opcode = opcode; 71 | } 72 | 73 | @Override 74 | public int getType() { 75 | return JUMP_INSN; 76 | } 77 | 78 | @Override 79 | public void accept(final MethodVisitor methodVisitor) { 80 | methodVisitor.visitJumpInsn(opcode, label.getLabel()); 81 | acceptAnnotations(methodVisitor); 82 | } 83 | 84 | @Override 85 | public AbstractInsnNode clone(final Map clonedLabels) { 86 | return new JumpInsnNode(opcode, clone(label, clonedLabels)).cloneAnnotations(this); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/LabelNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Label; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 34 | 35 | /** An {@link AbstractInsnNode} that encapsulates a {@link Label}. */ 36 | public class LabelNode extends AbstractInsnNode { 37 | 38 | private Label value; 39 | 40 | public LabelNode() { 41 | super(-1); 42 | } 43 | 44 | public LabelNode(final Label label) { 45 | super(-1); 46 | this.value = label; 47 | } 48 | 49 | @Override 50 | public int getType() { 51 | return LABEL; 52 | } 53 | 54 | /** 55 | * Returns the label encapsulated by this node. A new label is created and associated with this 56 | * node if it was created without an encapsulated label. 57 | * 58 | * @return the label encapsulated by this node. 59 | */ 60 | public Label getLabel() { 61 | if (value == null) { 62 | value = new Label(); 63 | } 64 | return value; 65 | } 66 | 67 | @Override 68 | public void accept(final MethodVisitor methodVisitor) { 69 | methodVisitor.visitLabel(getLabel()); 70 | } 71 | 72 | @Override 73 | public AbstractInsnNode clone(final Map clonedLabels) { 74 | return clonedLabels.get(this); 75 | } 76 | 77 | public void resetLabel() { 78 | value = null; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/LdcInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 34 | 35 | /** 36 | * A node that represents an LDC instruction. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class LdcInsnNode extends AbstractInsnNode { 41 | 42 | /** 43 | * The constant to be loaded on the stack. This parameter must be a non null {@link Integer}, a 44 | * {@link Float}, a {@link Long}, a {@link Double}, a {@link String} or a {@link 45 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}. 46 | */ 47 | public Object cst; 48 | 49 | /** 50 | * Constructs a new {@link LdcInsnNode}. 51 | * 52 | * @param value the constant to be loaded on the stack. This parameter must be a non null {@link 53 | * Integer}, a {@link Float}, a {@link Long}, a {@link Double} or a {@link String}. 54 | */ 55 | public LdcInsnNode(final Object value) { 56 | super(Opcodes.LDC); 57 | this.cst = value; 58 | } 59 | 60 | @Override 61 | public int getType() { 62 | return LDC_INSN; 63 | } 64 | 65 | @Override 66 | public void accept(final MethodVisitor methodVisitor) { 67 | methodVisitor.visitLdcInsn(cst); 68 | acceptAnnotations(methodVisitor); 69 | } 70 | 71 | @Override 72 | public AbstractInsnNode clone(final Map clonedLabels) { 73 | return new LdcInsnNode(cst).cloneAnnotations(this); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/LineNumberNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a line number declaration. These nodes are pseudo instruction nodes in 36 | * order to be inserted in an instruction list. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class LineNumberNode extends AbstractInsnNode { 41 | 42 | /** A line number. This number refers to the source file from which the class was compiled. */ 43 | public int line; 44 | 45 | /** The first instruction corresponding to this line number. */ 46 | public LabelNode start; 47 | 48 | /** 49 | * Constructs a new {@link LineNumberNode}. 50 | * 51 | * @param line a line number. This number refers to the source file from which the class was 52 | * compiled. 53 | * @param start the first instruction corresponding to this line number. 54 | */ 55 | public LineNumberNode(final int line, final LabelNode start) { 56 | super(-1); 57 | this.line = line; 58 | this.start = start; 59 | } 60 | 61 | @Override 62 | public int getType() { 63 | return LINE; 64 | } 65 | 66 | @Override 67 | public void accept(final MethodVisitor methodVisitor) { 68 | methodVisitor.visitLineNumber(line, start.getLabel()); 69 | } 70 | 71 | @Override 72 | public AbstractInsnNode clone(final Map clonedLabels) { 73 | return new LineNumberNode(line, clone(start, clonedLabels)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/LocalVariableNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 31 | 32 | /** 33 | * A node that represents a local variable declaration. 34 | * 35 | * @author Eric Bruneton 36 | */ 37 | public class LocalVariableNode { 38 | 39 | /** The name of a local variable. */ 40 | public String name; 41 | 42 | /** The type descriptor of this local variable. */ 43 | public String desc; 44 | 45 | /** The signature of this local variable. May be {@literal null}. */ 46 | public String signature; 47 | 48 | /** The first instruction corresponding to the scope of this local variable (inclusive). */ 49 | public LabelNode start; 50 | 51 | /** The last instruction corresponding to the scope of this local variable (exclusive). */ 52 | public LabelNode end; 53 | 54 | /** The local variable's index. */ 55 | public int index; 56 | 57 | /** 58 | * Constructs a new {@link LocalVariableNode}. 59 | * 60 | * @param name the name of a local variable. 61 | * @param descriptor the type descriptor of this local variable. 62 | * @param signature the signature of this local variable. May be {@literal null}. 63 | * @param start the first instruction corresponding to the scope of this local variable 64 | * (inclusive). 65 | * @param end the last instruction corresponding to the scope of this local variable (exclusive). 66 | * @param index the local variable's index. 67 | */ 68 | public LocalVariableNode( 69 | final String name, 70 | final String descriptor, 71 | final String signature, 72 | final LabelNode start, 73 | final LabelNode end, 74 | final int index) { 75 | this.name = name; 76 | this.desc = descriptor; 77 | this.signature = signature; 78 | this.start = start; 79 | this.end = end; 80 | this.index = index; 81 | } 82 | 83 | /** 84 | * Makes the given visitor visit this local variable declaration. 85 | * 86 | * @param methodVisitor a method visitor. 87 | */ 88 | public void accept(final MethodVisitor methodVisitor) { 89 | methodVisitor.visitLocalVariable( 90 | name, desc, signature, start.getLabel(), end.getLabel(), index); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/LookupSwitchInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | import java.util.Map; 32 | 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Label; 34 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 35 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 36 | 37 | /** 38 | * A node that represents a LOOKUPSWITCH instruction. 39 | * 40 | * @author Eric Bruneton 41 | */ 42 | public class LookupSwitchInsnNode extends AbstractInsnNode { 43 | 44 | /** Beginning of the default handler block. */ 45 | public LabelNode dflt; 46 | 47 | /** The values of the keys. */ 48 | public List keys; 49 | 50 | /** Beginnings of the handler blocks. */ 51 | public List labels; 52 | 53 | /** 54 | * Constructs a new {@link LookupSwitchInsnNode}. 55 | * 56 | * @param dflt beginning of the default handler block. 57 | * @param keys the values of the keys. 58 | * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the 59 | * handler block for the {@code keys[i]} key. 60 | */ 61 | public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) { 62 | super(Opcodes.LOOKUPSWITCH); 63 | this.dflt = dflt; 64 | this.keys = Util.asArrayList(keys); 65 | this.labels = Util.asArrayList(labels); 66 | } 67 | 68 | @Override 69 | public int getType() { 70 | return LOOKUPSWITCH_INSN; 71 | } 72 | 73 | @Override 74 | public void accept(final MethodVisitor methodVisitor) { 75 | int[] keysArray = new int[this.keys.size()]; 76 | for (int i = 0, n = keysArray.length; i < n; ++i) { 77 | keysArray[i] = this.keys.get(i).intValue(); 78 | } 79 | Label[] labelsArray = new Label[this.labels.size()]; 80 | for (int i = 0, n = labelsArray.length; i < n; ++i) { 81 | labelsArray[i] = this.labels.get(i).getLabel(); 82 | } 83 | methodVisitor.visitLookupSwitchInsn(dflt.getLabel(), keysArray, labelsArray); 84 | acceptAnnotations(methodVisitor); 85 | } 86 | 87 | @Override 88 | public AbstractInsnNode clone(final Map clonedLabels) { 89 | LookupSwitchInsnNode clone = 90 | new LookupSwitchInsnNode(clone(dflt, clonedLabels), null, clone(labels, clonedLabels)); 91 | clone.keys.addAll(keys); 92 | return clone.cloneAnnotations(this); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/MethodInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 34 | 35 | /** 36 | * A node that represents a method instruction. A method instruction is an instruction that invokes 37 | * a method. 38 | * 39 | * @author Eric Bruneton 40 | */ 41 | public class MethodInsnNode extends AbstractInsnNode { 42 | 43 | /** 44 | * The internal name of the method's owner class (see {@link 45 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). 46 | * 47 | *

For methods of arrays, e.g., {@code clone()}, the array type descriptor. 48 | */ 49 | public String owner; 50 | 51 | /** The method's name. */ 52 | public String name; 53 | 54 | /** The method's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). */ 55 | public String desc; 56 | 57 | /** Whether the method's owner class if an interface. */ 58 | public boolean itf; 59 | 60 | /** 61 | * Constructs a new {@link MethodInsnNode}. 62 | * 63 | * @param opcode the opcode of the type instruction to be constructed. This opcode must be 64 | * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. 65 | * @param owner the internal name of the method's owner class (see {@link 66 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). 67 | * @param name the method's name. 68 | * @param descriptor the method's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 69 | */ 70 | public MethodInsnNode( 71 | final int opcode, final String owner, final String name, final String descriptor) { 72 | this(opcode, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE); 73 | } 74 | 75 | /** 76 | * Constructs a new {@link MethodInsnNode}. 77 | * 78 | * @param opcode the opcode of the type instruction to be constructed. This opcode must be 79 | * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. 80 | * @param owner the internal name of the method's owner class (see {@link 81 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type#getInternalName()}). 82 | * @param name the method's name. 83 | * @param descriptor the method's descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 84 | * @param isInterface if the method's owner class is an interface. 85 | */ 86 | public MethodInsnNode( 87 | final int opcode, 88 | final String owner, 89 | final String name, 90 | final String descriptor, 91 | final boolean isInterface) { 92 | super(opcode); 93 | this.owner = owner; 94 | this.name = name; 95 | this.desc = descriptor; 96 | this.itf = isInterface; 97 | } 98 | 99 | /** 100 | * Sets the opcode of this instruction. 101 | * 102 | * @param opcode the new instruction opcode. This opcode must be INVOKEVIRTUAL, INVOKESPECIAL, 103 | * INVOKESTATIC or INVOKEINTERFACE. 104 | */ 105 | public void setOpcode(final int opcode) { 106 | this.opcode = opcode; 107 | } 108 | 109 | @Override 110 | public int getType() { 111 | return METHOD_INSN; 112 | } 113 | 114 | @Override 115 | public void accept(final MethodVisitor methodVisitor) { 116 | methodVisitor.visitMethodInsn(opcode, owner, name, desc, itf); 117 | acceptAnnotations(methodVisitor); 118 | } 119 | 120 | @Override 121 | public AbstractInsnNode clone(final Map clonedLabels) { 122 | return new MethodInsnNode(opcode, owner, name, desc, itf).cloneAnnotations(this); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/ModuleExportNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.ModuleVisitor; 33 | 34 | /** 35 | * A node that represents an exported package with its name and the module that can access to it. 36 | * 37 | * @author Remi Forax 38 | */ 39 | public class ModuleExportNode { 40 | 41 | /** The internal name of the exported package. */ 42 | public String packaze; 43 | 44 | /** 45 | * The access flags (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes}). Valid values are {@code 46 | * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 47 | */ 48 | public int access; 49 | 50 | /** 51 | * The list of modules that can access this exported package, specified with fully qualified names 52 | * (using dots). May be {@literal null}. 53 | */ 54 | public List modules; 55 | 56 | /** 57 | * Constructs a new {@link ModuleExportNode}. 58 | * 59 | * @param packaze the internal name of the exported package. 60 | * @param access the package access flags, one or more of {@code ACC_SYNTHETIC} and {@code 61 | * ACC_MANDATED}. 62 | * @param modules a list of modules that can access this exported package, specified with fully 63 | * qualified names (using dots). 64 | */ 65 | public ModuleExportNode(final String packaze, final int access, final List modules) { 66 | this.packaze = packaze; 67 | this.access = access; 68 | this.modules = modules; 69 | } 70 | 71 | /** 72 | * Makes the given module visitor visit this export declaration. 73 | * 74 | * @param moduleVisitor a module visitor. 75 | */ 76 | public void accept(final ModuleVisitor moduleVisitor) { 77 | moduleVisitor.visitExport( 78 | packaze, access, modules == null ? null : modules.toArray(new String[0])); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/ModuleOpenNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.ModuleVisitor; 33 | 34 | /** 35 | * A node that represents an opened package with its name and the module that can access it. 36 | * 37 | * @author Remi Forax 38 | */ 39 | public class ModuleOpenNode { 40 | 41 | /** The internal name of the opened package. */ 42 | public String packaze; 43 | 44 | /** 45 | * The access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and {@code 46 | * ACC_MANDATED}. 47 | */ 48 | public int access; 49 | 50 | /** 51 | * The fully qualified names (using dots) of the modules that can use deep reflection to the 52 | * classes of the open package, or {@literal null}. 53 | */ 54 | public List modules; 55 | 56 | /** 57 | * Constructs a new {@link ModuleOpenNode}. 58 | * 59 | * @param packaze the internal name of the opened package. 60 | * @param access the access flag of the opened package, valid values are among {@code 61 | * ACC_SYNTHETIC} and {@code ACC_MANDATED}. 62 | * @param modules the fully qualified names (using dots) of the modules that can use deep 63 | * reflection to the classes of the open package, or {@literal null}. 64 | */ 65 | public ModuleOpenNode(final String packaze, final int access, final List modules) { 66 | this.packaze = packaze; 67 | this.access = access; 68 | this.modules = modules; 69 | } 70 | 71 | /** 72 | * Makes the given module visitor visit this opened package. 73 | * 74 | * @param moduleVisitor a module visitor. 75 | */ 76 | public void accept(final ModuleVisitor moduleVisitor) { 77 | moduleVisitor.visitOpen( 78 | packaze, access, modules == null ? null : modules.toArray(new String[0])); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/ModuleProvideNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.ModuleVisitor; 33 | 34 | /** 35 | * A node that represents a service and its implementation provided by the current module. 36 | * 37 | * @author Remi Forax 38 | */ 39 | public class ModuleProvideNode { 40 | 41 | /** The internal name of the service. */ 42 | public String service; 43 | 44 | /** The internal names of the implementations of the service (there is at least one provider). */ 45 | public List providers; 46 | 47 | /** 48 | * Constructs a new {@link ModuleProvideNode}. 49 | * 50 | * @param service the internal name of the service. 51 | * @param providers the internal names of the implementations of the service (there is at least 52 | * one provider). 53 | */ 54 | public ModuleProvideNode(final String service, final List providers) { 55 | this.service = service; 56 | this.providers = providers; 57 | } 58 | 59 | /** 60 | * Makes the given module visitor visit this require declaration. 61 | * 62 | * @param moduleVisitor a module visitor. 63 | */ 64 | public void accept(final ModuleVisitor moduleVisitor) { 65 | moduleVisitor.visitProvide(service, providers.toArray(new String[0])); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/ModuleRequireNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.ModuleVisitor; 31 | 32 | /** 33 | * A node that represents a required module with its name and access of a module descriptor. 34 | * 35 | * @author Remi Forax 36 | */ 37 | public class ModuleRequireNode { 38 | 39 | /** The fully qualified name (using dots) of the dependence. */ 40 | public String module; 41 | 42 | /** 43 | * The access flag of the dependence among {@code ACC_TRANSITIVE}, {@code ACC_STATIC_PHASE}, 44 | * {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 45 | */ 46 | public int access; 47 | 48 | /** The module version at compile time, or {@literal null}. */ 49 | public String version; 50 | 51 | /** 52 | * Constructs a new {@link ModuleRequireNode}. 53 | * 54 | * @param module the fully qualified name (using dots) of the dependence. 55 | * @param access the access flag of the dependence among {@code ACC_TRANSITIVE}, {@code 56 | * ACC_STATIC_PHASE}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 57 | * @param version the module version at compile time, or {@literal null}. 58 | */ 59 | public ModuleRequireNode(final String module, final int access, final String version) { 60 | this.module = module; 61 | this.access = access; 62 | this.version = version; 63 | } 64 | 65 | /** 66 | * Makes the given module visitor visit this require directive. 67 | * 68 | * @param moduleVisitor a module visitor. 69 | */ 70 | public void accept(final ModuleVisitor moduleVisitor) { 71 | moduleVisitor.visitRequire(module, access, version); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/MultiANewArrayInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 34 | 35 | /** 36 | * A node that represents a MULTIANEWARRAY instruction. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class MultiANewArrayInsnNode extends AbstractInsnNode { 41 | 42 | /** An array type descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). */ 43 | public String desc; 44 | 45 | /** Number of dimensions of the array to allocate. */ 46 | public int dims; 47 | 48 | /** 49 | * Constructs a new {@link MultiANewArrayInsnNode}. 50 | * 51 | * @param descriptor an array type descriptor (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 52 | * @param numDimensions the number of dimensions of the array to allocate. 53 | */ 54 | public MultiANewArrayInsnNode(final String descriptor, final int numDimensions) { 55 | super(Opcodes.MULTIANEWARRAY); 56 | this.desc = descriptor; 57 | this.dims = numDimensions; 58 | } 59 | 60 | @Override 61 | public int getType() { 62 | return MULTIANEWARRAY_INSN; 63 | } 64 | 65 | @Override 66 | public void accept(final MethodVisitor methodVisitor) { 67 | methodVisitor.visitMultiANewArrayInsn(desc, dims); 68 | acceptAnnotations(methodVisitor); 69 | } 70 | 71 | @Override 72 | public AbstractInsnNode clone(final Map clonedLabels) { 73 | return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/ParameterNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 31 | 32 | /** 33 | * A node that represents a parameter of a method. 34 | * 35 | * @author Remi Forax 36 | */ 37 | public class ParameterNode { 38 | 39 | /** The parameter's name. */ 40 | public String name; 41 | 42 | /** 43 | * The parameter's access flags (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes}). Valid values are {@code 44 | * ACC_FINAL}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. 45 | */ 46 | public int access; 47 | 48 | /** 49 | * Constructs a new {@link ParameterNode}. 50 | * 51 | * @param access The parameter's access flags. Valid values are {@code ACC_FINAL}, {@code 52 | * ACC_SYNTHETIC} or/and {@code ACC_MANDATED} (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes}). 53 | * @param name the parameter's name. 54 | */ 55 | public ParameterNode(final String name, final int access) { 56 | this.name = name; 57 | this.access = access; 58 | } 59 | 60 | /** 61 | * Makes the given visitor visit this parameter declaration. 62 | * 63 | * @param methodVisitor a method visitor. 64 | */ 65 | public void accept(final MethodVisitor methodVisitor) { 66 | methodVisitor.visitParameter(name, access); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/TableSwitchInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | import java.util.Map; 32 | 33 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Label; 34 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 35 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 36 | 37 | /** 38 | * A node that represents a TABLESWITCH instruction. 39 | * 40 | * @author Eric Bruneton 41 | */ 42 | public class TableSwitchInsnNode extends AbstractInsnNode { 43 | 44 | /** The minimum key value. */ 45 | public int min; 46 | 47 | /** The maximum key value. */ 48 | public int max; 49 | 50 | /** Beginning of the default handler block. */ 51 | public LabelNode dflt; 52 | 53 | /** Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects. */ 54 | public List labels; 55 | 56 | /** 57 | * Constructs a new {@link TableSwitchInsnNode}. 58 | * 59 | * @param min the minimum key value. 60 | * @param max the maximum key value. 61 | * @param dflt beginning of the default handler block. 62 | * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the 63 | * handler block for the {@code min + i} key. 64 | */ 65 | public TableSwitchInsnNode( 66 | final int min, final int max, final LabelNode dflt, final LabelNode... labels) { 67 | super(Opcodes.TABLESWITCH); 68 | this.min = min; 69 | this.max = max; 70 | this.dflt = dflt; 71 | this.labels = Util.asArrayList(labels); 72 | } 73 | 74 | @Override 75 | public int getType() { 76 | return TABLESWITCH_INSN; 77 | } 78 | 79 | @Override 80 | public void accept(final MethodVisitor methodVisitor) { 81 | Label[] labelsArray = new Label[this.labels.size()]; 82 | for (int i = 0, n = labelsArray.length; i < n; ++i) { 83 | labelsArray[i] = this.labels.get(i).getLabel(); 84 | } 85 | methodVisitor.visitTableSwitchInsn(min, max, dflt.getLabel(), labelsArray); 86 | acceptAnnotations(methodVisitor); 87 | } 88 | 89 | @Override 90 | public AbstractInsnNode clone(final Map clonedLabels) { 91 | return new TableSwitchInsnNode(min, max, clone(dflt, clonedLabels), clone(labels, clonedLabels)) 92 | .cloneAnnotations(this); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/TryCatchBlockNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.List; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a try catch block. 36 | * 37 | * @author Eric Bruneton 38 | */ 39 | public class TryCatchBlockNode { 40 | 41 | /** The beginning of the exception handler's scope (inclusive). */ 42 | public LabelNode start; 43 | 44 | /** The end of the exception handler's scope (exclusive). */ 45 | public LabelNode end; 46 | 47 | /** The beginning of the exception handler's code. */ 48 | public LabelNode handler; 49 | 50 | /** 51 | * The internal name of the type of exceptions handled by the handler. May be {@literal null} to 52 | * catch any exceptions (for "finally" blocks). 53 | */ 54 | public String type; 55 | 56 | /** The runtime visible type annotations on the exception handler type. May be {@literal null}. */ 57 | public List visibleTypeAnnotations; 58 | 59 | /** 60 | * The runtime invisible type annotations on the exception handler type. May be {@literal null}. 61 | */ 62 | public List invisibleTypeAnnotations; 63 | 64 | /** 65 | * Constructs a new {@link TryCatchBlockNode}. 66 | * 67 | * @param start the beginning of the exception handler's scope (inclusive). 68 | * @param end the end of the exception handler's scope (exclusive). 69 | * @param handler the beginning of the exception handler's code. 70 | * @param type the internal name of the type of exceptions handled by the handler, or {@literal 71 | * null} to catch any exceptions (for "finally" blocks). 72 | */ 73 | public TryCatchBlockNode( 74 | final LabelNode start, final LabelNode end, final LabelNode handler, final String type) { 75 | this.start = start; 76 | this.end = end; 77 | this.handler = handler; 78 | this.type = type; 79 | } 80 | 81 | /** 82 | * Updates the index of this try catch block in the method's list of try catch block nodes. This 83 | * index maybe stored in the 'target' field of the type annotations of this block. 84 | * 85 | * @param index the new index of this try catch block in the method's list of try catch block 86 | * nodes. 87 | */ 88 | public void updateIndex(final int index) { 89 | int newTypeRef = 0x42000000 | (index << 8); 90 | if (visibleTypeAnnotations != null) { 91 | for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) { 92 | visibleTypeAnnotations.get(i).typeRef = newTypeRef; 93 | } 94 | } 95 | if (invisibleTypeAnnotations != null) { 96 | for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) { 97 | invisibleTypeAnnotations.get(i).typeRef = newTypeRef; 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * Makes the given visitor visit this try catch block. 104 | * 105 | * @param methodVisitor a method visitor. 106 | */ 107 | public void accept(final MethodVisitor methodVisitor) { 108 | methodVisitor.visitTryCatchBlock( 109 | start.getLabel(), end.getLabel(), handler == null ? null : handler.getLabel(), type); 110 | if (visibleTypeAnnotations != null) { 111 | for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) { 112 | TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i); 113 | typeAnnotation.accept( 114 | methodVisitor.visitTryCatchAnnotation( 115 | typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true)); 116 | } 117 | } 118 | if (invisibleTypeAnnotations != null) { 119 | for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) { 120 | TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i); 121 | typeAnnotation.accept( 122 | methodVisitor.visitTryCatchAnnotation( 123 | typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false)); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/TypeAnnotationNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Opcodes; 31 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.TypePath; 32 | 33 | /** 34 | * A node that represents a type annotation. 35 | * 36 | * @author Eric Bruneton 37 | */ 38 | public class TypeAnnotationNode extends AnnotationNode { 39 | 40 | /** A reference to the annotated type. See {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.TypeReference}. */ 41 | public int typeRef; 42 | 43 | /** 44 | * The path to the annotated type argument, wildcard bound, array element type, or static outer 45 | * type within the referenced type. May be {@literal null} if the annotation targets 'typeRef' as 46 | * a whole. 47 | */ 48 | public TypePath typePath; 49 | 50 | /** 51 | * Constructs a new {@link AnnotationNode}. Subclasses must not use this constructor. 52 | * Instead, they must use the {@link #TypeAnnotationNode(int, int, TypePath, String)} version. 53 | * 54 | * @param typeRef a reference to the annotated type. See {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.TypeReference}. 55 | * @param typePath the path to the annotated type argument, wildcard bound, array element type, or 56 | * static inner type within 'typeRef'. May be {@literal null} if the annotation targets 57 | * 'typeRef' as a whole. 58 | * @param descriptor the class descriptor of the annotation class. 59 | * @throws IllegalStateException If a subclass calls this constructor. 60 | */ 61 | public TypeAnnotationNode(final int typeRef, final TypePath typePath, final String descriptor) { 62 | this(/* latest api = */ Opcodes.ASM8, typeRef, typePath, descriptor); 63 | if (getClass() != TypeAnnotationNode.class) { 64 | throw new IllegalStateException(); 65 | } 66 | } 67 | 68 | /** 69 | * Constructs a new {@link AnnotationNode}. 70 | * 71 | * @param api the ASM API version implemented by this visitor. Must be one of {@link 72 | * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link 73 | * Opcodes#ASM8}. 74 | * @param typeRef a reference to the annotated type. See {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.TypeReference}. 75 | * @param typePath the path to the annotated type argument, wildcard bound, array element type, or 76 | * static inner type within 'typeRef'. May be {@literal null} if the annotation targets 77 | * 'typeRef' as a whole. 78 | * @param descriptor the class descriptor of the annotation class. 79 | */ 80 | public TypeAnnotationNode( 81 | final int api, final int typeRef, final TypePath typePath, final String descriptor) { 82 | super(api, descriptor); 83 | this.typeRef = typeRef; 84 | this.typePath = typePath; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/TypeInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a type instruction. A type instruction is an instruction that takes a type 36 | * descriptor as parameter. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class TypeInsnNode extends AbstractInsnNode { 41 | 42 | /** 43 | * The operand of this instruction. This operand is an internal name (see {@link 44 | * sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 45 | */ 46 | public String desc; 47 | 48 | /** 49 | * Constructs a new {@link TypeInsnNode}. 50 | * 51 | * @param opcode the opcode of the type instruction to be constructed. This opcode must be NEW, 52 | * ANEWARRAY, CHECKCAST or INSTANCEOF. 53 | * @param descriptor the operand of the instruction to be constructed. This operand is an internal 54 | * name (see {@link sipka.jvm.tailrec.thirdparty.org.objectweb.asm.Type}). 55 | */ 56 | public TypeInsnNode(final int opcode, final String descriptor) { 57 | super(opcode); 58 | this.desc = descriptor; 59 | } 60 | 61 | /** 62 | * Sets the opcode of this instruction. 63 | * 64 | * @param opcode the new instruction opcode. This opcode must be NEW, ANEWARRAY, CHECKCAST or 65 | * INSTANCEOF. 66 | */ 67 | public void setOpcode(final int opcode) { 68 | this.opcode = opcode; 69 | } 70 | 71 | @Override 72 | public int getType() { 73 | return TYPE_INSN; 74 | } 75 | 76 | @Override 77 | public void accept(final MethodVisitor methodVisitor) { 78 | methodVisitor.visitTypeInsn(opcode, desc); 79 | acceptAnnotations(methodVisitor); 80 | } 81 | 82 | @Override 83 | public AbstractInsnNode clone(final Map clonedLabels) { 84 | return new TypeInsnNode(opcode, desc).cloneAnnotations(this); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/UnsupportedClassVersionException.java: -------------------------------------------------------------------------------- 1 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 2 | 3 | /** 4 | * Exception thrown in {@link AnnotationNode#check}, {@link ClassNode#check}, {@link 5 | * FieldNode#check} and {@link MethodNode#check} when these nodes (or their children, recursively) 6 | * contain elements that were introduced in more recent versions of the ASM API than version passed 7 | * to these methods. 8 | * 9 | * @author Eric Bruneton 10 | */ 11 | public class UnsupportedClassVersionException extends RuntimeException { 12 | 13 | private static final long serialVersionUID = -3502347765891805831L; 14 | } 15 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/Util.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | /** 34 | * Utility methods to convert an array of primitive or object values to a mutable ArrayList, not 35 | * baked by the array (unlike {@link java.util.Arrays#asList}). 36 | * 37 | * @author Eric Bruneton 38 | */ 39 | final class Util { 40 | 41 | private Util() {} 42 | 43 | static List add(final List list, final T element) { 44 | List newList = list == null ? new ArrayList<>(1) : list; 45 | newList.add(element); 46 | return newList; 47 | } 48 | 49 | static List asArrayList(final int length) { 50 | List list = new ArrayList<>(length); 51 | for (int i = 0; i < length; ++i) { 52 | list.add(null); 53 | } 54 | return list; 55 | } 56 | 57 | static List asArrayList(final T[] array) { 58 | if (array == null) { 59 | return new ArrayList<>(); 60 | } 61 | ArrayList list = new ArrayList<>(array.length); 62 | for (T t : array) { 63 | list.add(t); 64 | } 65 | return list; 66 | } 67 | 68 | static List asArrayList(final byte[] byteArray) { 69 | if (byteArray == null) { 70 | return new ArrayList<>(); 71 | } 72 | ArrayList byteList = new ArrayList<>(byteArray.length); 73 | for (byte b : byteArray) { 74 | byteList.add(b); 75 | } 76 | return byteList; 77 | } 78 | 79 | static List asArrayList(final boolean[] booleanArray) { 80 | if (booleanArray == null) { 81 | return new ArrayList<>(); 82 | } 83 | ArrayList booleanList = new ArrayList<>(booleanArray.length); 84 | for (boolean b : booleanArray) { 85 | booleanList.add(b); 86 | } 87 | return booleanList; 88 | } 89 | 90 | static List asArrayList(final short[] shortArray) { 91 | if (shortArray == null) { 92 | return new ArrayList<>(); 93 | } 94 | ArrayList shortList = new ArrayList<>(shortArray.length); 95 | for (short s : shortArray) { 96 | shortList.add(s); 97 | } 98 | return shortList; 99 | } 100 | 101 | static List asArrayList(final char[] charArray) { 102 | if (charArray == null) { 103 | return new ArrayList<>(); 104 | } 105 | ArrayList charList = new ArrayList<>(charArray.length); 106 | for (char c : charArray) { 107 | charList.add(c); 108 | } 109 | return charList; 110 | } 111 | 112 | static List asArrayList(final int[] intArray) { 113 | if (intArray == null) { 114 | return new ArrayList<>(); 115 | } 116 | ArrayList intList = new ArrayList<>(intArray.length); 117 | for (int i : intArray) { 118 | intList.add(i); 119 | } 120 | return intList; 121 | } 122 | 123 | static List asArrayList(final float[] floatArray) { 124 | if (floatArray == null) { 125 | return new ArrayList<>(); 126 | } 127 | ArrayList floatList = new ArrayList<>(floatArray.length); 128 | for (float f : floatArray) { 129 | floatList.add(f); 130 | } 131 | return floatList; 132 | } 133 | 134 | static List asArrayList(final long[] longArray) { 135 | if (longArray == null) { 136 | return new ArrayList<>(); 137 | } 138 | ArrayList longList = new ArrayList<>(longArray.length); 139 | for (long l : longArray) { 140 | longList.add(l); 141 | } 142 | return longList; 143 | } 144 | 145 | static List asArrayList(final double[] doubleArray) { 146 | if (doubleArray == null) { 147 | return new ArrayList<>(); 148 | } 149 | ArrayList doubleList = new ArrayList<>(doubleArray.length); 150 | for (double d : doubleArray) { 151 | doubleList.add(d); 152 | } 153 | return doubleList; 154 | } 155 | 156 | static List asArrayList(final int length, final T[] array) { 157 | List list = new ArrayList<>(length); 158 | for (int i = 0; i < length; ++i) { 159 | list.add(array[i]); // NOPMD(UseArraysAsList): we convert a part of the array. 160 | } 161 | return list; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/sipka/jvm/tailrec/thirdparty/org/objectweb/asm/tree/VarInsnNode.java: -------------------------------------------------------------------------------- 1 | // ASM: a very small and fast Java bytecode manipulation framework 2 | // Copyright (c) 2000-2011 INRIA, France Telecom 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 1. Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 2. Redistributions in binary form must reproduce the above copyright 11 | // notice, this list of conditions and the following disclaimer in the 12 | // documentation and/or other materials provided with the distribution. 13 | // 3. Neither the name of the copyright holders nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 | // THE POSSIBILITY OF SUCH DAMAGE. 28 | package sipka.jvm.tailrec.thirdparty.org.objectweb.asm.tree; 29 | 30 | import java.util.Map; 31 | 32 | import sipka.jvm.tailrec.thirdparty.org.objectweb.asm.MethodVisitor; 33 | 34 | /** 35 | * A node that represents a local variable instruction. A local variable instruction is an 36 | * instruction that loads or stores the value of a local variable. 37 | * 38 | * @author Eric Bruneton 39 | */ 40 | public class VarInsnNode extends AbstractInsnNode { 41 | 42 | /** The operand of this instruction. This operand is the index of a local variable. */ 43 | public int var; 44 | 45 | /** 46 | * Constructs a new {@link VarInsnNode}. 47 | * 48 | * @param opcode the opcode of the local variable instruction to be constructed. This opcode must 49 | * be ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. 50 | * @param var the operand of the instruction to be constructed. This operand is the index of a 51 | * local variable. 52 | */ 53 | public VarInsnNode(final int opcode, final int var) { 54 | super(opcode); 55 | this.var = var; 56 | } 57 | 58 | /** 59 | * Sets the opcode of this instruction. 60 | * 61 | * @param opcode the new instruction opcode. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD, 62 | * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. 63 | */ 64 | public void setOpcode(final int opcode) { 65 | this.opcode = opcode; 66 | } 67 | 68 | @Override 69 | public int getType() { 70 | return VAR_INSN; 71 | } 72 | 73 | @Override 74 | public void accept(final MethodVisitor methodVisitor) { 75 | methodVisitor.visitVarInsn(opcode, var); 76 | acceptAnnotations(methodVisitor); 77 | } 78 | 79 | @Override 80 | public AbstractInsnNode clone(final Map clonedLabels) { 81 | return new VarInsnNode(opcode, var).cloneAnnotations(this); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/OptimizerTaskSakerTest/saker.build: -------------------------------------------------------------------------------- 1 | build( 2 | out path 3 | ) { 4 | $javac = saker.java.compile(src) 5 | 6 | $path = sipka.jvm.tailrec.optimize($javac[ClassDirectory]) 7 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/OptimizerTaskSakerTest/src/test/Main.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Main { 4 | public static void count(int n) { 5 | if (n == 0) { 6 | return; 7 | } 8 | count(n - 1); 9 | } 10 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/RepackageArchiveOptimizeSakerTest/saker.build: -------------------------------------------------------------------------------- 1 | build( 2 | out path, 3 | out secondpath, 4 | ) { 5 | $javac = saker.java.compile(src) 6 | 7 | $jar = saker.jar.create( 8 | Output: first.jar, 9 | Resources: { 10 | Directory: $javac[ClassDirectory], 11 | Resources: **, 12 | }, 13 | Transformers: sipka.jvm.tailrec.zip.transformer(), 14 | ) 15 | 16 | $secondjar = saker.jar.create( 17 | Output: second.jar, 18 | Include: $jar[Path], 19 | Transformers: sipka.jvm.tailrec.zip.transformer(), 20 | ) 21 | 22 | $path = $jar[Path] 23 | $secondpath = $secondjar[Path] 24 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/RepackageArchiveOptimizeSakerTest/src/test/Main.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Main { 4 | public static void count(int n) { 5 | if (n == 0) { 6 | return; 7 | } 8 | count(n - 1); 9 | } 10 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/SimpleJarOptimizeSakerTest/saker.build: -------------------------------------------------------------------------------- 1 | build( 2 | out path 3 | ) { 4 | $javac = saker.java.compile(src) 5 | 6 | $jar = saker.jar.create( 7 | Resources: { 8 | Directory: $javac[ClassDirectory], 9 | Resources: **, 10 | }, 11 | Transformers: sipka.jvm.tailrec.zip.transformer(), 12 | ) 13 | 14 | $path = $jar[Path] 15 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/SimpleJarOptimizeSakerTest/src/test/Main.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Main { 4 | public static void count(int n) { 5 | if (n == 0) { 6 | return; 7 | } 8 | count(n - 1); 9 | } 10 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/SimpleZipOptimizeSakerTest/saker.build: -------------------------------------------------------------------------------- 1 | build( 2 | out path 3 | ) { 4 | $javac = saker.java.compile(src) 5 | 6 | $jar = saker.zip.create( 7 | Resources: { 8 | Directory: $javac[ClassDirectory], 9 | Resources: **, 10 | }, 11 | Transformers: sipka.jvm.tailrec.zip.transformer(), 12 | ) 13 | 14 | $path = $jar[Path] 15 | } -------------------------------------------------------------------------------- /test/resources/testcontents/testing/saker/sipka/jvm/tailrec/SimpleZipOptimizeSakerTest/src/test/Main.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class Main { 4 | public static void count(int n) { 5 | if (n == 0) { 6 | return; 7 | } 8 | count(n - 1); 9 | } 10 | } -------------------------------------------------------------------------------- /test/src-jdk8/testing/sipka/jvm/tailrec/InterfaceDefaultMethodTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class InterfaceDefaultMethodTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | optimizeClass(TestMethods.class); 12 | Class optimizedimpl = optimizeClass(Impl.class); 13 | assertInvocationException(StackOverflowError.class, () -> optimizedimpl.getMethod("count", int.class) 14 | .invoke(optimizedimpl.getConstructor().newInstance(), 100000)); 15 | } 16 | 17 | public static interface TestMethods { 18 | public default void count(int n) { 19 | if (n == 0) { 20 | return; 21 | } 22 | count(n - 1); 23 | } 24 | } 25 | 26 | public static class Impl implements TestMethods { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/src-jdk8/testing/sipka/jvm/tailrec/InterfaceStaticMethodTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class InterfaceStaticMethodTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 13 | } 14 | 15 | public static interface TestMethods { 16 | public static void count(int n) { 17 | if (n == 0) { 18 | return; 19 | } 20 | count(n - 1); 21 | } 22 | 23 | public static void count(long n) { 24 | if (n == 0) { 25 | return; 26 | } 27 | count(n - 1); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src-jdk8/testing/sipka/jvm/tailrec/LambdaCountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class LambdaCountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | optimizeClass(CounterInt.class); 12 | optimizeClass(CounterLong.class); 13 | 14 | assertSuccessfulOptimization(TestMethods.class.getMethod("countViaLambda", int.class), 10000000); 15 | assertSuccessfulOptimization(TestMethods.class.getMethod("countViaLambda", long.class), 10000000); 16 | } 17 | 18 | public interface CounterInt { 19 | public void lambdacount(int n); 20 | } 21 | 22 | public interface CounterLong { 23 | public void lambdacount(long n); 24 | } 25 | 26 | public static class TestMethods { 27 | public static void countViaLambda(int startn) { 28 | CounterInt c = (n) -> { 29 | count(n); 30 | }; 31 | c.lambdacount(startn); 32 | } 33 | 34 | public static void countViaLambda(long startn) { 35 | CounterLong c = (n) -> { 36 | count(n); 37 | }; 38 | c.lambdacount(startn); 39 | } 40 | 41 | public static void count(int n) { 42 | if (n == 0) { 43 | return; 44 | } 45 | count(n - 1); 46 | } 47 | 48 | public static void count(long n) { 49 | if (n == 0) { 50 | return; 51 | } 52 | count(n - 1); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/src/testing/saker/sipka/jvm/tailrec/OptimizerTaskSakerTest.java: -------------------------------------------------------------------------------- 1 | package testing.saker.sipka.jvm.tailrec; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | 5 | import saker.build.file.path.SakerPath; 6 | import saker.build.thirdparty.saker.util.classloader.ClassLoaderDataFinder; 7 | import saker.build.thirdparty.saker.util.classloader.MultiDataClassLoader; 8 | import saker.build.util.classloader.SakerPathClassLoaderDataFinder; 9 | import testing.saker.SakerTest; 10 | import testing.saker.nest.util.NestRepositoryCachingEnvironmentTestCase; 11 | 12 | @SakerTest 13 | public class OptimizerTaskSakerTest extends NestRepositoryCachingEnvironmentTestCase { 14 | 15 | @Override 16 | protected void runNestTaskTestImpl() throws Throwable { 17 | SakerPath mainjavapath = PATH_WORKING_DIRECTORY.resolve("src/test/Main.java"); 18 | 19 | CombinedTargetTaskResult res = runScriptTask("build"); 20 | 21 | testOptimization((SakerPath) res.getTargetTaskResult("path")); 22 | 23 | res = runScriptTask("build"); 24 | assertEmpty(getMetric().getRunTaskIdResults()); 25 | 26 | files.putFile(mainjavapath, files.getAllBytes(mainjavapath).toString().replace("n - 1", "n - 2")); 27 | res = runScriptTask("build"); 28 | assertNotEmpty(getMetric().getRunTaskIdResults()); 29 | testOptimization((SakerPath) res.getTargetTaskResult("path")); 30 | 31 | //make the file non-optimizable 32 | //test proper incremental operation 33 | files.putFile(mainjavapath, files.getAllBytes(mainjavapath).toString().replace("count(n - 2);", 34 | "count(n - 2);System.out.println();")); 35 | res = runScriptTask("build"); 36 | assertNotEmpty(getMetric().getRunTaskIdResults()); 37 | try { 38 | testOptimization((SakerPath) res.getTargetTaskResult("path")); 39 | fail("no stackoverflow caught"); 40 | } catch (StackOverflowError e) { 41 | //this is expected 42 | } 43 | } 44 | 45 | private void testOptimization(SakerPath outpath) throws Throwable { 46 | ClassLoaderDataFinder finder = null; 47 | try { 48 | finder = new SakerPathClassLoaderDataFinder(files, outpath); 49 | MultiDataClassLoader cl = new MultiDataClassLoader(finder); 50 | Class c = Class.forName("test.Main", false, cl); 51 | //this should succeed, as it was optimized 52 | c.getMethod("count", int.class).invoke(null, 10000000); 53 | } catch (InvocationTargetException e) { 54 | throw e.getCause(); 55 | } finally { 56 | if (finder != null) { 57 | finder.close(); 58 | } 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /test/src/testing/saker/sipka/jvm/tailrec/RepackageArchiveOptimizeSakerTest.java: -------------------------------------------------------------------------------- 1 | package testing.saker.sipka.jvm.tailrec; 2 | 3 | import java.io.InputStream; 4 | import java.util.Map; 5 | import java.util.TreeMap; 6 | import java.util.zip.ZipEntry; 7 | import java.util.zip.ZipInputStream; 8 | 9 | import saker.build.file.path.SakerPath; 10 | import saker.build.thirdparty.saker.util.classloader.ClassLoaderDataFinder; 11 | import saker.build.thirdparty.saker.util.classloader.MultiDataClassLoader; 12 | import saker.build.thirdparty.saker.util.io.ByteArrayRegion; 13 | import saker.build.thirdparty.saker.util.io.ByteSource; 14 | import saker.build.thirdparty.saker.util.io.ByteSourceInputStream; 15 | import saker.build.thirdparty.saker.util.io.StreamUtils; 16 | import testing.saker.SakerTest; 17 | import testing.saker.build.tests.TestUtils; 18 | import testing.saker.nest.util.NestRepositoryCachingEnvironmentTestCase; 19 | 20 | @SakerTest 21 | public class RepackageArchiveOptimizeSakerTest extends NestRepositoryCachingEnvironmentTestCase { 22 | 23 | @Override 24 | protected void runNestTaskTestImpl() throws Throwable { 25 | CombinedTargetTaskResult res = runScriptTask("build"); 26 | SakerPath outpath = (SakerPath) res.getTargetTaskResult("secondpath"); 27 | 28 | Map resourceBytes = new TreeMap(); 29 | InputStream is = null; 30 | try { 31 | is = new ByteSourceInputStream(files.openInput(outpath)); 32 | ZipInputStream zis = null; 33 | try { 34 | zis = new ZipInputStream(is); 35 | for (ZipEntry entry; (entry = zis.getNextEntry()) != null;) { 36 | resourceBytes.put(entry.getName(), StreamUtils.readStreamFully(zis)); 37 | } 38 | } finally { 39 | if (zis != null) { 40 | zis.close(); 41 | } 42 | } 43 | } finally { 44 | if (is != null) { 45 | is.close(); 46 | } 47 | } 48 | 49 | ClassLoaderDataFinder jarfinder = null; 50 | try { 51 | jarfinder = new TestUtils.MemoryClassLoaderDataFinder(resourceBytes); 52 | MultiDataClassLoader cl = new MultiDataClassLoader(jarfinder); 53 | Class c = Class.forName("test.Main", false, cl); 54 | //this should succeed, as it was optimized 55 | c.getMethod("count", int.class).invoke(null, 10000000); 56 | } finally { 57 | if (jarfinder != null) { 58 | jarfinder.close(); 59 | } 60 | } 61 | 62 | runScriptTask("build"); 63 | assertEmpty(getMetric().getRunTaskIdResults()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /test/src/testing/saker/sipka/jvm/tailrec/SimpleJarOptimizeSakerTest.java: -------------------------------------------------------------------------------- 1 | package testing.saker.sipka.jvm.tailrec; 2 | 3 | import java.io.InputStream; 4 | import java.util.Map; 5 | import java.util.TreeMap; 6 | import java.util.zip.ZipEntry; 7 | import java.util.zip.ZipInputStream; 8 | 9 | import saker.build.file.path.SakerPath; 10 | import saker.build.thirdparty.saker.util.classloader.ClassLoaderDataFinder; 11 | import saker.build.thirdparty.saker.util.classloader.MultiDataClassLoader; 12 | import saker.build.thirdparty.saker.util.io.ByteArrayRegion; 13 | import saker.build.thirdparty.saker.util.io.ByteSource; 14 | import saker.build.thirdparty.saker.util.io.ByteSourceInputStream; 15 | import saker.build.thirdparty.saker.util.io.StreamUtils; 16 | import testing.saker.SakerTest; 17 | import testing.saker.build.tests.TestUtils; 18 | import testing.saker.nest.util.NestRepositoryCachingEnvironmentTestCase; 19 | 20 | @SakerTest 21 | public class SimpleJarOptimizeSakerTest extends NestRepositoryCachingEnvironmentTestCase { 22 | 23 | @Override 24 | protected void runNestTaskTestImpl() throws Throwable { 25 | CombinedTargetTaskResult res = runScriptTask("build"); 26 | SakerPath outpath = (SakerPath) res.getTargetTaskResult("path"); 27 | 28 | Map resourceBytes = new TreeMap(); 29 | InputStream is = null; 30 | try { 31 | is = new ByteSourceInputStream(files.openInput(outpath)); 32 | ZipInputStream zis = null; 33 | try { 34 | zis = new ZipInputStream(is); 35 | for (ZipEntry entry; (entry = zis.getNextEntry()) != null;) { 36 | resourceBytes.put(entry.getName(), StreamUtils.readStreamFully(zis)); 37 | } 38 | } finally { 39 | if (zis != null) { 40 | zis.close(); 41 | } 42 | } 43 | } finally { 44 | if (is != null) { 45 | is.close(); 46 | } 47 | } 48 | 49 | ClassLoaderDataFinder jarfinder = null; 50 | try { 51 | jarfinder = new TestUtils.MemoryClassLoaderDataFinder(resourceBytes); 52 | MultiDataClassLoader cl = new MultiDataClassLoader(jarfinder); 53 | Class c = Class.forName("test.Main", false, cl); 54 | //this should succeed, as it was optimized 55 | c.getMethod("count", int.class).invoke(null, 10000000); 56 | } finally { 57 | if (jarfinder != null) { 58 | jarfinder.close(); 59 | } 60 | } 61 | 62 | runScriptTask("build"); 63 | assertEmpty(getMetric().getRunTaskIdResults()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /test/src/testing/saker/sipka/jvm/tailrec/SimpleZipOptimizeSakerTest.java: -------------------------------------------------------------------------------- 1 | package testing.saker.sipka.jvm.tailrec; 2 | 3 | import java.io.InputStream; 4 | import java.util.Map; 5 | import java.util.TreeMap; 6 | import java.util.zip.ZipEntry; 7 | import java.util.zip.ZipInputStream; 8 | 9 | import saker.build.file.path.SakerPath; 10 | import saker.build.thirdparty.saker.util.classloader.ClassLoaderDataFinder; 11 | import saker.build.thirdparty.saker.util.classloader.MultiDataClassLoader; 12 | import saker.build.thirdparty.saker.util.io.ByteArrayRegion; 13 | import saker.build.thirdparty.saker.util.io.ByteSource; 14 | import saker.build.thirdparty.saker.util.io.ByteSourceInputStream; 15 | import saker.build.thirdparty.saker.util.io.StreamUtils; 16 | import testing.saker.SakerTest; 17 | import testing.saker.build.tests.TestUtils; 18 | import testing.saker.nest.util.NestRepositoryCachingEnvironmentTestCase; 19 | 20 | @SakerTest 21 | public class SimpleZipOptimizeSakerTest extends NestRepositoryCachingEnvironmentTestCase { 22 | 23 | @Override 24 | protected void runNestTaskTestImpl() throws Throwable { 25 | CombinedTargetTaskResult res = runScriptTask("build"); 26 | SakerPath outpath = (SakerPath) res.getTargetTaskResult("path"); 27 | 28 | Map resourceBytes = new TreeMap(); 29 | InputStream is = null; 30 | try { 31 | is = new ByteSourceInputStream(files.openInput(outpath)); 32 | ZipInputStream zis = null; 33 | try { 34 | zis = new ZipInputStream(is); 35 | for (ZipEntry entry; (entry = zis.getNextEntry()) != null;) { 36 | resourceBytes.put(entry.getName(), StreamUtils.readStreamFully(zis)); 37 | } 38 | } finally { 39 | if (zis != null) { 40 | zis.close(); 41 | } 42 | } 43 | } finally { 44 | if (is != null) { 45 | is.close(); 46 | } 47 | } 48 | 49 | ClassLoaderDataFinder jarfinder = null; 50 | try { 51 | jarfinder = new TestUtils.MemoryClassLoaderDataFinder(resourceBytes); 52 | MultiDataClassLoader cl = new MultiDataClassLoader(jarfinder); 53 | Class c = Class.forName("test.Main", false, cl); 54 | //this should succeed, as it was optimized 55 | c.getMethod("count", int.class).invoke(null, 10000000); 56 | } finally { 57 | if (jarfinder != null) { 58 | jarfinder.close(); 59 | } 60 | } 61 | 62 | runScriptTask("build"); 63 | assertEmpty(getMetric().getRunTaskIdResults()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/AfterTryCatchTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class AfterTryCatchTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("trying", int.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static void trying(int n) throws Throwable { 17 | try { 18 | if (n == 0) { 19 | return; 20 | } 21 | } catch (Throwable e) { 22 | throw e; 23 | } 24 | trying(n - 1); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/ArrayAccessReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class ArrayAccessReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | optimizeClass(ArrayContainer.class); 12 | //the array access instruction has been optimized away 13 | assertSuccessfulOptimizationWithException(TestMethods.class.getMethod("count", int.class), 14 | NullPointerException.class, 1); 15 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 16 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 17 | } 18 | 19 | public static class ArrayContainer { 20 | public static Object[] o; 21 | } 22 | 23 | public static class TestMethods { 24 | 25 | public static int count(int n) { 26 | if (n == 0) { 27 | return 0; 28 | } 29 | int v = count(n - 1); 30 | Object x = ArrayContainer.o[3]; 31 | return v; 32 | } 33 | 34 | public static long count(long n) { 35 | if (n == 0) { 36 | return 0; 37 | } 38 | long v = count(n - 1); 39 | Object x = ArrayContainer.o[3]; 40 | return v; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/BeforeTryCatchTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class BeforeTryCatchTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("trying", int.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static void trying(int n) throws Throwable { 17 | if (n != 0) { 18 | trying(n - 1); 19 | return; 20 | } 21 | try { 22 | } catch (Throwable e) { 23 | throw e; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/CollectInterfacesTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.HashSet; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | import testing.saker.SakerTest; 8 | 9 | /** 10 | * As seen in the README. 11 | */ 12 | @SakerTest 13 | public class CollectInterfacesTest extends TailRecOptimizerTestCase { 14 | 15 | @Override 16 | public void runTest(Map parameters) throws Throwable { 17 | optimizeClass(MockClass.class); 18 | assertSuccessfulOptimization(TestMethods.class.getMethod("collect", int.class), 10000000); 19 | } 20 | 21 | public static class TestMethods { 22 | public static Set collect(int depth) { 23 | Set result = new HashSet(); 24 | collectInterfaces(new MockClass(depth), result); 25 | return result; 26 | } 27 | 28 | public static void collectInterfaces(MockClass clazz, Set result) { 29 | 30 | for (MockClass itf : clazz.getInterfaces()) { 31 | if (result.add(itf)) 32 | collectInterfaces(itf, result); 33 | } 34 | MockClass sclass = clazz.getSuperclass(); 35 | if (sclass != null) { 36 | collectInterfaces(sclass, result); 37 | 38 | } 39 | 40 | } 41 | } 42 | 43 | public static class MockClass { 44 | private int count; 45 | 46 | public MockClass(int count) { 47 | this.count = count; 48 | } 49 | 50 | public MockClass[] getInterfaces() { 51 | if (count == 0) { 52 | return new MockClass[0]; 53 | } 54 | MockClass[] result = new MockClass[count % 4]; 55 | for (int i = 0; i < result.length; i++) { 56 | result[i] = new MockClass((count - 1) % result.length); 57 | } 58 | return result; 59 | } 60 | 61 | public MockClass getSuperclass() { 62 | if (count == 0) { 63 | return null; 64 | } 65 | return new MockClass(count - 1); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return count; 71 | } 72 | 73 | @Override 74 | public boolean equals(Object obj) { 75 | if (this == obj) 76 | return true; 77 | if (obj == null) 78 | return false; 79 | if (getClass() != obj.getClass()) 80 | return false; 81 | MockClass other = (MockClass) obj; 82 | if (count != other.count) 83 | return false; 84 | return true; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | StringBuilder builder = new StringBuilder(); 90 | builder.append("MockClass[count="); 91 | builder.append(count); 92 | builder.append("]"); 93 | return builder.toString(); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/ConditionReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class ConditionReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static int count(int n) { 17 | if (n == 0) { 18 | return 0; 19 | } 20 | int v = count(n - 1); 21 | int k = 3; 22 | if (v == 0) { 23 | k += 3; 24 | } else { 25 | k *= 2; 26 | } 27 | return v; 28 | } 29 | 30 | public static long count(long n) { 31 | if (n == 0) { 32 | return 0; 33 | } 34 | long v = count(n - 1); 35 | long k = 3; 36 | if (v == 0) { 37 | k += 3; 38 | } else { 39 | k *= 2; 40 | } 41 | return v; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/CountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class CountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static void count(int n) { 17 | if (n == 0) { 18 | return; 19 | } 20 | count(n - 1); 21 | } 22 | 23 | public static void count(long n) { 24 | if (n == 0) { 25 | return; 26 | } 27 | count(n - 1); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/FactorialTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class FactorialTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("fact", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("fact", long.class), 10000000); 14 | } 15 | 16 | public static class TestMethods { 17 | public static int fact(int n) { 18 | return factImpl(n, 1); 19 | } 20 | 21 | private static int factImpl(int n, int acc) { 22 | if (n == 0) { 23 | return acc; 24 | } 25 | return factImpl(n - 1, acc * n); 26 | } 27 | 28 | public static long fact(long n) { 29 | return factImpl(n, 1); 30 | } 31 | 32 | private static long factImpl(long n, long acc) { 33 | if (n == 0) { 34 | return acc; 35 | } 36 | return factImpl(n - 1, acc * n); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/GetFieldReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class GetFieldReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | optimizeClass(Fielded.class); 12 | //the getfield instruction has been optimized away 13 | assertSuccessfulOptimizationWithException(TestMethods.class.getMethod("count", int.class, Fielded.class), 14 | NullPointerException.class, 1, null); 15 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class, Fielded.class), 10000000, null); 16 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class, Fielded.class), 10000000, null); 17 | } 18 | 19 | public static class Fielded { 20 | public Fielded o; 21 | } 22 | 23 | public static class TestMethods { 24 | 25 | public static int count(int n, Fielded m) { 26 | if (n == 0) { 27 | return 0; 28 | } 29 | int v = count(n - 1, m); 30 | Object x = m.o; 31 | return v; 32 | } 33 | 34 | public static long count(long n, Fielded m) { 35 | if (n == 0) { 36 | return 0; 37 | } 38 | long v = count(n - 1, m); 39 | Object x = m.o; 40 | return v; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/GetStaticReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class GetStaticReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | //the getstatic instruction has been optimized away, or else NoClassDefFoundError would be thrown 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 14 | } 15 | 16 | public static class Fielded { 17 | public static Fielded o; 18 | } 19 | 20 | public static class TestMethods { 21 | 22 | public static int count(int n) { 23 | if (n == 0) { 24 | return 0; 25 | } 26 | int v = count(n - 1); 27 | Fielded x = Fielded.o; 28 | return v; 29 | } 30 | 31 | public static long count(long n) { 32 | if (n == 0) { 33 | return 0; 34 | } 35 | long v = count(n - 1); 36 | Fielded x = Fielded.o; 37 | return v; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/IfElseFalseBranchTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class IfElseFalseBranchTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("counter", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("counter", long.class), 10000000); 14 | } 15 | 16 | public static class TestMethods { 17 | public static void counter(int n) { 18 | if (n == 0) { 19 | } else { 20 | counter(n - 1); 21 | } 22 | } 23 | 24 | public static void counter(long n) { 25 | if (n == 0) { 26 | } else { 27 | counter(n - 1); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/IfElseTrueBranchTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class IfElseTrueBranchTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("counter", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("counter", long.class), 10000000); 14 | } 15 | 16 | public static class TestMethods { 17 | public static void counter(int n) { 18 | if (n != 0) { 19 | counter(n - 1); 20 | } else { 21 | } 22 | } 23 | 24 | public static void counter(long n) { 25 | if (n != 0) { 26 | counter(n - 1); 27 | } else { 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/IfEndCountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class IfEndCountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("ifEndCount", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("ifEndCount", long.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static void ifEndCount(int n) { 17 | if (n != 0) { 18 | ifEndCount(n - 1); 19 | } 20 | } 21 | 22 | public static void ifEndCount(long n) { 23 | if (n != 0) { 24 | ifEndCount(n - 1); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/InstanceCountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class InstanceCountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("countInstance", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("countInstance", long.class), 10000000); 13 | 14 | assertSuccessfulOptimization(InstanceCounter.class.getMethod("countViaInstance", int.class), 10000000); 15 | } 16 | 17 | public static class TestMethods { 18 | public void countInstance(int n) { 19 | countInstanceImpl(n); 20 | } 21 | 22 | private void countInstanceImpl(int n) { 23 | if (n == 0) { 24 | return; 25 | } 26 | new TestMethods().countInstanceImpl(n - 1); 27 | } 28 | 29 | public void countInstance(long n) { 30 | countInstanceImpl(n); 31 | } 32 | 33 | private void countInstanceImpl(long n) { 34 | if (n == 0) { 35 | return; 36 | } 37 | new TestMethods().countInstanceImpl(n - 1); 38 | } 39 | } 40 | 41 | public static class InstanceCounter { 42 | private final int n; 43 | 44 | public InstanceCounter(int n) { 45 | this.n = n; 46 | } 47 | 48 | private void count() { 49 | if (n == 0) { 50 | return; 51 | } 52 | new InstanceCounter(n - 1).count(); 53 | } 54 | 55 | public static void countViaInstance(int n) { 56 | new InstanceCounter(n).count(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/InstanceOfModifyReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class InstanceOfModifyReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertNotOptimized(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 0); 13 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 1); 14 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 10); 15 | } 16 | 17 | public static class TestMethods { 18 | public static Object count(int n) { 19 | if (n == 0) { 20 | return "123"; 21 | } 22 | Object v = count(n - 1); 23 | if (v instanceof CharSequence) { 24 | v = ""; 25 | } 26 | return v; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/InstanceOfReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class InstanceOfReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 13 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 0); 14 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 1); 15 | assertOptimizationResultEquals(TestMethods.class.getMethod("count", int.class), 10); 16 | } 17 | 18 | public static class TestMethods { 19 | public static Object count(int n) { 20 | if (n == 0) { 21 | return "123"; 22 | } 23 | Object v = count(n - 1); 24 | if (v instanceof CharSequence) { 25 | String k = ""; 26 | } 27 | return v; 28 | } 29 | 30 | public static Object count(long n) { 31 | if (n == 0) { 32 | return "123"; 33 | } 34 | Object v = count(n - 1); 35 | if (v instanceof CharSequence) { 36 | String k = ""; 37 | } 38 | return v; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/LookupSwitchReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class LookupSwitchReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class, int.class), 10000000, 10); 12 | } 13 | 14 | public static class TestMethods { 15 | 16 | public static int count(int n, int sw) { 17 | if (n == 0) { 18 | return 0; 19 | } 20 | int v = count(n - 1, sw); 21 | switch (sw) { 22 | case Integer.MIN_VALUE: 23 | ++sw; 24 | break; 25 | case 1: 26 | --sw; 27 | break; 28 | case Integer.MAX_VALUE: 29 | sw += 3; 30 | break; 31 | default: 32 | sw += 4; 33 | break; 34 | } 35 | return v; 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/LoopReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class LoopReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static int count(int n) { 17 | if (n == 0) { 18 | return 0; 19 | } 20 | int v = count(n - 1); 21 | for (int i = 0; i < 10; i++) { 22 | 23 | } 24 | return v; 25 | } 26 | 27 | public static long count(long n) { 28 | if (n == 0) { 29 | return 0; 30 | } 31 | long v = count(n - 1); 32 | for (int i = 0; i < 10; i++) { 33 | 34 | } 35 | return v; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/MiscMethodsTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class MiscMethodsTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("doubleCount", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("doubleCount", long.class), 10000000); 14 | } 15 | 16 | public static class TestMethods { 17 | public static void doubleCount(int n) { 18 | if (n == 0) { 19 | return; 20 | } 21 | for (int i = 0; i < 2; i++) { 22 | --n; 23 | } 24 | doubleCount(n); 25 | } 26 | 27 | public static void doubleCount(long n) { 28 | if (n == 0) { 29 | return; 30 | } 31 | for (long i = 0; i < 2; i++) { 32 | --n; 33 | } 34 | doubleCount(n); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/MultiVariableCounterFactorialTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class MultiVariableCounterFactorialTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("multiVarCount", int.class), 10000000); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("multiVarCountDiff", int.class), 10000000); 14 | 15 | assertSuccessfulOptimization(TestMethods.class.getMethod("multiVarCount", long.class), 10000000); 16 | assertSuccessfulOptimization(TestMethods.class.getMethod("multiVarCountDiff", long.class), 10000000); 17 | } 18 | 19 | public static class TestMethods { 20 | public static int multiVarCount(int n) { 21 | if (n == 0) { 22 | return 0; 23 | } 24 | int v1 = multiVarCount(n - 1); 25 | int v2 = v1; 26 | return v2; 27 | } 28 | 29 | public static int multiVarCountDiff(int n) { 30 | if (n == 0) { 31 | return 0; 32 | } 33 | int v1 = multiVarCountDiff(n - 1); 34 | int v2 = v1; 35 | return v1; 36 | } 37 | 38 | public static long multiVarCount(long n) { 39 | if (n == 0) { 40 | return 0; 41 | } 42 | long v1 = multiVarCount(n - 1); 43 | long v2 = v1; 44 | return v2; 45 | } 46 | 47 | public static long multiVarCountDiff(long n) { 48 | if (n == 0) { 49 | return 0; 50 | } 51 | long v1 = multiVarCountDiff(n - 1); 52 | long v2 = v1; 53 | return v1; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/NewArrayReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class NewArrayReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimizationWithException(TestMethods.class.getMethod("count", int.class), 12 | OutOfMemoryError.class, 1); 13 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class), 10000000); 14 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", long.class), 10000000); 15 | } 16 | 17 | public static class Fielded { 18 | public static Fielded o; 19 | } 20 | 21 | public static class TestMethods { 22 | 23 | public static int count(int n) { 24 | if (n == 0) { 25 | return 0; 26 | } 27 | int v = count(n - 1); 28 | Object a = new long[Integer.MAX_VALUE]; 29 | Object b = new int[10][20]; 30 | Object c = new Object[10]; 31 | Object d = new Object[10][20]; 32 | return v; 33 | } 34 | 35 | public static long count(long n) { 36 | if (n == 0) { 37 | return 0; 38 | } 39 | long v = count(n - 1); 40 | Object a = new long[Integer.MAX_VALUE]; 41 | Object b = new int[10][20]; 42 | Object c = new Object[10]; 43 | Object d = new Object[10][20]; 44 | return v; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/NumberConcatTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class NumberConcatTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("numbers", int.class, String.class), 20000, ""); 13 | } 14 | 15 | public static class TestMethods { 16 | public static String numbers(int n, String s) { 17 | if (n == 0) { 18 | return s + "0"; 19 | } 20 | return numbers(n - 1, s + n + ","); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/OptimizationImplEdgeCasesTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | /** 8 | * Just tests that the optimization doesn't crash for some edge cases. 9 | */ 10 | @SakerTest 11 | public class OptimizationImplEdgeCasesTest extends TailRecOptimizerTestCase { 12 | 13 | @Override 14 | public void runTest(Map parameters) throws Throwable { 15 | optimizeClass(TestMethods.class); 16 | assertNotOptimized(TestMethods.class.getMethod("whileStartCount", int.class), 1000000); 17 | } 18 | 19 | public static class TestMethods { 20 | public TestMethods() { 21 | } 22 | 23 | public TestMethods(int i) { 24 | this(); 25 | } 26 | 27 | static { 28 | System.out.println("OptimizationImplEdgeCasesTest.TestMethods.()"); 29 | } 30 | 31 | public static void infloop() { 32 | infloop(); 33 | while (true) { 34 | } 35 | } 36 | 37 | public static void trySynchronized() { 38 | try { 39 | synchronized (TestMethods.class) { 40 | System.out.println("trySynchronized()"); 41 | } 42 | } catch (Exception e) { 43 | } 44 | } 45 | 46 | public static void mixedArguments(int i, long l, double d, boolean b, short s) { 47 | ++i; 48 | ++l; 49 | ++d; 50 | b = !b; 51 | ++s; 52 | mixedArguments(i, l, d, b, s); 53 | } 54 | 55 | public final void mixedInstanceArguments(int i, long l, double d, boolean b, short s) { 56 | ++i; 57 | ++l; 58 | ++d; 59 | b = !b; 60 | ++s; 61 | mixedArguments(i, l, d, b, s); 62 | } 63 | 64 | public static int whileStartCount(int n) { 65 | while (true) { 66 | if (n == 0) { 67 | break; 68 | } 69 | whileStartCount(n - 1); 70 | } 71 | if (n == 0) { 72 | return 0; 73 | } 74 | return whileStartCount(n - 1); 75 | } 76 | 77 | //TODO these methods could be optimizable, as the lock is loaded with LDC 78 | public static void insynchCount(int n) { 79 | synchronized (TestMethods.class) { 80 | if (n == 0) { 81 | return; 82 | } 83 | insynchCount(n - 1); 84 | return; 85 | } 86 | } 87 | 88 | public static void insynchCount(long n) { 89 | synchronized (TestMethods.class) { 90 | if (n == 0) { 91 | return; 92 | } 93 | insynchCount(n - 1); 94 | return; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/OutsideSynchronizedCountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class OutsideSynchronizedCountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("outsynchCount", int.class), 10000000); 12 | assertSuccessfulOptimization(TestMethods.class.getMethod("outsynchCount", long.class), 10000000); 13 | } 14 | 15 | public static class TestMethods { 16 | public static void outsynchCount(int n) { 17 | synchronized (TestMethods.class) { 18 | if (n == 0) { 19 | return; 20 | } 21 | } 22 | outsynchCount(n - 1); 23 | } 24 | 25 | public static void outsynchCount(long n) { 26 | synchronized (TestMethods.class) { 27 | if (n == 0) { 28 | return; 29 | } 30 | } 31 | outsynchCount(n - 1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/TableSwitchReturnPathTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class TableSwitchReturnPathTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("count", int.class, int.class), 10000000, 10); 12 | } 13 | 14 | public static class TestMethods { 15 | 16 | public static int count(int n, int sw) { 17 | if (n == 0) { 18 | return 0; 19 | } 20 | int v = count(n - 1, sw); 21 | switch (sw) { 22 | case 0: 23 | ++sw; 24 | break; 25 | case 1: 26 | --sw; 27 | break; 28 | case 2: 29 | sw += 3; 30 | break; 31 | default: 32 | sw += 4; 33 | break; 34 | } 35 | return v; 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/TypeCastCountTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class TypeCastCountTest extends TailRecOptimizerTestCase { 9 | @Override 10 | public void runTest(Map parameters) throws Throwable { 11 | assertSuccessfulOptimization(TestMethods.class.getMethod("castingCount", int.class), 10000000); 12 | } 13 | 14 | public static class TestMethods { 15 | public static CharSequence castingCount(int n) { 16 | if (n == 0) { 17 | return ""; 18 | } 19 | String v = (String) castingCount(n - 1); 20 | return v; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/testing/sipka/jvm/tailrec/VariableCounterTest.java: -------------------------------------------------------------------------------- 1 | package testing.sipka.jvm.tailrec; 2 | 3 | import java.util.Map; 4 | 5 | import testing.saker.SakerTest; 6 | 7 | @SakerTest 8 | public class VariableCounterTest extends TailRecOptimizerTestCase { 9 | 10 | @Override 11 | public void runTest(Map parameters) throws Throwable { 12 | callMethodsWithArgType(int.class); 13 | callMethodsWithArgType(long.class); 14 | } 15 | 16 | private void callMethodsWithArgType(Class t) throws Throwable, NoSuchMethodException { 17 | assertSuccessfulOptimization(TestMethods.class.getMethod("varCount1", t), 10000000); 18 | assertSuccessfulOptimization(TestMethods.class.getMethod("varCount2", t), 10000000); 19 | assertSuccessfulOptimization(TestMethods.class.getMethod("varCount3", t), 10000000); 20 | assertSuccessfulOptimization(TestMethods.class.getMethod("varCount4", t), 10000000); 21 | assertSuccessfulOptimization(TestMethods.class.getMethod("varCount5", t), 10000000); 22 | } 23 | 24 | public static class TestMethods { 25 | public static int varCount1(int n) { 26 | if (n == 0) { 27 | return 0; 28 | } 29 | int v = varCount1(n - 1); 30 | return v; 31 | } 32 | 33 | public static int varCount2(int n) { 34 | int v = n == 0 ? 0 : varCount2(n - 1); 35 | return v; 36 | } 37 | 38 | public static int varCount3(int n) { 39 | int v = n != 0 ? varCount3(n - 1) : 0; 40 | return v; 41 | } 42 | 43 | public static int varCount4(int n) { 44 | int v; 45 | if (n == 0) { 46 | v = 0; 47 | } else { 48 | v = varCount4(n - 1); 49 | } 50 | return v; 51 | } 52 | 53 | public static int varCount5(int n) { 54 | int v; 55 | if (n != 0) { 56 | v = varCount5(n - 1); 57 | } else { 58 | v = 0; 59 | } 60 | return v; 61 | } 62 | 63 | public static long varCount1(long n) { 64 | if (n == 0) { 65 | return 0; 66 | } 67 | long v = varCount1(n - 1); 68 | return v; 69 | } 70 | 71 | public static long varCount2(long n) { 72 | long v = n == 0 ? 0 : varCount2(n - 1); 73 | return v; 74 | } 75 | 76 | public static long varCount3(long n) { 77 | long v = n != 0 ? varCount3(n - 1) : 0; 78 | return v; 79 | } 80 | 81 | public static long varCount4(long n) { 82 | long v; 83 | if (n == 0) { 84 | v = 0; 85 | } else { 86 | v = varCount4(n - 1); 87 | } 88 | return v; 89 | } 90 | 91 | public static long varCount5(long n) { 92 | long v; 93 | if (n != 0) { 94 | v = varCount5(n - 1); 95 | } else { 96 | v = 0; 97 | } 98 | return v; 99 | } 100 | } 101 | } 102 | --------------------------------------------------------------------------------