summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--META-INF/MANIFEST.MF7
-rw-r--r--README.rst1
-rw-r--r--build.detach.xml8
-rw-r--r--build.examples.xml29
-rw-r--r--build.xml205
-rw-r--r--lib/fjbg.jar.desired.sha11
-rw-r--r--lib/msil.jar.desired.sha11
-rw-r--r--project/Build.scala40
-rw-r--r--project/Layers.scala14
-rw-r--r--project/Packaging.scala2
-rw-r--r--project/Testing.scala10
-rw-r--r--src/asm/scala/tools/asm/AnnotationVisitor.java66
-rw-r--r--src/asm/scala/tools/asm/AnnotationWriter.java58
-rw-r--r--src/asm/scala/tools/asm/Attribute.java193
-rw-r--r--src/asm/scala/tools/asm/ByteVector.java49
-rw-r--r--src/asm/scala/tools/asm/ClassReader.java2980
-rw-r--r--src/asm/scala/tools/asm/ClassVisitor.java233
-rw-r--r--src/asm/scala/tools/asm/ClassWriter.java499
-rw-r--r--src/asm/scala/tools/asm/Context.java110
-rw-r--r--src/asm/scala/tools/asm/FieldVisitor.java34
-rw-r--r--src/asm/scala/tools/asm/FieldWriter.java72
-rw-r--r--src/asm/scala/tools/asm/Frame.java1024
-rw-r--r--src/asm/scala/tools/asm/Handle.java48
-rw-r--r--src/asm/scala/tools/asm/Handler.java9
-rw-r--r--src/asm/scala/tools/asm/Item.java162
-rw-r--r--src/asm/scala/tools/asm/Label.java135
-rw-r--r--src/asm/scala/tools/asm/MethodVisitor.java516
-rw-r--r--src/asm/scala/tools/asm/MethodWriter.java1165
-rw-r--r--src/asm/scala/tools/asm/Type.java254
-rw-r--r--src/asm/scala/tools/asm/signature/SignatureReader.java181
-rw-r--r--src/asm/scala/tools/asm/signature/SignatureVisitor.java51
-rw-r--r--src/asm/scala/tools/asm/signature/SignatureWriter.java2
-rw-r--r--src/asm/scala/tools/asm/tree/AbstractInsnNode.java30
-rw-r--r--src/asm/scala/tools/asm/tree/AnnotationNode.java55
-rw-r--r--src/asm/scala/tools/asm/tree/ClassNode.java102
-rw-r--r--src/asm/scala/tools/asm/tree/FieldInsnNode.java34
-rw-r--r--src/asm/scala/tools/asm/tree/FieldNode.java104
-rw-r--r--src/asm/scala/tools/asm/tree/FrameNode.java121
-rw-r--r--src/asm/scala/tools/asm/tree/IincInsnNode.java8
-rw-r--r--src/asm/scala/tools/asm/tree/InnerClassNode.java42
-rw-r--r--src/asm/scala/tools/asm/tree/InsnList.java120
-rw-r--r--src/asm/scala/tools/asm/tree/InsnNode.java33
-rw-r--r--src/asm/scala/tools/asm/tree/IntInsnNode.java13
-rw-r--r--src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java22
-rw-r--r--src/asm/scala/tools/asm/tree/JumpInsnNode.java25
-rw-r--r--src/asm/scala/tools/asm/tree/LabelNode.java2
-rw-r--r--src/asm/scala/tools/asm/tree/LdcInsnNode.java11
-rw-r--r--src/asm/scala/tools/asm/tree/LineNumberNode.java8
-rw-r--r--src/asm/scala/tools/asm/tree/LocalVariableNode.java45
-rw-r--r--src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java21
-rw-r--r--src/asm/scala/tools/asm/tree/MethodInsnNode.java38
-rw-r--r--src/asm/scala/tools/asm/tree/MethodNode.java236
-rw-r--r--src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java10
-rw-r--r--src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java30
-rw-r--r--src/asm/scala/tools/asm/tree/TryCatchBlockNode.java32
-rw-r--r--src/asm/scala/tools/asm/tree/TypeInsnNode.java19
-rw-r--r--src/asm/scala/tools/asm/tree/VarInsnNode.java21
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/Analyzer.java160
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java11
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java483
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/BasicValue.java9
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java598
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/Frame.java854
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/Interpreter.java110
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java119
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java148
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/SourceValue.java8
-rw-r--r--src/asm/scala/tools/asm/tree/analysis/Subroutine.java9
-rw-r--r--src/asm/scala/tools/asm/util/ASMifiable.java13
-rw-r--r--src/asm/scala/tools/asm/util/ASMifier.java485
-rw-r--r--src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java28
-rw-r--r--src/asm/scala/tools/asm/util/CheckClassAdapter.java587
-rw-r--r--src/asm/scala/tools/asm/util/CheckFieldAdapter.java23
-rw-r--r--src/asm/scala/tools/asm/util/CheckMethodAdapter.java937
-rw-r--r--src/asm/scala/tools/asm/util/CheckSignatureAdapter.java57
-rw-r--r--src/asm/scala/tools/asm/util/Printer.java316
-rw-r--r--src/asm/scala/tools/asm/util/SignatureChecker.java47
-rw-r--r--src/asm/scala/tools/asm/util/Textifiable.java8
-rw-r--r--src/asm/scala/tools/asm/util/Textifier.java446
-rw-r--r--src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java23
-rw-r--r--src/asm/scala/tools/asm/util/TraceClassVisitor.java159
-rw-r--r--src/asm/scala/tools/asm/util/TraceFieldVisitor.java10
-rw-r--r--src/asm/scala/tools/asm/util/TraceMethodVisitor.java89
-rw-r--r--src/asm/scala/tools/asm/util/TraceSignatureVisitor.java59
-rw-r--r--src/compiler/scala/reflect/reify/Errors.scala8
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala8
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala131
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala35
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala4
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala6
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala15
-rw-r--r--src/compiler/scala/tools/ant/sabbus/ScalacFork.scala5
-rw-r--r--src/compiler/scala/tools/ant/sabbus/TaskArgs.scala2
-rw-r--r--src/compiler/scala/tools/ant/templates/tool-unix.tmpl3
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala20
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala5
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala25
-rw-r--r--src/compiler/scala/tools/nsc/Main.scala7
-rw-r--r--src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ScalaDoc.scala9
-rw-r--r--src/compiler/scala/tools/nsc/ast/Positions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala27
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala24
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala33
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala86
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala22
-rw-r--r--src/compiler/scala/tools/nsc/backend/JavaPlatform.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/MSILPlatform.scala69
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala272
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala138
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala69
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala31
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala97
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala62
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala1950
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala97
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala141
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala2244
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala47
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala21
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala11
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala8
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ISettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Naming.scala12
-rw-r--r--src/compiler/scala/tools/nsc/io/MsilFile.scala15
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala4
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala19
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala132
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala849
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala34
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala42
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala55
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala54
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala48
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala46
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala105
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala550
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala3
-rw-r--r--src/compiler/scala/tools/nsc/util/MsilClassPath.scala166
-rw-r--r--src/compiler/scala/tools/nsc/util/SimpleTracer.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala5
-rw-r--r--src/compiler/scala/tools/util/Javap.scala493
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala2
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala2
-rw-r--r--src/eclipse/README.md2
-rw-r--r--src/eclipse/continuations-library/.classpath8
-rw-r--r--src/eclipse/continuations-library/.project (renamed from src/eclipse/fjbg/.project)10
-rw-r--r--src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs2
-rw-r--r--src/eclipse/fjbg/.classpath7
-rw-r--r--src/eclipse/partest/.classpath2
-rw-r--r--src/eclipse/reflect/.classpath1
-rw-r--r--src/eclipse/scala-compiler/.classpath3
-rw-r--r--src/eclipse/scalap/.classpath2
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java195
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java35
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java62
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java84
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java101
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JClass.java420
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JCode.java1308
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java125
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java377
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java771
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java69
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java83
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java90
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java667
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JField.java62
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java138
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java201
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JLabel.java30
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java121
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java42
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java167
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JMember.java109
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JMethod.java199
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java87
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java65
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java1267
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java77
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java19
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java69
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java282
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JType.java316
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/Main.java131
-rw-r--r--src/fjbg/ch/epfl/lamp/util/ByteArray.java145
-rw-r--r--src/intellij/compiler.iml.SAMPLE2
-rw-r--r--src/intellij/fjbg.iml.SAMPLE12
-rw-r--r--src/intellij/msil.iml.SAMPLE24
-rw-r--r--src/intellij/scala-lang.ipr.SAMPLE3
-rw-r--r--src/intellij/test.iml.SAMPLE2
-rw-r--r--src/library/scala/SerialVersionUID.scala2
-rw-r--r--src/library/scala/StringContext.scala13
-rw-r--r--src/library/scala/Symbol.scala5
-rw-r--r--src/library/scala/collection/SeqLike.scala2
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala3
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala5
-rw-r--r--src/library/scala/collection/immutable/Range.scala1
-rw-r--r--src/library/scala/collection/mutable/FlatHashTable.scala13
-rw-r--r--src/library/scala/collection/mutable/MutableList.scala10
-rw-r--r--src/library/scala/collection/mutable/Queue.scala28
-rw-r--r--src/library/scala/util/Random.scala2
-rw-r--r--src/manual/scala/man1/scalac.scala24
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Assembly.java253
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/AssemblyName.java96
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Attribute.java654
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/BindingFlags.java169
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/CallingConventions.java75
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/ConstructedType.java48
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/ConstructorInfo.java54
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/CustomAttributeProvider.java82
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/CustomModifier.java45
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/EventAttributes.java32
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/EventInfo.java58
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/FieldAttributes.java119
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/FieldInfo.java141
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/GenericParamAndConstraints.java40
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/HasCustomModifiers.java9
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/ICustomAttributeProvider.java57
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MemberInfo.java47
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MemberTypes.java81
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MethodAttributes.java158
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MethodBase.java198
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MethodImplAttributes.java116
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/MethodInfo.java69
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Module.java155
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PEAssembly.java69
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PEFile.java941
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PEModule.java456
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PEType.java419
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/ParameterAttributes.java72
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/ParameterInfo.java76
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PrimitiveType.java62
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PropertyAttributes.java45
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/PropertyInfo.java104
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Type.java1142
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/TypeAttributes.java190
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Version.java71
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/AssemblyBuilder.scala122
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ConstructorBuilder.scala64
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/FieldBuilder.scala60
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ICustomAttributeSetter.scala18
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala539
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ILPrinterVisitor.scala860
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/Label.scala147
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/LocalBuilder.scala44
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/MethodBuilder.scala70
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ModuleBuilder.scala136
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/MultipleFilesILPrinterVisitor.scala137
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/OpCode.scala1948
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/OpCodes.scala1205
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/ParameterBuilder.scala44
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/SingleFileILPrinterVisitor.scala93
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/TypeBuilder.scala261
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/Visitable.scala24
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/emit/Visitor.scala58
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/tests/CustomAttributesTest.java31
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/tests/JavaTypeTest.java18
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/tests/MembersTest.java100
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/tests/TableDump.java311
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/tests/Test.java92
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/PECustomMod.java23
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/PESection.java57
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java199
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/Signature.java129
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/Table.java1859
-rw-r--r--src/partest/scala/tools/partest/CompilerTest.scala2
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleFileManager.scala5
-rw-r--r--src/partest/scala/tools/partest/nest/ReflectiveRunner.scala4
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala103
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala62
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala21
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala6
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala94
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala18
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala5
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala177
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala49
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/UnCurry.scala3
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala3
-rw-r--r--src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala40
-rw-r--r--src/reflect/scala/reflect/internal/util/package.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala21
-rw-r--r--test/attic/files/cli/test1/Main.check.scalac6
-rw-r--r--test/attic/files/cli/test2/Main.check.scalac6
-rw-r--r--test/attic/files/cli/test3/Main.check.scalac6
-rw-r--r--test/disabled/presentation/akka.flags4
-rw-r--r--test/disabled/presentation/simple-tests.opts4
-rw-r--r--test/files/ant/imported.xml5
-rw-r--r--test/files/jvm/serialization.scala15
-rw-r--r--test/files/neg/anyval-anyref-parent.check2
-rw-r--r--test/files/neg/case-collision.check12
-rw-r--r--test/files/neg/case-collision.flags1
-rw-r--r--test/files/neg/case-collision.scala11
-rw-r--r--test/files/neg/cyclics-import.check11
-rw-r--r--test/files/neg/gadts1.check4
-rw-r--r--test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala4
-rw-r--r--test/files/neg/names-defaults-neg.check2
-rw-r--r--test/files/neg/protected-constructors.check5
-rw-r--r--test/files/neg/serialversionuid-not-const.check10
-rw-r--r--test/files/neg/serialversionuid-not-const.scala16
-rw-r--r--test/files/neg/t1672b.check16
-rw-r--r--test/files/neg/t1672b.scala52
-rw-r--r--test/files/neg/t2148.check2
-rw-r--r--test/files/neg/t409.check4
-rw-r--r--test/files/neg/t5529.check5
-rw-r--r--test/files/neg/t5696.check2
-rw-r--r--test/files/neg/t5753.check4
-rw-r--r--test/files/neg/t5753.flags1
-rw-r--r--test/files/neg/t5753/Impls$class.classbin0 -> 626 bytes
-rw-r--r--test/files/neg/t5753/Impls.classbin0 -> 866 bytes
-rw-r--r--test/files/neg/t5753/Impls_Macros_1.scala6
-rw-r--r--test/files/neg/t5753/Test_2.scala11
-rw-r--r--test/files/neg/t6535.check6
-rw-r--r--test/files/neg/t6535.scala15
-rw-r--r--test/files/neg/t6558.check10
-rw-r--r--test/files/neg/t6558.scala27
-rw-r--r--test/files/neg/t6558b.check7
-rw-r--r--test/files/neg/t6558b.scala15
-rw-r--r--test/files/neg/t6667.check13
-rw-r--r--test/files/neg/t6667.scala10
-rw-r--r--test/files/neg/t6667b.check13
-rw-r--r--test/files/neg/t6667b.scala25
-rw-r--r--test/files/neg/t667.check4
-rw-r--r--test/files/neg/t877.check4
-rw-r--r--test/files/pos/t1672.scala10
-rw-r--r--test/files/pos/t5726.scala17
-rw-r--r--test/files/pos/t5858.scala3
-rw-r--r--test/files/pos/t5877.scala14
-rw-r--r--test/files/pos/t5877b.scala13
-rw-r--r--test/files/pos/t6547.flags1
-rw-r--r--test/files/pos/t6547.scala6
-rw-r--r--test/files/pos/t6551.scala2
-rw-r--r--test/files/pos/t6595.flags1
-rw-r--r--test/files/pos/t6595.scala18
-rw-r--r--test/files/pos/t6712.scala5
-rw-r--r--test/files/pos/t6722.scala11
-rw-r--r--test/files/run/idempotency-case-classes.check52
-rw-r--r--test/files/run/idempotency-case-classes.scala22
-rw-r--r--test/files/run/idempotency-extractors.check5
-rw-r--r--test/files/run/idempotency-extractors.scala22
-rw-r--r--test/files/run/idempotency-labels.check15
-rw-r--r--test/files/run/idempotency-labels.scala22
-rw-r--r--test/files/run/idempotency-lazy-vals.check23
-rw-r--r--test/files/run/idempotency-lazy-vals.scala27
-rw-r--r--test/files/run/idempotency-partial-functions.check2
-rw-r--r--test/files/run/idempotency-partial-functions.scala25
-rw-r--r--test/files/run/idempotency-this.check4
-rw-r--r--test/files/run/idempotency-this.scala22
-rw-r--r--test/files/run/macro-abort-fresh/Test_2.scala2
-rw-r--r--test/files/run/macro-declared-in-class-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-class-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-declared-in-method/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object-class/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-package-object/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-refinement/Impls_1.scala2
-rw-r--r--test/files/run/macro-declared-in-trait/Impls_1.scala2
-rw-r--r--test/files/run/macro-def-infer-return-type-b/Test_2.scala2
-rw-r--r--test/files/run/macro-expand-implicit-argument/Macros_1.scala8
-rw-r--r--test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala2
-rw-r--r--test/files/run/macro-impl-default-params/Impls_Macros_1.scala4
-rw-r--r--test/files/run/macro-impl-rename-context/Impls_Macros_1.scala4
-rw-r--r--test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala2
-rw-r--r--test/files/run/macro-invalidret-nontypeable/Test_2.scala4
-rw-r--r--test/files/run/macro-invalidusage-badret/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala2
-rw-r--r--test/files/run/macro-invalidusage-partialapplication/Test_2.scala2
-rw-r--r--test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala2
-rw-r--r--test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala6
-rw-r--r--test/files/run/macro-reify-freevars/Test_2.scala4
-rw-r--r--test/files/run/macro-reify-splice-outside-reify/Test_2.scala2
-rw-r--r--test/files/run/macro-reify-tagless-a/Test_2.scala4
-rw-r--r--test/files/run/reify_renamed_term_basic.check1
-rw-r--r--test/files/run/reify_renamed_term_basic.scala20
-rw-r--r--test/files/run/reify_renamed_term_local_to_reifee.check1
-rw-r--r--test/files/run/reify_renamed_term_local_to_reifee.scala20
-rw-r--r--test/files/run/reify_renamed_term_overloaded_method.check1
-rw-r--r--test/files/run/reify_renamed_term_overloaded_method.scala17
-rw-r--r--test/files/run/reify_renamed_term_si5841.check1
-rw-r--r--test/files/run/reify_renamed_term_si5841.scala7
-rw-r--r--test/files/run/reify_renamed_type_basic.check1
-rw-r--r--test/files/run/reify_renamed_type_basic.scala16
-rw-r--r--test/files/run/reify_renamed_type_local_to_reifee.check1
-rw-r--r--test/files/run/reify_renamed_type_local_to_reifee.scala24
-rw-r--r--test/files/run/reify_renamed_type_spliceable.check1
-rw-r--r--test/files/run/reify_renamed_type_spliceable.scala21
-rw-r--r--test/files/run/showraw_aliases.check4
-rw-r--r--test/files/run/showraw_aliases.scala6
-rw-r--r--test/files/run/sm-interpolator.scala41
-rw-r--r--test/files/run/t0091.check1
-rw-r--r--test/files/run/t0091.scala15
-rw-r--r--test/files/run/t1672.scala28
-rw-r--r--test/files/run/t5064.check6
-rw-r--r--test/files/run/t5374.check3
-rw-r--r--test/files/run/t5374.scala46
-rw-r--r--test/files/run/t5603.check4
-rw-r--r--test/files/run/t5733.check2
-rw-r--r--test/files/run/t5733.scala53
-rw-r--r--test/files/run/t5753_1.check1
-rw-r--r--test/files/run/t5753_1.flags1
-rw-r--r--test/files/run/t5753_1/Impls_Macros_1.scala10
-rw-r--r--test/files/run/t5753_1/Test_2.scala4
-rw-r--r--test/files/run/t5753_2.check1
-rw-r--r--test/files/run/t5753_2.flags1
-rw-r--r--test/files/run/t5753_2/Impls_Macros_1.scala10
-rw-r--r--test/files/run/t5753_2/Test_2.scala4
-rw-r--r--test/files/run/t5789.check14
-rw-r--r--test/files/run/t5789.scala14
-rw-r--r--test/files/run/t5894.scala17
-rw-r--r--test/files/run/t6320.check17
-rw-r--r--test/files/run/t6320.scala9
-rw-r--r--test/files/run/t6549.check32
-rw-r--r--test/files/run/t6549.scala22
-rw-r--r--test/files/run/t6614.check11
-rw-r--r--test/files/run/t6614.scala8
-rw-r--r--test/files/run/t6631.scala18
-rw-r--r--test/files/run/t6677.scala28
-rw-r--r--test/files/run/t6677b.scala33
-rw-r--r--test/files/run/t6687.scala10
-rw-r--r--test/files/run/t6690.scala62
-rw-r--r--test/files/run/t6706.scala14
-rw-r--r--test/files/run/t6731.check40
-rw-r--r--test/files/run/t6731.scala143
-rw-r--r--test/files/run/t6745-2.scala22
-rw-r--r--test/files/run/toolbox_typecheck_implicitsdisabled.scala8
-rw-r--r--test/pending/jvm/cf-attributes.scala26
-rw-r--r--test/pending/run/macro-reify-tagless-b/Test_2.scala2
-rw-r--r--test/postreview.py2540
-rwxr-xr-xtest/review44
-rw-r--r--test/scaladoc/run/t4922.check1
-rw-r--r--test/scaladoc/run/t4922.scala32
-rwxr-xr-xtools/buildcp2
-rwxr-xr-xtools/strapcp3
478 files changed, 11042 insertions, 40903 deletions
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
index 28a70d2879..4dd69827c3 100644
--- a/META-INF/MANIFEST.MF
+++ b/META-INF/MANIFEST.MF
@@ -7,9 +7,7 @@ Eclipse-LazyStart: true
Bundle-ClassPath:
.,
bin,
- lib/fjbg.jar,
lib/jline.jar,
- lib/msil.jar
Export-Package:
scala.tools.nsc,
scala.tools.nsc.ast,
@@ -47,11 +45,6 @@ Export-Package:
scala.reflect.runtime,
scala.reflect.internal.transform,
scala.reflect.api,
- ch.epfl.lamp.compiler.msil,
- ch.epfl.lamp.compiler.msil.emit,
- ch.epfl.lamp.compiler.msil.util,
- ch.epfl.lamp.fjbg,
- ch.epfl.lamp.util
Require-Bundle:
org.apache.ant,
org.scala-ide.scala.library
diff --git a/README.rst b/README.rst
index 72c4b6028b..7a1ed1dcf4 100644
--- a/README.rst
+++ b/README.rst
@@ -18,7 +18,6 @@ build script or user-created if needed. This is not a complete listing. ::
+--dist/ The destination folder for Scala distributions.
+--docs/ Documentation and sample code.
+--lib/ Pre-compiled libraries for the build.
- | +--fjbg.jar The Java byte-code generation library.
| +--scala-compiler.jar The stable reference ('starr') compiler jar
| +--scala-library.jar The stable reference ('starr') library jar
| +--scala-library-src.jar A snapshot of the source used to build starr.
diff --git a/build.detach.xml b/build.detach.xml
index 132c812a26..03360e36d5 100644
--- a/build.detach.xml
+++ b/build.detach.xml
@@ -11,7 +11,7 @@ SuperSabbus for Scala detach plugin.
<!-- ===========================================================================
END-USER TARGETS
============================================================================ -->
-
+
<target name="build" depends="pack.done"
description="Builds the Scala detach plugin."/>
@@ -72,8 +72,6 @@ QUICK BUILD (QUICK)
<path id="quick.classpath">
<pathelement location="${build-quick.dir}/classes/library"/>
<pathelement location="${build-quick.dir}/classes/compiler"/>
- <pathelement location="${lib.dir}/fjbg.jar"/>
- <pathelement location="${lib.dir}/msil.jar"/>
<pathelement location="${lib.dir}/forkjoin.jar"/>
<pathelement location="${ant.home}/lib/ant.jar"/>
</path>
@@ -120,9 +118,9 @@ QUICK BUILD (QUICK)
<!-- ===========================================================================
PACKED QUICK BUILD (PACK)
============================================================================ -->
-
+
<target name="pack.start" depends="quick.done"/>
-
+
<target name="pack.pre-lib" depends="pack.start">
<uptodate
property="pack.lib.available"
diff --git a/build.examples.xml b/build.examples.xml
index 62210d5ece..82432121ca 100644
--- a/build.examples.xml
+++ b/build.examples.xml
@@ -28,10 +28,6 @@ PROPERTIES
<!-- Location of pre-compiled libraries properties -->
<property name="scala.lib.jar" value="${lib.dir}/scala-library.jar"/>
<property name="scala.comp.jar" value="${lib.dir}/scala-compiler.jar"/>
- <property name="fjbg.name" value="fjbg.jar"/>
- <property name="fjbg.jar" value="${lib.dir}/${fjbg.name}"/>
- <property name="msil.name" value="msil.jar"/>
- <property name="msil.jar" value="${lib.dir}/${msil.name}"/>
<property name="ant.jar" value="${ant.home}/lib/ant.jar"/>
<property name="ant-contrib.jar" value="${lib.dir}/ant/ant-contrib.jar"/>
<!-- -->
@@ -59,7 +55,7 @@ INITIALISATION
<fail message="Scala library in '${lib.dir}/' is not available">
<condition><not><and>
<available
- classname="scala.Predef"
+ classname="scala.Predef"
classpath="${scala.lib.jar}"
/>
<available
@@ -81,24 +77,6 @@ INITIALISATION
/>
</not></condition>
</fail>
- <echo level="verbose" message="fjbg.jar=${fjbg.jar}"/>
- <fail message="FJBG library in '${lib.dir}/' is not available">
- <condition><not>
- <available
- classname="ch.epfl.lamp.fjbg.JCode"
- classpath="${fjbg.jar}"
- />
- </not></condition>
- </fail>
- <echo level="verbose" message="msil.jar=${msil.jar}"/>
- <fail message="MSIL library in '${lib.dir}/' is not available">
- <condition><not>
- <available
- classname="ch.epfl.lamp.compiler.msil.MemberInfo"
- classpath="${msil.jar}"
- />
- </not></condition>
- </fail>
<echo level="verbose" message="ant.jar=${ant.jar}"/>
<echo level="verbose" message="ant-contrib.jar=${ant-contrib.jar}"/>
<fail message="Additional Ant tasks in '${lib.dir}/' is not available">
@@ -110,14 +88,9 @@ INITIALISATION
</not></condition>
</fail>
<!-- Creating class-pathes -->
- <path id="common.classpath">
- <pathelement location="${fjbg.jar}"/>
- <pathelement location="${msil.jar}"/>
- </path>
<path id="scala.classpath">
<pathelement location="${scala.lib.jar}"/>
<pathelement location="${scala.comp.jar}"/>
- <path refid="common.classpath"/>
</path>
<!-- Creating boot-level tasks -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
diff --git a/build.xml b/build.xml
index 3cfbd454e2..0052b8914d 100644
--- a/build.xml
+++ b/build.xml
@@ -22,7 +22,7 @@ END-USER TARGETS
<target name="clean" depends="quick.clean"
description="Removes binaries of compiler and library. Distributions are untouched."/>
- <target name="test" depends="test.done, osgi.test"
+ <target name="test" depends="test.done, osgi.test, bc.run"
description="Runs test suite and bootstrapping test on Scala compiler and library."/>
<target name="test-opt"
@@ -203,7 +203,6 @@ PROPERTIES
<!-- Sets location of pre-compiled libraries -->
<property name="lib.starr.jar" value="${lib.dir}/scala-library.jar"/>
- <property name="msil.starr.jar" value="${lib.dir}/msil.jar"/>
<property name="reflect.starr.jar" value="${lib.dir}/scala-reflect.jar"/>
<property name="comp.starr.jar" value="${lib.dir}/scala-compiler.jar"/>
<property name="jline.jar" value="${lib.dir}/jline.jar"/>
@@ -461,9 +460,7 @@ INITIALISATION
<!-- Libraries only used for STARR -->
<path id="starr.dep.libs">
<fileset dir="${lib.dir}">
- <include name="fjbg.jar"/>
<include name="forkjoin.jar"/>
- <include name="msil.jar"/>
</fileset>
</path>
<!-- Auxiliary libs placed on every classpath. -->
@@ -593,57 +590,10 @@ LOCAL DEPENDENCY (FORKJOIN)
</target>
<!-- ===========================================================================
-LOCAL DEPENDENCY (FJBG)
-============================================================================ -->
-
- <target name="fjbg.init" depends="init">
- <uptodate property="fjbg.available" targetfile="${build-libs.dir}/fjbg.complete">
- <srcfiles dir="${src.dir}/fjbg">
- <include name="**/*.java"/>
- <include name="**/*.scala"/>
- </srcfiles>
- </uptodate>
- </target>
-
- <target name="fjbg.lib" depends="fjbg.init" unless="fjbg.available">
- <stopwatch name="fjbg.lib.timer" />
- <mkdir dir="${build-libs.dir}/classes/fjbg"/>
- <javac
- srcdir="${src.dir}/fjbg"
- destdir="${build-libs.dir}/classes/fjbg"
- classpath="${build-libs.dir}/classes/fjbg"
- includes="**/*.java"
- debug="true"
- target="1.6" source="1.4">
- <compilerarg line="${javac.args} -XDignore.symbol.file"/>
- </javac>
- <touch file="${build-libs.dir}/fjbg.complete" verbose="no"/>
- <stopwatch name="fjbg.lib.timer" action="total"/>
- </target>
-
- <target name="fjbg.pack" depends="fjbg.lib">
- <jar destfile="${build-libs.dir}/fjbg.jar">
- <fileset dir="${build-libs.dir}/classes/fjbg"/>
- </jar>
- </target>
-
- <target name="fjbg.done" depends="fjbg.pack">
- <!-- TODO - jar or classfiles? -->
- <path id="fjbg.classpath">
- <pathelement location="${build-libs.dir}/classes/fjbg"/>
- </path>
- </target>
-
- <target name="fjbg.clean" depends="init">
- <delete dir="${build-libs.dir}/classes/fjbg" includeemptydirs="yes" quiet="yes" failonerror="no"/>
- <delete file="${build-libs.dir}/fjbg.complete" quiet="yes" failonerror="no"/>
- </target>
-
-<!-- ===========================================================================
LOCAL REFERENCE BUILD (LOCKER)
============================================================================ -->
- <target name="locker.start" depends="asm.done, forkjoin.done, fjbg.done">
+ <target name="locker.start" depends="asm.done, forkjoin.done">
<condition property="locker.available">
<available file="${build-locker.dir}/all.complete"/>
</condition>
@@ -669,9 +619,6 @@ LOCAL REFERENCE BUILD (LOCKER)
<pathelement location="${build-locker.dir}/classes/library"/>
</classpath>
</javac>
- <!-- NOTE: Potential problem with maximal command line length on Windows
- (32768 characters for XP, since executed with Java's "exec"). See
- src/build/msil.xml in msil branch for more details. -->
<scalacfork
destdir="${build-locker.dir}/classes/library"
compilerpathref="starr.classpath"
@@ -761,43 +708,6 @@ LOCAL REFERENCE BUILD (LOCKER)
<target name="locker.comp" depends="locker.pre-comp" if="locker.comp.needed">
<stopwatch name="locker.comp.timer"/>
<mkdir dir="${build-locker.dir}/classes/compiler"/>
- <if>
- <equals arg1="${fastlocker}" arg2="true" />
- <then>
- <!-- Fastlocker build: don't compile MSIL, use its starr version.... -->
- <property name="locker.comp.msil" value="${msil.starr.jar}"/>
- </then>
- <else>
- <!-- Regular build: Compile MSIL inside of locker.... -->
- <javac
- srcdir="${src.dir}/msil"
- destdir="${build-locker.dir}/classes/compiler"
- classpath="${build-locker.dir}/classes/compiler"
- includes="**/*.java"
- excludes="**/tests/**"
- debug="true"
- target="1.6" source="1.4">
- <compilerarg line="${javac.args}"/>
- </javac>
- <scalacfork
- destdir="${build-locker.dir}/classes/compiler"
- compilerpathref="starr.classpath"
- params="${scalac.args.all}"
- srcdir="${src.dir}/msil"
- jvmargs="${scalacfork.jvmargs}">
- <include name="**/*.scala"/>
- <compilationpath>
- <pathelement location="${build-locker.dir}/classes/library"/>
- <pathelement location="${build-locker.dir}/classes/reflect"/>
- <pathelement location="${build-locker.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
- <path refid="aux.libs"/>
- <pathelement location="${jline.jar}"/>
- </compilationpath>
- </scalacfork>
- <property name="locker.comp.msil" value="${build-locker.dir}/classes/compiler"/>
- </else>
- </if>
<scalacfork
destdir="${build-locker.dir}/classes/compiler"
compilerpathref="starr.classpath"
@@ -809,10 +719,8 @@ LOCAL REFERENCE BUILD (LOCKER)
<pathelement location="${build-locker.dir}/classes/library"/>
<pathelement location="${build-locker.dir}/classes/reflect"/>
<pathelement location="${build-locker.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
<path refid="aux.libs"/>
<path refid="asm.classpath"/>
- <pathelement location="${locker.comp.msil}" />
<pathelement location="${jline.jar}"/>
</compilationpath>
</scalacfork>
@@ -845,7 +753,6 @@ LOCAL REFERENCE BUILD (LOCKER)
<pathelement location="${build-locker.dir}/classes/library"/>
<pathelement location="${build-locker.dir}/classes/reflect"/>
<pathelement location="${build-locker.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
<path refid="forkjoin.classpath"/>
<path refid="asm.classpath"/>
<path refid="aux.libs"/>
@@ -855,7 +762,6 @@ LOCAL REFERENCE BUILD (LOCKER)
<pathelement location="${build-quick.dir}/classes/library"/>
<pathelement location="${build-quick.dir}/classes/reflect"/>
<pathelement location="${build-quick.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
<path refid="forkjoin.classpath"/>
<path refid="asm.classpath"/>
<path refid="aux.libs"/>
@@ -953,7 +859,6 @@ PACKED LOCKER BUILD (PALO)
<jar destfile="${build-palo.dir}/lib/scala-compiler.jar" manifest="${basedir}/META-INF/MANIFEST.MF">
<fileset dir="${build-locker.dir}/classes/compiler"/>
<fileset dir="${build-asm.dir}/classes/"/>
- <fileset dir="${build-libs.dir}/classes/fjbg"/>
</jar>
<copy file="${jline.jar}" toDir="${build-palo.dir}/lib"/>
</target>
@@ -1163,33 +1068,6 @@ QUICK BUILD (QUICK)
<target name="quick.comp" depends="quick.pre-comp" unless="quick.comp.available">
<stopwatch name="quick.comp.timer"/>
<mkdir dir="${build-quick.dir}/classes/compiler"/>
- <!-- Compile MSIL inside of quick.... -->
- <javac
- srcdir="${src.dir}/msil"
- destdir="${build-quick.dir}/classes/compiler"
- classpath="${build-quick.dir}/classes/compiler"
- includes="**/*.java"
- excludes="**/tests/**"
- debug="true"
- target="1.6" source="1.4">
- <compilerarg line="${javac.args}"/>
- </javac>
- <scalacfork
- destdir="${build-quick.dir}/classes/compiler"
- compilerpathref="locker.classpath"
- params="${scalac.args.all}"
- srcdir="${src.dir}/msil"
- jvmargs="${scalacfork.jvmargs}">
- <include name="**/*.scala"/>
- <compilationpath>
- <pathelement location="${build-quick.dir}/classes/library"/>
- <pathelement location="${build-quick.dir}/classes/reflect"/>
- <pathelement location="${build-quick.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
- <path refid="aux.libs"/>
- <pathelement location="${jline.jar}"/>
- </compilationpath>
- </scalacfork>
<scalacfork
destdir="${build-quick.dir}/classes/compiler"
compilerpathref="locker.classpath"
@@ -1203,7 +1081,6 @@ QUICK BUILD (QUICK)
<pathelement location="${build-quick.dir}/classes/compiler"/>
<path refid="aux.libs"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<path refid="asm.classpath"/>
<pathelement location="${jline.jar}"/>
</compilationpath>
@@ -1254,7 +1131,6 @@ QUICK BUILD (QUICK)
<pathelement location="${build-quick.dir}/classes/compiler"/>
<pathelement location="${build-quick.dir}/classes/continuations-plugin"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<path refid="aux.libs"/>
</compilationpath>
</scalacfork>
@@ -1376,7 +1252,6 @@ QUICK BUILD (QUICK)
<pathelement location="${build-quick.dir}/classes/partest"/>
<pathelement location="${ant.jar}"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<pathelement location="${scalacheck.jar}"/>
</compilationpath>
</scalacfork>
@@ -1406,7 +1281,6 @@ QUICK BUILD (QUICK)
<pathelement location="${build-quick.dir}/classes/compiler"/>
<pathelement location="${build-quick.dir}/classes/scalap"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<path refid="aux.libs"/>
<path refid="asm.classpath"/>
<pathelement location="${jline.jar}"/>
@@ -1533,7 +1407,6 @@ PACKED QUICK BUILD (PACK)
<jar destfile="${build-pack.dir}/lib/scala-compiler.jar" manifest="${build-pack.dir}/META-INF/MANIFEST.MF">
<fileset dir="${build-quick.dir}/classes/compiler"/>
<fileset dir="${build-asm.dir}/classes"/>
- <fileset dir="${build-libs.dir}/classes/fjbg"/>
</jar>
<copy file="${jline.jar}" toDir="${build-pack.dir}/lib"/>
<copy todir="${build-pack.dir}/lib">
@@ -1945,33 +1818,6 @@ BOOTSTRAPPING BUILD (STRAP)
<target name="strap.comp" depends="strap.pre-comp" unless="strap.comp.available">
<stopwatch name="strap.comp.timer"/>
<mkdir dir="${build-strap.dir}/classes/compiler"/>
- <!-- Compile MSIL inside of strap.... -->
- <javac
- srcdir="${src.dir}/msil"
- destdir="${build-strap.dir}/classes/compiler"
- classpath="${build-strap.dir}/classes/compiler"
- includes="**/*.java"
- excludes="**/tests/**"
- debug="true"
- target="1.6" source="1.4">
- <compilerarg line="${javac.args}"/>
- </javac>
- <scalacfork
- destdir="${build-strap.dir}/classes/compiler"
- compilerpathref="pack.classpath"
- params="${scalac.args.all}"
- srcdir="${src.dir}/msil"
- jvmargs="${scalacfork.jvmargs}">
- <include name="**/*.scala"/>
- <compilationpath>
- <pathelement location="${build-strap.dir}/classes/library"/>
- <pathelement location="${build-strap.dir}/classes/reflect"/>
- <pathelement location="${build-strap.dir}/classes/compiler"/>
- <path refid="fjbg.classpath"/>
- <path refid="aux.libs"/>
- <pathelement location="${jline.jar}"/>
- </compilationpath>
- </scalacfork>
<scalacfork
destdir="${build-strap.dir}/classes/compiler"
compilerpathref="pack.classpath"
@@ -1985,7 +1831,6 @@ BOOTSTRAPPING BUILD (STRAP)
<pathelement location="${build-strap.dir}/classes/compiler"/>
<path refid="aux.libs"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<path refid="asm.classpath"/>
<pathelement location="${jline.jar}"/>
</compilationpath>
@@ -2036,7 +1881,6 @@ BOOTSTRAPPING BUILD (STRAP)
<pathelement location="${build-strap.dir}/classes/compiler"/>
<pathelement location="${build-strap.dir}/classes/continuations-plugin"/>
<path refid="forkjoin.classpath"/>
- <path refid="fjbg.classpath"/>
<path refid="aux.libs"/>
</compilationpath>
</scalacfork>
@@ -2168,7 +2012,7 @@ BOOTSTRAPPING BUILD (STRAP)
</target>
<!-- ===========================================================================
-LIBRARIES (Forkjoin, FJBG, ASM)
+LIBRARIES (Forkjoin, ASM)
============================================================================ -->
@@ -2644,6 +2488,40 @@ BOOTRAPING TEST AND TEST SUITE
<target name="test.done" depends="test.suite, test.continuations.suite, test.scaladoc, test.stability, test.sbt"/>
+
+<!-- ===========================================================================
+Binary compatibility testing
+============================================================================ -->
+
+ <target name="bc.init" depends="init">
+ <property name="bc-build.dir" value="${build.dir}/bc"/>
+ <!-- Obtain mima -->
+ <mkdir dir="${bc-build.dir}"/>
+ <!-- Pull down MIMA -->
+ <artifact:dependencies pathId="mima.classpath">
+ <dependency groupId="com.typesafe" artifactId="mima-reporter_2.9.2" version="0.1.4"/>
+ </artifact:dependencies>
+ <artifact:dependencies pathId="old.bc.classpath">
+ <dependency groupId="org.scala-lang" artifactId="scala-library" version="2.10.0-RC2"/>
+ </artifact:dependencies>
+ </target>
+
+ <target name="bc.run" depends="bc.init, pack.lib">
+ <java
+ fork="true"
+ failonerror="true"
+ classname="com.typesafe.tools.mima.cli.Main">
+ <arg value="--prev"/>
+ <arg value="${org.scala-lang:scala-library:jar}"/>
+ <arg value="--curr"/>
+ <arg value="${build-pack.dir}/lib/scala-library.jar"/>
+ <classpath>
+ <path refid="mima.classpath"/>
+ </classpath>
+ </java>
+ </target>
+
+
<!-- ===========================================================================
DISTRIBUTION
============================================================================ -->
@@ -2672,7 +2550,12 @@ DISTRIBUTION
<target name="dist.base" depends="dist.start">
<mkdir dir="${dist.dir}/lib"/>
<copy toDir="${dist.dir}/lib">
- <fileset dir="${build-pack.dir}/lib"/>
+ <fileset dir="${build-pack.dir}/lib">
+ <include name="jline.jar"/>
+ <include name="scalacheck.jar"/>
+ <include name="scala-partest.jar"/>
+ <include name="scalap.jar"/>
+ </fileset>
</copy>
<mkdir dir="${dist.dir}/bin"/>
<!-- TODO - Stop being inefficient and don't copy OSGi bundles overtop other jars. -->
@@ -2829,8 +2712,6 @@ STABLE REFERENCE (STARR)
<jar destfile="${basedir}/lib/scala-compiler-src.jar">
<fileset dir="${basedir}/src/compiler"/>
<fileset dir="${basedir}/src/asm"/>
- <fileset dir="${basedir}/src/fjbg"/>
- <fileset dir="${basedir}/src/msil"/>
</jar>
</target>
diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1
deleted file mode 100644
index 6f3ccc77bd..0000000000
--- a/lib/fjbg.jar.desired.sha1
+++ /dev/null
@@ -1 +0,0 @@
-8acc87f222210b4a5eb2675477602fc1759e7684 *fjbg.jar
diff --git a/lib/msil.jar.desired.sha1 b/lib/msil.jar.desired.sha1
deleted file mode 100644
index 9396b273ab..0000000000
--- a/lib/msil.jar.desired.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d48cb950ceded82a5e0ffae8ef2c68d0923ed00c *msil.jar
diff --git a/project/Build.scala b/project/Build.scala
index a50a572d54..efa8a7a038 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -11,7 +11,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
override lazy val settings = super.settings ++ Versions.settings ++ Seq(
autoScalaLibrary := false,
resolvers += Resolver.url(
- "Typesafe nightlies",
+ "Typesafe nightlies",
url("https://typesafe.artifactoryonline.com/typesafe/ivy-snapshots/")
)(Resolver.ivyStylePatterns),
resolvers ++= Seq(
@@ -21,14 +21,14 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
organization := "org.scala-lang",
version <<= Versions.mavenVersion,
pomExtra := epflPomExtra
- )
+ )
// Collections of projects to run 'compile' on.
- lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, forkjoin, fjbg)
+ lazy val compiledProjects = Seq(quickLib, quickComp, continuationsLibrary, actors, swing, forkjoin)
// Collection of projects to 'package' and 'publish' together.
lazy val packagedBinaryProjects = Seq(scalaLibrary, scalaCompiler, swing, actors, continuationsPlugin, jline, scalap)
lazy val partestRunProjects = Seq(testsuite, continuationsTestsuite)
-
+
private def epflPomExtra = (
<xml:group>
<inceptionYear>2002</inceptionYear>
@@ -47,7 +47,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
</issueManagement>
</xml:group>
)
-
+
// Settings used to make sure publishing goes smoothly.
def publishSettings: Seq[Setting[_]] = Seq(
ivyScala ~= ((is: Option[IvyScala]) => is.map(_.copy(checkExplicit = false))),
@@ -82,7 +82,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
makeExplodedDist <<= (makeExplodedDist in scaladist).identity,
// Note: We override unmanagedSources so that ~ compile will look at all these sources, then run our aggregated compile...
unmanagedSourceDirectories in Compile <<= baseDirectory apply (_ / "src") apply { dir =>
- Seq("library/scala","actors","compiler","fjbg","swing","continuations/library","forkjoin") map (dir / _)
+ Seq("library/scala","actors","compiler","swing","continuations/library","forkjoin") map (dir / _)
},
// TODO - Make exported products == makeDist so we can use this when creating a *real* distribution.
commands += Release.pushStarr
@@ -91,7 +91,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
lazy val aaa_root = Project("scala", file(".")) settings(projectSettings: _*) settings(ShaResolve.settings: _*)
// External dependencies used for various projects
- lazy val externalDeps: Setting[_] = libraryDependencies <<= (sbtVersion)(v =>
+ lazy val externalDeps: Setting[_] = libraryDependencies <<= (sbtVersion)(v =>
Seq(
"org.apache.ant" % "ant" % "1.8.2",
"org.scala-sbt" % "compiler-interface" % v % "provided"
@@ -132,9 +132,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
// Jline nested project. Compile this sucker once and be done.
lazy val jline = Project("jline", file("src/jline"))
- // Fast Java Bytecode Generator (nested in every scala-compiler.jar)
- lazy val fjbg = Project("fjbg", file(".")) settings(settingOverrides : _*)
- // Our wrapped version of msil.
+ // Our wrapped version of asm.
lazy val asm = Project("asm", file(".")) settings(settingOverrides : _*)
// Forkjoin backport
lazy val forkjoin = Project("forkjoin", file(".")) settings(settingOverrides : _*)
@@ -175,9 +173,9 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
// --------------------------------------------------------------
// Projects dependent on layered compilation (quick)
// --------------------------------------------------------------
- def addCheaterDependency(projectName: String): Setting[_] =
- pomPostProcess <<= (version, organization, pomPostProcess) apply { (v,o,k) =>
- val dependency: scala.xml.Node =
+ def addCheaterDependency(projectName: String): Setting[_] =
+ pomPostProcess <<= (version, organization, pomPostProcess) apply { (v,o,k) =>
+ val dependency: scala.xml.Node =
<dependency>
<groupId>{o}</groupId>
<artifactid>{projectName}</artifactid>
@@ -193,10 +191,10 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
case n: scala.xml.Elem if n.label == "dependencies" => n
} isEmpty)
// TODO - Keep namespace on project...
- k andThen {
+ k andThen {
case n @ <project>{ nested@_*}</project> if hasDependencies(n) =>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">{nested}<dependencies>{dependency}</dependencies></project>
- case <project>{ nested@_*}</project> =>
+ case <project>{ nested@_*}</project> =>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0">{ nested map fixDependencies }</project>
}
}
@@ -205,7 +203,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
lazy val dependentProjectSettings = settingOverrides ++ Seq(quickScalaInstance, quickScalaLibraryDependency, addCheaterDependency("scala-library"))
lazy val actors = Project("scala-actors", file(".")) settings(dependentProjectSettings:_*) dependsOn(forkjoin % "provided")
lazy val swing = Project("scala-swing", file(".")) settings(dependentProjectSettings:_*) dependsOn(actors % "provided")
- // This project will generate man pages (in man1 and html) for scala.
+ // This project will generate man pages (in man1 and html) for scala.
lazy val manmakerSettings: Seq[Setting[_]] = dependentProjectSettings :+ externalDeps
lazy val manmaker = Project("manual", file(".")) settings(manmakerSettings:_*)
@@ -234,7 +232,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
lazy val continuationsPlugin = Project("continuations-plugin", file(".")) settings(continuationsPluginSettings:_*)
lazy val continuationsLibrarySettings = dependentProjectSettings ++ Seq(
scalaSource in Compile <<= baseDirectory(_ / "src/continuations/library/"),
- scalacOptions in Compile <++= (exportedProducts in Compile in continuationsPlugin) map {
+ scalacOptions in Compile <++= (exportedProducts in Compile in continuationsPlugin) map {
case Seq(cpDir) => Seq("-Xplugin-require:continuations", "-P:continuations:enable", "-Xplugin:"+cpDir.data.getAbsolutePath)
}
)
@@ -283,7 +281,7 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
// --------------------------------------------------------------
// Real Compiler Artifact
// --------------------------------------------------------------
- lazy val packageScalaBinTask = Seq(quickComp, fjbg, asm).map(p => products in p in Compile).join.map(_.flatten).map(productTaskToMapping)
+ lazy val packageScalaBinTask = Seq(quickComp, asm).map(p => products in p in Compile).join.map(_.flatten).map(productTaskToMapping)
lazy val scalaBinArtifactSettings : Seq[Setting[_]] = inConfig(Compile)(Defaults.packageTasks(packageBin, packageScalaBinTask)) ++ Seq(
name := "scala-compiler",
crossPaths := false,
@@ -297,11 +295,11 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
lazy val scalaCompiler = Project("scala-compiler", file(".")) settings(publishSettings:_*) settings(scalaBinArtifactSettings:_*) dependsOn(scalaReflect)
lazy val fullQuickScalaReference = makeScalaReference("pack", scalaLibrary, scalaReflect, scalaCompiler)
-
+
// --------------------------------------------------------------
// Generating Documentation.
// --------------------------------------------------------------
-
+
// TODO - Migrate this into the dist project.
// Scaladocs
lazy val documentationSettings: Seq[Setting[_]] = dependentProjectSettings ++ Seq(
@@ -331,6 +329,6 @@ object ScalaBuild extends Build with Layers with Packaging with Testing {
lazy val documentation = (
Project("documentation", file("."))
settings (documentationSettings: _*)
- dependsOn(quickLib, quickComp, actors, fjbg, forkjoin, swing, continuationsLibrary)
+ dependsOn(quickLib, quickComp, actors, forkjoin, swing, continuationsLibrary)
)
}
diff --git a/project/Layers.scala b/project/Layers.scala
index 35cc79c130..6c939d0ff7 100644
--- a/project/Layers.scala
+++ b/project/Layers.scala
@@ -13,8 +13,6 @@ trait Layers extends Build {
def jline: Project
/** Reference to forkjoin library */
def forkjoin: Project
- /** Reference to Fast-Java-Bytecode-Generator library */
- def fjbg: Project
/** Reference to the ASM wrapped project. */
def asm: Project
/** A setting that adds some external dependencies. */
@@ -23,7 +21,7 @@ trait Layers extends Build {
def aaa_root: Project
/** Creates a reference Scala version that can be used to build other projects. This takes in the raw
- * library, compiler and fjbg libraries as well as a string representing the layer name (used for compiling the compile-interface).
+ * library, compiler as well as a string representing the layer name (used for compiling the compile-interface).
*/
def makeScalaReference(layer: String, library: Project, reflect: Project, compiler: Project) =
scalaInstance <<= (appConfiguration in library,
@@ -31,10 +29,9 @@ trait Layers extends Build {
(exportedProducts in library in Compile),
(exportedProducts in reflect in Compile),
(exportedProducts in compiler in Compile),
- (exportedProducts in fjbg in Compile),
(fullClasspath in jline in Runtime),
(exportedProducts in asm in Runtime)) map {
- (app, version: String, lib: Classpath, reflect: Classpath, comp: Classpath, fjbg: Classpath, jline: Classpath, asm: Classpath) =>
+ (app, version: String, lib: Classpath, reflect: Classpath, comp: Classpath, jline: Classpath, asm: Classpath) =>
val launcher = app.provider.scalaProvider.launcher
(lib,comp) match {
case (Seq(libraryJar), Seq(compilerJar)) =>
@@ -43,14 +40,14 @@ trait Layers extends Build {
libraryJar.data,
compilerJar.data,
launcher,
- ((fjbg.files ++ jline.files ++ asm.files ++ reflect.files):_*))
+ ((jline.files ++ asm.files ++ reflect.files):_*))
case _ => error("Cannot build a ScalaReference with more than one classpath element")
}
}
/** Creates a "layer" of Scala compilation. That is, this will build the next version of Scala from a previous version.
* Returns the library project and compiler project from the next layer.
- * Note: The library and compiler are not *complete* in the sense that they are missing things like "actors" and "fjbg".
+ * Note: The library and compiler are not *complete* in the sense that they are missing things like "actors".
*/
def makeLayer(layer: String, referenceScala: Setting[Task[ScalaInstance]], autoLock: Boolean = false) : (Project, Project, Project) = {
val autoLockSettings: Seq[Setting[_]] =
@@ -96,7 +93,6 @@ trait Layers extends Build {
version := layer,
scalaSource in Compile <<= (baseDirectory) apply (_ / "src" / "compiler"),
resourceDirectory in Compile <<= baseDirectory apply (_ / "src" / "compiler"),
- unmanagedSourceDirectories in Compile <+= (baseDirectory) apply (_ / "src" / "msil"),
defaultExcludes := ("tests"),
defaultExcludes in unmanagedResources := "*.scala",
resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, skip in Compile, streams) map Versions.generateVersionPropertiesFile("compiler.properties"),
@@ -108,7 +104,7 @@ trait Layers extends Build {
dirs.descendentsExcept( ("*.xml" | "*.html" | "*.gif" | "*.png" | "*.js" | "*.css" | "*.tmpl" | "*.swf" | "*.properties" | "*.txt"),"*.scala").get
},
// TODO - Use depends on *and* SBT's magic dependency mechanisms...
- unmanagedClasspath in Compile <<= Seq(forkjoin, library, reflect, fjbg, jline, asm).map(exportedProducts in Compile in _).join.map(_.flatten),
+ unmanagedClasspath in Compile <<= Seq(forkjoin, library, reflect, jline, asm).map(exportedProducts in Compile in _).join.map(_.flatten),
externalDeps,
referenceScala
)
diff --git a/project/Packaging.scala b/project/Packaging.scala
index eb4e69f99e..6cb51a10a6 100644
--- a/project/Packaging.scala
+++ b/project/Packaging.scala
@@ -19,7 +19,7 @@ trait Packaging { self: ScalaBuild.type =>
genBin <<= genBinTask(genBinRunner, binDir, fullClasspath in Runtime, false),
binDir in genBinQuick <<= baseDirectory apply (_ / "target" / "bin"),
// Configure the classpath this way to avoid having .jar files and previous layers on the classpath.
- fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,fjbg,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq),
+ fullClasspath in Runtime in genBinQuick <<= Seq(quickComp,quickLib,scalap,actors,swing,jline,forkjoin).map(classDirectory in Compile in _).join.map(Attributed.blankSeq),
fullClasspath in Runtime in genBinQuick <++= (fullClasspath in Compile in jline),
genBinQuick <<= genBinTask(genBinRunner, binDir in genBinQuick, fullClasspath in Runtime in genBinQuick, true),
runManmakerMan <<= runManmakerTask(fullClasspath in Runtime in manmaker, runner in manmaker, "scala.tools.docutil.EmitManPage", "man1", ".1"),
diff --git a/project/Testing.scala b/project/Testing.scala
index 5de72116a3..5b4135a31a 100644
--- a/project/Testing.scala
+++ b/project/Testing.scala
@@ -17,7 +17,7 @@ trait Testing { self: ScalaBuild.type =>
autoScalaLibrary := false
)
lazy val continuationsTestsuiteSettings: Seq[Setting[_]] = testsuiteSettings ++ Seq(
- scalacOptions in Test <++= (exportedProducts in Compile in continuationsPlugin) map {
+ scalacOptions in Test <++= (exportedProducts in Compile in continuationsPlugin) map {
case Seq(cpDir) => Seq("-Xplugin-require:continuations", "-P:continuations:enable", "-Xplugin:"+cpDir.data.getAbsolutePath)
},
partestDirs <<= baseDirectory apply { bd =>
@@ -27,14 +27,14 @@ trait Testing { self: ScalaBuild.type =>
}
)
val testsuite = (
- Project("testsuite", file("."))
+ Project("testsuite", file("."))
settings (testsuiteSettings:_*)
- dependsOn (scalaLibrary, scalaCompiler, fjbg, partest, scalacheck)
+ dependsOn (scalaLibrary, scalaCompiler, partest, scalacheck)
)
val continuationsTestsuite = (
Project("continuations-testsuite", file("."))
- settings (continuationsTestsuiteSettings:_*)
- dependsOn (partest, scalaLibrary, scalaCompiler, fjbg)
+ settings (continuationsTestsuiteSettings:_*)
+ dependsOn (partest, scalaLibrary, scalaCompiler)
)
}
diff --git a/src/asm/scala/tools/asm/AnnotationVisitor.java b/src/asm/scala/tools/asm/AnnotationVisitor.java
index b96e730a73..c806ca71e8 100644
--- a/src/asm/scala/tools/asm/AnnotationVisitor.java
+++ b/src/asm/scala/tools/asm/AnnotationVisitor.java
@@ -54,8 +54,9 @@ public abstract class AnnotationVisitor {
/**
* Constructs a new {@link AnnotationVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
@@ -64,15 +65,17 @@ public abstract class AnnotationVisitor {
/**
* Constructs a new {@link AnnotationVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param av the annotation visitor to which this visitor must delegate
- * method calls. May be null.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param av
+ * the annotation visitor to which this visitor must delegate
+ * method calls. May be null.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
- /*if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4) {
throw new IllegalArgumentException();
- }*/
+ }
this.api = api;
this.av = av;
}
@@ -80,14 +83,17 @@ public abstract class AnnotationVisitor {
/**
* Visits a primitive value of the annotation.
*
- * @param name the value name.
- * @param value the actual value, whose type must be {@link Byte},
- * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}
- * , {@link Long}, {@link Float}, {@link Double}, {@link String} or
- * {@link Type} or OBJECT or ARRAY sort. This value can also be an
- * array of byte, boolean, short, char, int, long, float or double
- * values (this is equivalent to using {@link #visitArray visitArray}
- * and visiting each array element in turn, but is more convenient).
+ * @param name
+ * the value name.
+ * @param value
+ * the actual value, whose type must be {@link Byte},
+ * {@link Boolean}, {@link Character}, {@link Short},
+ * {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+ * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+ * value can also be an array of byte, boolean, short, char, int,
+ * long, float or double values (this is equivalent to using
+ * {@link #visitArray visitArray} and visiting each array element
+ * in turn, but is more convenient).
*/
public void visit(String name, Object value) {
if (av != null) {
@@ -98,9 +104,12 @@ public abstract class AnnotationVisitor {
/**
* Visits an enumeration value of the annotation.
*
- * @param name the value name.
- * @param desc the class descriptor of the enumeration class.
- * @param value the actual enumeration value.
+ * @param name
+ * the value name.
+ * @param desc
+ * the class descriptor of the enumeration class.
+ * @param value
+ * the actual enumeration value.
*/
public void visitEnum(String name, String desc, String value) {
if (av != null) {
@@ -111,12 +120,14 @@ public abstract class AnnotationVisitor {
/**
* Visits a nested annotation value of the annotation.
*
- * @param name the value name.
- * @param desc the class descriptor of the nested annotation class.
+ * @param name
+ * the value name.
+ * @param desc
+ * the class descriptor of the nested annotation class.
* @return a visitor to visit the actual nested annotation value, or
- * <tt>null</tt> if this visitor is not interested in visiting
- * this nested annotation. <i>The nested annotation value must be
- * fully visited before calling other methods on this annotation
+ * <tt>null</tt> if this visitor is not interested in visiting this
+ * nested annotation. <i>The nested annotation value must be fully
+ * visited before calling other methods on this annotation
* visitor</i>.
*/
public AnnotationVisitor visitAnnotation(String name, String desc) {
@@ -132,10 +143,11 @@ public abstract class AnnotationVisitor {
* can be passed as value to {@link #visit visit}. This is what
* {@link ClassReader} does.
*
- * @param name the value name.
+ * @param name
+ * the value name.
* @return a visitor to visit the actual array value elements, or
- * <tt>null</tt> if this visitor is not interested in visiting
- * these values. The 'name' parameters passed to the methods of this
+ * <tt>null</tt> if this visitor is not interested in visiting these
+ * values. The 'name' parameters passed to the methods of this
* visitor are ignored. <i>All the array values must be visited
* before calling other methods on this annotation visitor</i>.
*/
diff --git a/src/asm/scala/tools/asm/AnnotationWriter.java b/src/asm/scala/tools/asm/AnnotationWriter.java
index e530780249..8eb5b2ef48 100644
--- a/src/asm/scala/tools/asm/AnnotationWriter.java
+++ b/src/asm/scala/tools/asm/AnnotationWriter.java
@@ -90,20 +90,20 @@ final class AnnotationWriter extends AnnotationVisitor {
/**
* Constructs a new {@link AnnotationWriter}.
*
- * @param cw the class writer to which this annotation must be added.
- * @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise.
- * @param bv where the annotation values must be stored.
- * @param parent where the number of annotation values must be stored.
- * @param offset where in <tt>parent</tt> the number of annotation values must
- * be stored.
+ * @param cw
+ * the class writer to which this annotation must be added.
+ * @param named
+ * <tt>true<tt> if values are named, <tt>false</tt> otherwise.
+ * @param bv
+ * where the annotation values must be stored.
+ * @param parent
+ * where the number of annotation values must be stored.
+ * @param offset
+ * where in <tt>parent</tt> the number of annotation values must
+ * be stored.
*/
- AnnotationWriter(
- final ClassWriter cw,
- final boolean named,
- final ByteVector bv,
- final ByteVector parent,
- final int offset)
- {
+ AnnotationWriter(final ClassWriter cw, final boolean named,
+ final ByteVector bv, final ByteVector parent, final int offset) {
super(Opcodes.ASM4);
this.cw = cw;
this.named = named;
@@ -190,11 +190,8 @@ final class AnnotationWriter extends AnnotationVisitor {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
@@ -203,10 +200,8 @@ final class AnnotationWriter extends AnnotationVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String name,
- final String desc)
- {
+ public AnnotationVisitor visitAnnotation(final String name,
+ final String desc) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
@@ -259,7 +254,8 @@ final class AnnotationWriter extends AnnotationVisitor {
* Puts the annotations of this annotation writer list into the given byte
* vector.
*
- * @param out where the annotations must be put.
+ * @param out
+ * where the annotations must be put.
*/
void put(final ByteVector out) {
int n = 0;
@@ -286,15 +282,15 @@ final class AnnotationWriter extends AnnotationVisitor {
/**
* Puts the given annotation lists into the given byte vector.
*
- * @param panns an array of annotation writer lists.
- * @param off index of the first annotation to be written.
- * @param out where the annotations must be put.
+ * @param panns
+ * an array of annotation writer lists.
+ * @param off
+ * index of the first annotation to be written.
+ * @param out
+ * where the annotations must be put.
*/
- static void put(
- final AnnotationWriter[] panns,
- final int off,
- final ByteVector out)
- {
+ static void put(final AnnotationWriter[] panns, final int off,
+ final ByteVector out) {
int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) {
size += panns[i] == null ? 0 : panns[i].getSize();
diff --git a/src/asm/scala/tools/asm/Attribute.java b/src/asm/scala/tools/asm/Attribute.java
index 408f21ce1e..ac40a758a2 100644
--- a/src/asm/scala/tools/asm/Attribute.java
+++ b/src/asm/scala/tools/asm/Attribute.java
@@ -55,7 +55,8 @@ public class Attribute {
/**
* Constructs a new empty attribute.
*
- * @param type the type of the attribute.
+ * @param type
+ * the type of the attribute.
*/
protected Attribute(final String type) {
this.type = type;
@@ -91,39 +92,39 @@ public class Attribute {
}
/**
- * Reads a {@link #type type} attribute. This method must return a <i>new</i>
- * {@link Attribute} object, of type {@link #type type}, corresponding to
- * the <tt>len</tt> bytes starting at the given offset, in the given class
- * reader.
+ * Reads a {@link #type type} attribute. This method must return a
+ * <i>new</i> {@link Attribute} object, of type {@link #type type},
+ * corresponding to the <tt>len</tt> bytes starting at the given offset, in
+ * the given class reader.
*
- * @param cr the class that contains the attribute to be read.
- * @param off index of the first byte of the attribute's content in {@link
- * ClassReader#b cr.b}. The 6 attribute header bytes, containing the
- * type and the length of the attribute, are not taken into account
- * here.
- * @param len the length of the attribute's content.
- * @param buf buffer to be used to call
- * {@link ClassReader#readUTF8 readUTF8},
- * {@link ClassReader#readClass(int,char[]) readClass} or
- * {@link ClassReader#readConst readConst}.
- * @param codeOff index of the first byte of code's attribute content in
- * {@link ClassReader#b cr.b}, or -1 if the attribute to be read is
- * not a code attribute. The 6 attribute header bytes, containing the
- * type and the length of the attribute, are not taken into account
- * here.
- * @param labels the labels of the method's code, or <tt>null</tt> if the
- * attribute to be read is not a code attribute.
+ * @param cr
+ * the class that contains the attribute to be read.
+ * @param off
+ * index of the first byte of the attribute's content in
+ * {@link ClassReader#b cr.b}. The 6 attribute header bytes,
+ * containing the type and the length of the attribute, are not
+ * taken into account here.
+ * @param len
+ * the length of the attribute's content.
+ * @param buf
+ * buffer to be used to call {@link ClassReader#readUTF8
+ * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
+ * or {@link ClassReader#readConst readConst}.
+ * @param codeOff
+ * index of the first byte of code's attribute content in
+ * {@link ClassReader#b cr.b}, or -1 if the attribute to be read
+ * is not a code attribute. The 6 attribute header bytes,
+ * containing the type and the length of the attribute, are not
+ * taken into account here.
+ * @param labels
+ * the labels of the method's code, or <tt>null</tt> if the
+ * attribute to be read is not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given
* bytes.
*/
- protected Attribute read(
- final ClassReader cr,
- final int off,
- final int len,
- final char[] buf,
- final int codeOff,
- final Label[] labels)
- {
+ protected Attribute read(final ClassReader cr, final int off,
+ final int len, final char[] buf, final int codeOff,
+ final Label[] labels) {
Attribute attr = new Attribute(type);
attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len);
@@ -133,30 +134,30 @@ public class Attribute {
/**
* Returns the byte array form of this attribute.
*
- * @param cw the class to which this attribute must be added. This parameter
- * can be used to add to the constant pool of this class the items
- * that corresponds to this attribute.
- * @param code the bytecode of the method corresponding to this code
- * attribute, or <tt>null</tt> if this attribute is not a code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to this
- * code attribute, or <tt>null</tt> if this attribute is not a code
- * attribute.
- * @param maxStack the maximum stack size of the method corresponding to
- * this code attribute, or -1 if this attribute is not a code
- * attribute.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to this code attribute, or -1 if this attribute is
- * not a code attribute.
+ * @param cw
+ * the class to which this attribute must be added. This
+ * parameter can be used to add to the constant pool of this
+ * class the items that corresponds to this attribute.
+ * @param code
+ * the bytecode of the method corresponding to this code
+ * attribute, or <tt>null</tt> if this attribute is not a code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to this
+ * code attribute, or <tt>null</tt> if this attribute is not a
+ * code attribute.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to this
+ * code attribute, or -1 if this attribute is not a code
+ * attribute.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to this code attribute, or -1 if this attribute
+ * is not a code attribute.
* @return the byte array form of this attribute.
*/
- protected ByteVector write(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals)
- {
+ protected ByteVector write(final ClassWriter cw, final byte[] code,
+ final int len, final int maxStack, final int maxLocals) {
ByteVector v = new ByteVector();
v.data = value;
v.length = value.length;
@@ -181,30 +182,30 @@ public class Attribute {
/**
* Returns the size of all the attributes in this attribute list.
*
- * @param cw the class writer to be used to convert the attributes into byte
- * arrays, with the {@link #write write} method.
- * @param code the bytecode of the method corresponding to these code
- * attributes, or <tt>null</tt> if these attributes are not code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to
- * these code attributes, or <tt>null</tt> if these attributes are
- * not code attributes.
- * @param maxStack the maximum stack size of the method corresponding to
- * these code attributes, or -1 if these attributes are not code
- * attributes.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to these code attributes, or -1 if these attributes
- * are not code attributes.
+ * @param cw
+ * the class writer to be used to convert the attributes into
+ * byte arrays, with the {@link #write write} method.
+ * @param code
+ * the bytecode of the method corresponding to these code
+ * attributes, or <tt>null</tt> if these attributes are not code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to
+ * these code attributes, or <tt>null</tt> if these attributes
+ * are not code attributes.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to these
+ * code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these
+ * attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size
* includes the size of the attribute headers.
*/
- final int getSize(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals)
- {
+ final int getSize(final ClassWriter cw, final byte[] code, final int len,
+ final int maxStack, final int maxLocals) {
Attribute attr = this;
int size = 0;
while (attr != null) {
@@ -219,30 +220,30 @@ public class Attribute {
* Writes all the attributes of this attribute list in the given byte
* vector.
*
- * @param cw the class writer to be used to convert the attributes into byte
- * arrays, with the {@link #write write} method.
- * @param code the bytecode of the method corresponding to these code
- * attributes, or <tt>null</tt> if these attributes are not code
- * attributes.
- * @param len the length of the bytecode of the method corresponding to
- * these code attributes, or <tt>null</tt> if these attributes are
- * not code attributes.
- * @param maxStack the maximum stack size of the method corresponding to
- * these code attributes, or -1 if these attributes are not code
- * attributes.
- * @param maxLocals the maximum number of local variables of the method
- * corresponding to these code attributes, or -1 if these attributes
- * are not code attributes.
- * @param out where the attributes must be written.
+ * @param cw
+ * the class writer to be used to convert the attributes into
+ * byte arrays, with the {@link #write write} method.
+ * @param code
+ * the bytecode of the method corresponding to these code
+ * attributes, or <tt>null</tt> if these attributes are not code
+ * attributes.
+ * @param len
+ * the length of the bytecode of the method corresponding to
+ * these code attributes, or <tt>null</tt> if these attributes
+ * are not code attributes.
+ * @param maxStack
+ * the maximum stack size of the method corresponding to these
+ * code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals
+ * the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these
+ * attributes are not code attributes.
+ * @param out
+ * where the attributes must be written.
*/
- final void put(
- final ClassWriter cw,
- final byte[] code,
- final int len,
- final int maxStack,
- final int maxLocals,
- final ByteVector out)
- {
+ final void put(final ClassWriter cw, final byte[] code, final int len,
+ final int maxStack, final int maxLocals, final ByteVector out) {
Attribute attr = this;
while (attr != null) {
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
diff --git a/src/asm/scala/tools/asm/ByteVector.java b/src/asm/scala/tools/asm/ByteVector.java
index 5081f0184b..2bc63eb384 100644
--- a/src/asm/scala/tools/asm/ByteVector.java
+++ b/src/asm/scala/tools/asm/ByteVector.java
@@ -59,7 +59,8 @@ public class ByteVector {
* Constructs a new {@link ByteVector ByteVector} with the given initial
* size.
*
- * @param initialSize the initial size of the byte vector to be constructed.
+ * @param initialSize
+ * the initial size of the byte vector to be constructed.
*/
public ByteVector(final int initialSize) {
data = new byte[initialSize];
@@ -69,7 +70,8 @@ public class ByteVector {
* Puts a byte into this byte vector. The byte vector is automatically
* enlarged if necessary.
*
- * @param b a byte.
+ * @param b
+ * a byte.
* @return this byte vector.
*/
public ByteVector putByte(final int b) {
@@ -86,8 +88,10 @@ public class ByteVector {
* Puts two bytes into this byte vector. The byte vector is automatically
* enlarged if necessary.
*
- * @param b1 a byte.
- * @param b2 another byte.
+ * @param b1
+ * a byte.
+ * @param b2
+ * another byte.
* @return this byte vector.
*/
ByteVector put11(final int b1, final int b2) {
@@ -106,7 +110,8 @@ public class ByteVector {
* Puts a short into this byte vector. The byte vector is automatically
* enlarged if necessary.
*
- * @param s a short.
+ * @param s
+ * a short.
* @return this byte vector.
*/
public ByteVector putShort(final int s) {
@@ -125,8 +130,10 @@ public class ByteVector {
* Puts a byte and a short into this byte vector. The byte vector is
* automatically enlarged if necessary.
*
- * @param b a byte.
- * @param s a short.
+ * @param b
+ * a byte.
+ * @param s
+ * a short.
* @return this byte vector.
*/
ByteVector put12(final int b, final int s) {
@@ -146,7 +153,8 @@ public class ByteVector {
* Puts an int into this byte vector. The byte vector is automatically
* enlarged if necessary.
*
- * @param i an int.
+ * @param i
+ * an int.
* @return this byte vector.
*/
public ByteVector putInt(final int i) {
@@ -167,7 +175,8 @@ public class ByteVector {
* Puts a long into this byte vector. The byte vector is automatically
* enlarged if necessary.
*
- * @param l a long.
+ * @param l
+ * a long.
* @return this byte vector.
*/
public ByteVector putLong(final long l) {
@@ -194,7 +203,8 @@ public class ByteVector {
* Puts an UTF8 string into this byte vector. The byte vector is
* automatically enlarged if necessary.
*
- * @param s a String.
+ * @param s
+ * a String.
* @return this byte vector.
*/
public ByteVector putUTF8(final String s) {
@@ -259,14 +269,16 @@ public class ByteVector {
* Puts an array of bytes into this byte vector. The byte vector is
* automatically enlarged if necessary.
*
- * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
- * null bytes into this byte vector.
- * @param off index of the fist byte of b that must be copied.
- * @param len number of bytes of b that must be copied.
+ * @param b
+ * an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
+ * null bytes into this byte vector.
+ * @param off
+ * index of the fist byte of b that must be copied.
+ * @param len
+ * number of bytes of b that must be copied.
* @return this byte vector.
*/
- public ByteVector putByteArray(final byte[] b, final int off, final int len)
- {
+ public ByteVector putByteArray(final byte[] b, final int off, final int len) {
if (length + len > data.length) {
enlarge(len);
}
@@ -280,8 +292,9 @@ public class ByteVector {
/**
* Enlarge this byte vector so that it can receive n more bytes.
*
- * @param size number of additional bytes that this byte vector should be
- * able to receive.
+ * @param size
+ * number of additional bytes that this byte vector should be
+ * able to receive.
*/
private void enlarge(final int size) {
int length1 = 2 * data.length;
diff --git a/src/asm/scala/tools/asm/ClassReader.java b/src/asm/scala/tools/asm/ClassReader.java
index f3287d41ae..cc655c1b62 100644
--- a/src/asm/scala/tools/asm/ClassReader.java
+++ b/src/asm/scala/tools/asm/ClassReader.java
@@ -112,9 +112,8 @@ public class ClassReader {
public final byte[] b;
/**
- * The start index of each constant pool item in {@link #b b}, plus one.
- * The one byte offset skips the constant pool item tag that indicates its
- * type.
+ * The start index of each constant pool item in {@link #b b}, plus one. The
+ * one byte offset skips the constant pool item tag that indicates its type.
*/
private final int[] items;
@@ -147,7 +146,8 @@ public class ClassReader {
/**
* Constructs a new {@link ClassReader} object.
*
- * @param b the bytecode of the class to be read.
+ * @param b
+ * the bytecode of the class to be read.
*/
public ClassReader(final byte[] b) {
this(b, 0, b.length);
@@ -156,14 +156,17 @@ public class ClassReader {
/**
* Constructs a new {@link ClassReader} object.
*
- * @param b the bytecode of the class to be read.
- * @param off the start offset of the class data.
- * @param len the length of the class data.
+ * @param b
+ * the bytecode of the class to be read.
+ * @param off
+ * the start offset of the class data.
+ * @param len
+ * the length of the class data.
*/
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
- if (readShort(6) > Opcodes.V1_7) {
+ if (readShort(off + 6) > Opcodes.V1_7) {
throw new IllegalArgumentException();
}
// parses the constant pool
@@ -176,35 +179,35 @@ public class ClassReader {
items[i] = index + 1;
int size;
switch (b[index]) {
- case ClassWriter.FIELD:
- case ClassWriter.METH:
- case ClassWriter.IMETH:
- case ClassWriter.INT:
- case ClassWriter.FLOAT:
- case ClassWriter.NAME_TYPE:
- case ClassWriter.INDY:
- size = 5;
- break;
- case ClassWriter.LONG:
- case ClassWriter.DOUBLE:
- size = 9;
- ++i;
- break;
- case ClassWriter.UTF8:
- size = 3 + readUnsignedShort(index + 1);
- if (size > max) {
- max = size;
- }
- break;
- case ClassWriter.HANDLE:
- size = 4;
- break;
- // case ClassWriter.CLASS:
- // case ClassWriter.STR:
- // case ClassWriter.MTYPE
- default:
- size = 3;
- break;
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ case ClassWriter.INT:
+ case ClassWriter.FLOAT:
+ case ClassWriter.NAME_TYPE:
+ case ClassWriter.INDY:
+ size = 5;
+ break;
+ case ClassWriter.LONG:
+ case ClassWriter.DOUBLE:
+ size = 9;
+ ++i;
+ break;
+ case ClassWriter.UTF8:
+ size = 3 + readUnsignedShort(index + 1);
+ if (size > max) {
+ max = size;
+ }
+ break;
+ case ClassWriter.HANDLE:
+ size = 4;
+ break;
+ // case ClassWriter.CLASS:
+ // case ClassWriter.STR:
+ // case ClassWriter.MTYPE
+ default:
+ size = 3;
+ break;
}
index += size;
}
@@ -249,8 +252,7 @@ public class ClassReader {
* @see ClassVisitor#visit(int, int, String, String, String, String[])
*/
public String getSuperName() {
- int n = items[readUnsignedShort(header + 4)];
- return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
+ return readClass(header + 4, new char[maxStringLength]);
}
/**
@@ -280,7 +282,8 @@ public class ClassReader {
* Copies the constant pool data into the given {@link ClassWriter}. Should
* be called before the {@link #accept(ClassVisitor,int)} method.
*
- * @param classWriter the {@link ClassWriter} to copy constant pool into.
+ * @param classWriter
+ * the {@link ClassWriter} to copy constant pool into.
*/
void copyPool(final ClassWriter classWriter) {
char[] buf = new char[maxStringLength];
@@ -292,82 +295,63 @@ public class ClassReader {
Item item = new Item(i);
int nameType;
switch (tag) {
- case ClassWriter.FIELD:
- case ClassWriter.METH:
- case ClassWriter.IMETH:
- nameType = items[readUnsignedShort(index + 2)];
- item.set(tag,
- readClass(index, buf),
- readUTF8(nameType, buf),
- readUTF8(nameType + 2, buf));
- break;
-
- case ClassWriter.INT:
- item.set(readInt(index));
- break;
-
- case ClassWriter.FLOAT:
- item.set(Float.intBitsToFloat(readInt(index)));
- break;
-
- case ClassWriter.NAME_TYPE:
- item.set(tag,
- readUTF8(index, buf),
- readUTF8(index + 2, buf),
- null);
- break;
-
- case ClassWriter.LONG:
- item.set(readLong(index));
- ++i;
- break;
-
- case ClassWriter.DOUBLE:
- item.set(Double.longBitsToDouble(readLong(index)));
- ++i;
- break;
-
- case ClassWriter.UTF8: {
- String s = strings[i];
- if (s == null) {
- index = items[i];
- s = strings[i] = readUTF(index + 2,
- readUnsignedShort(index),
- buf);
- }
- item.set(tag, s, null, null);
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ nameType = items[readUnsignedShort(index + 2)];
+ item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
+ readUTF8(nameType + 2, buf));
+ break;
+ case ClassWriter.INT:
+ item.set(readInt(index));
+ break;
+ case ClassWriter.FLOAT:
+ item.set(Float.intBitsToFloat(readInt(index)));
+ break;
+ case ClassWriter.NAME_TYPE:
+ item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
+ null);
+ break;
+ case ClassWriter.LONG:
+ item.set(readLong(index));
+ ++i;
+ break;
+ case ClassWriter.DOUBLE:
+ item.set(Double.longBitsToDouble(readLong(index)));
+ ++i;
+ break;
+ case ClassWriter.UTF8: {
+ String s = strings[i];
+ if (s == null) {
+ index = items[i];
+ s = strings[i] = readUTF(index + 2,
+ readUnsignedShort(index), buf);
}
- break;
-
- case ClassWriter.HANDLE: {
- int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
- nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
- item.set(ClassWriter.HANDLE_BASE + readByte(index),
- readClass(fieldOrMethodRef, buf),
- readUTF8(nameType, buf),
- readUTF8(nameType + 2, buf));
-
+ item.set(tag, s, null, null);
+ break;
+ }
+ case ClassWriter.HANDLE: {
+ int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
+ nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
+ item.set(ClassWriter.HANDLE_BASE + readByte(index),
+ readClass(fieldOrMethodRef, buf),
+ readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
+ break;
+ }
+ case ClassWriter.INDY:
+ if (classWriter.bootstrapMethods == null) {
+ copyBootstrapMethods(classWriter, items2, buf);
}
- break;
-
-
- case ClassWriter.INDY:
- if (classWriter.bootstrapMethods == null) {
- copyBootstrapMethods(classWriter, items2, buf);
- }
- nameType = items[readUnsignedShort(index + 2)];
- item.set(readUTF8(nameType, buf),
- readUTF8(nameType + 2, buf),
- readUnsignedShort(index));
- break;
-
-
- // case ClassWriter.STR:
- // case ClassWriter.CLASS:
- // case ClassWriter.MTYPE
- default:
- item.set(tag, readUTF8(index, buf), null, null);
- break;
+ nameType = items[readUnsignedShort(index + 2)];
+ item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
+ readUnsignedShort(index));
+ break;
+ // case ClassWriter.STR:
+ // case ClassWriter.CLASS:
+ // case ClassWriter.MTYPE
+ default:
+ item.set(tag, readUTF8(index, buf), null, null);
+ break;
}
int index2 = item.hashCode % items2.length;
@@ -382,77 +366,59 @@ public class ClassReader {
classWriter.index = ll;
}
- private void copyBootstrapMethods(ClassWriter classWriter, Item[] items2, char[] buf) {
- int i, j, k, u, v;
-
- // skip class header
- v = header;
- v += 8 + (readUnsignedShort(v + 6) << 1);
-
- // skips fields and methods
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
+ /**
+ * Copies the bootstrap method data into the given {@link ClassWriter}.
+ * Should be called before the {@link #accept(ClassVisitor,int)} method.
+ *
+ * @param classWriter
+ * the {@link ClassWriter} to copy bootstrap methods into.
+ */
+ private void copyBootstrapMethods(final ClassWriter classWriter,
+ final Item[] items, final char[] c) {
+ // finds the "BootstrapMethods" attribute
+ int u = getAttributes();
+ boolean found = false;
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ if ("BootstrapMethods".equals(attrName)) {
+ found = true;
+ break;
}
+ u += 6 + readInt(u + 4);
}
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
- }
+ if (!found) {
+ return;
}
-
- // read class attributes
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- String attrName = readUTF8(v, buf);
- int size = readInt(v + 2);
- if ("BootstrapMethods".equals(attrName)) {
- int boostrapMethodCount = readUnsignedShort(v + 6);
- int x = v + 8;
- for (j = 0; j < boostrapMethodCount; j++) {
- int hashCode = readConst(readUnsignedShort(x), buf).hashCode();
- k = readUnsignedShort(x + 2);
- u = x + 4;
- for(; k > 0; --k) {
- hashCode ^= readConst(readUnsignedShort(u), buf).hashCode();
- u += 2;
- }
- Item item = new Item(j);
- item.set(x - v - 8, hashCode & 0x7FFFFFFF);
-
- int index2 = item.hashCode % items2.length;
- item.next = items2[index2];
- items2[index2] = item;
-
- x = u;
- }
-
- classWriter.bootstrapMethodsCount = boostrapMethodCount;
- ByteVector bootstrapMethods = new ByteVector(size + 62);
- bootstrapMethods.putByteArray(b, v + 8, size - 2);
- classWriter.bootstrapMethods = bootstrapMethods;
- return;
+ // copies the bootstrap methods in the class writer
+ int boostrapMethodCount = readUnsignedShort(u + 8);
+ for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
+ int position = v - u - 10;
+ int hashCode = readConst(readUnsignedShort(v), c).hashCode();
+ for (int k = readUnsignedShort(v + 2); k > 0; --k) {
+ hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
+ v += 2;
}
- v += 6 + size;
+ v += 4;
+ Item item = new Item(j);
+ item.set(position, hashCode & 0x7FFFFFFF);
+ int index = item.hashCode % items.length;
+ item.next = items[index];
+ items[index] = item;
}
-
- // we are in trouble !!!
+ int attrSize = readInt(u + 4);
+ ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
+ bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
+ classWriter.bootstrapMethodsCount = boostrapMethodCount;
+ classWriter.bootstrapMethods = bootstrapMethods;
}
/**
* Constructs a new {@link ClassReader} object.
*
- * @param is an input stream from which to read the class.
- * @throws IOException if a problem occurs during reading.
+ * @param is
+ * an input stream from which to read the class.
+ * @throws IOException
+ * if a problem occurs during reading.
*/
public ClassReader(final InputStream is) throws IOException {
this(readClass(is, false));
@@ -461,25 +427,30 @@ public class ClassReader {
/**
* Constructs a new {@link ClassReader} object.
*
- * @param name the binary qualified name of the class to be read.
- * @throws IOException if an exception occurs during reading.
+ * @param name
+ * the binary qualified name of the class to be read.
+ * @throws IOException
+ * if an exception occurs during reading.
*/
public ClassReader(final String name) throws IOException {
- this(readClass(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
- + ".class"), true));
+ this(readClass(
+ ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+ + ".class"), true));
}
/**
* Reads the bytecode of a class.
*
- * @param is an input stream from which to read the class.
- * @param close true to close the input stream after reading.
+ * @param is
+ * an input stream from which to read the class.
+ * @param close
+ * true to close the input stream after reading.
* @return the bytecode read from the given input stream.
- * @throws IOException if a problem occurs during reading.
+ * @throws IOException
+ * if a problem occurs during reading.
*/
private static byte[] readClass(final InputStream is, boolean close)
- throws IOException
- {
+ throws IOException {
if (is == null) {
throw new IOException("Class not found");
}
@@ -520,14 +491,16 @@ public class ClassReader {
// ------------------------------------------------------------------------
/**
- * Makes the given visitor visit the Java class of this {@link ClassReader}.
- * This class is the one specified in the constructor (see
+ * Makes the given visitor visit the Java class of this {@link ClassReader}
+ * . This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
- * @param classVisitor the visitor that must visit this class.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
- * {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+ * @param classVisitor
+ * the visitor that must visit this class.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+ * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
*/
public void accept(final ClassVisitor classVisitor, final int flags) {
accept(classVisitor, new Attribute[0], flags);
@@ -538,1117 +511,923 @@ public class ClassReader {
* This class is the one specified in the constructor (see
* {@link #ClassReader(byte[]) ClassReader}).
*
- * @param classVisitor the visitor that must visit this class.
- * @param attrs prototypes of the attributes that must be parsed during the
- * visit of the class. Any attribute whose type is not equal to the
- * type of one the prototypes will not be parsed: its byte array
- * value will be passed unchanged to the ClassWriter. <i>This may
- * corrupt it if this value contains references to the constant pool,
- * or has syntactic or semantic links with a class element that has
- * been transformed by a class adapter between the reader and the
- * writer</i>.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES},
- * {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+ * @param classVisitor
+ * the visitor that must visit this class.
+ * @param attrs
+ * prototypes of the attributes that must be parsed during the
+ * visit of the class. Any attribute whose type is not equal to
+ * the type of one the prototypes will not be parsed: its byte
+ * array value will be passed unchanged to the ClassWriter.
+ * <i>This may corrupt it if this value contains references to
+ * the constant pool, or has syntactic or semantic links with a
+ * class element that has been transformed by a class adapter
+ * between the reader and the writer</i>.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+ * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
*/
- public void accept(
- final ClassVisitor classVisitor,
- final Attribute[] attrs,
- final int flags)
- {
- byte[] b = this.b; // the bytecode array
+ public void accept(final ClassVisitor classVisitor,
+ final Attribute[] attrs, final int flags) {
+ int u = header; // current offset in the class file
char[] c = new char[maxStringLength]; // buffer used to read strings
- int i, j, k; // loop variables
- int u, v, w; // indexes in b
- Attribute attr;
-
- int access;
- String name;
- String desc;
- String attrName;
- String signature;
- int anns = 0;
- int ianns = 0;
- Attribute cattrs = null;
-
- // visits the header
- u = header;
- access = readUnsignedShort(u);
- name = readClass(u + 2, c);
- v = items[readUnsignedShort(u + 4)];
- String superClassName = v == 0 ? null : readUTF8(v, c);
- String[] implementedItfs = new String[readUnsignedShort(u + 6)];
- w = 0;
+
+ Context context = new Context();
+ context.attrs = attrs;
+ context.flags = flags;
+ context.buffer = c;
+
+ // reads the class declaration
+ int access = readUnsignedShort(u);
+ String name = readClass(u + 2, c);
+ String superClass = readClass(u + 4, c);
+ String[] interfaces = new String[readUnsignedShort(u + 6)];
u += 8;
- for (i = 0; i < implementedItfs.length; ++i) {
- implementedItfs[i] = readClass(u, c);
+ for (int i = 0; i < interfaces.length; ++i) {
+ interfaces[i] = readClass(u, c);
u += 2;
}
- boolean skipCode = (flags & SKIP_CODE) != 0;
- boolean skipDebug = (flags & SKIP_DEBUG) != 0;
- boolean unzip = (flags & EXPAND_FRAMES) != 0;
-
- // skips fields and methods
- v = u;
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
- }
- }
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- j = readUnsignedShort(v + 6);
- v += 8;
- for (; j > 0; --j) {
- v += 6 + readInt(v + 2);
- }
- }
- // reads the class's attributes
- signature = null;
+ // reads the class attributes
+ String signature = null;
String sourceFile = null;
String sourceDebug = null;
String enclosingOwner = null;
String enclosingName = null;
String enclosingDesc = null;
- int[] bootstrapMethods = null; // start indexed of the bsms
+ int anns = 0;
+ int ianns = 0;
+ int innerClasses = 0;
+ Attribute attributes = null;
- i = readUnsignedShort(v);
- v += 2;
- for (; i > 0; --i) {
- attrName = readUTF8(v, c);
+ u = getAttributes();
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
// tests are sorted in decreasing frequency order
// (based on frequencies observed on typical classes)
if ("SourceFile".equals(attrName)) {
- sourceFile = readUTF8(v + 6, c);
+ sourceFile = readUTF8(u + 8, c);
} else if ("InnerClasses".equals(attrName)) {
- w = v + 6;
+ innerClasses = u + 8;
} else if ("EnclosingMethod".equals(attrName)) {
- enclosingOwner = readClass(v + 6, c);
- int item = readUnsignedShort(v + 8);
+ enclosingOwner = readClass(u + 8, c);
+ int item = readUnsignedShort(u + 10);
if (item != 0) {
enclosingName = readUTF8(items[item], c);
enclosingDesc = readUTF8(items[item] + 2, c);
}
} else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(v + 6, c);
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = v + 6;
+ signature = readUTF8(u + 8, c);
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
} else if ("Deprecated".equals(attrName)) {
access |= Opcodes.ACC_DEPRECATED;
} else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+ access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
} else if ("SourceDebugExtension".equals(attrName)) {
- int len = readInt(v + 2);
- sourceDebug = readUTF(v + 6, len, new char[len]);
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = v + 6;
+ int len = readInt(u + 4);
+ sourceDebug = readUTF(u + 8, len, new char[len]);
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
} else if ("BootstrapMethods".equals(attrName)) {
- int boostrapMethodCount = readUnsignedShort(v + 6);
- bootstrapMethods = new int[boostrapMethodCount];
- int x = v + 8;
- for (j = 0; j < boostrapMethodCount; j++) {
- bootstrapMethods[j] = x;
- x += 2 + readUnsignedShort(x + 2) << 1;
+ int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
+ for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
+ bootstrapMethods[j] = v;
+ v += 2 + readUnsignedShort(v + 2) << 1;
}
+ context.bootstrapMethods = bootstrapMethods;
} else {
- attr = readAttribute(attrs,
- attrName,
- v + 6,
- readInt(v + 2),
- c,
- -1,
- null);
+ Attribute attr = readAttribute(attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
+ attr.next = attributes;
+ attributes = attr;
}
}
- v += 6 + readInt(v + 2);
+ u += 6 + readInt(u + 4);
}
- // calls the visit method
- classVisitor.visit(readInt(4),
- access,
- name,
- signature,
- superClassName,
- implementedItfs);
-
- // calls the visitSource method
- if (!skipDebug && (sourceFile != null || sourceDebug != null)) {
+
+ // visits the class declaration
+ classVisitor.visit(readInt(items[1] - 7), access, name, signature,
+ superClass, interfaces);
+
+ // visits the source and debug info
+ if ((flags & SKIP_DEBUG) == 0
+ && (sourceFile != null || sourceDebug != null)) {
classVisitor.visitSource(sourceFile, sourceDebug);
}
- // calls the visitOuterClass method
+ // visits the outer class
if (enclosingOwner != null) {
- classVisitor.visitOuterClass(enclosingOwner,
- enclosingName,
+ classVisitor.visitOuterClass(enclosingOwner, enclosingName,
enclosingDesc);
}
// visits the class annotations
- if (ANNOTATIONS) {
- for (i = 1; i >= 0; --i) {
- v = i == 0 ? ianns : anns;
- if (v != 0) {
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- v = readAnnotationValues(v + 2,
- c,
- true,
- classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
- }
- }
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ classVisitor.visitAnnotation(readUTF8(v, c), false));
}
}
- // visits the class attributes
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- classVisitor.visitAttribute(cattrs);
- cattrs = attr;
+ // visits the attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ classVisitor.visitAttribute(attributes);
+ attributes = attr;
}
- // calls the visitInnerClass method
- if (w != 0) {
- i = readUnsignedShort(w);
- w += 2;
- for (; i > 0; --i) {
- classVisitor.visitInnerClass(readUnsignedShort(w) == 0
- ? null
- : readClass(w, c), readUnsignedShort(w + 2) == 0
- ? null
- : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
- ? null
- : readUTF8(w + 4, c), readUnsignedShort(w + 6));
- w += 8;
+ // visits the inner classes
+ if (innerClasses != 0) {
+ int v = innerClasses + 2;
+ for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
+ classVisitor.visitInnerClass(readClass(v, c),
+ readClass(v + 2, c), readUTF8(v + 4, c),
+ readUnsignedShort(v + 6));
+ v += 8;
}
}
- // visits the fields
- i = readUnsignedShort(u);
+ // visits the fields and methods
+ u = header + 10 + 2 * interfaces.length;
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ u = readField(classVisitor, context, u);
+ }
u += 2;
- for (; i > 0; --i) {
- access = readUnsignedShort(u);
- name = readUTF8(u + 2, c);
- desc = readUTF8(u + 4, c);
- // visits the field's attributes and looks for a ConstantValue
- // attribute
- int fieldValueItem = 0;
- signature = null;
- anns = 0;
- ianns = 0;
- cattrs = null;
-
- j = readUnsignedShort(u + 6);
- u += 8;
- for (; j > 0; --j) {
- attrName = readUTF8(u, c);
- // tests are sorted in decreasing frequency order
- // (based on frequencies observed on typical classes)
- if ("ConstantValue".equals(attrName)) {
- fieldValueItem = readUnsignedShort(u + 6);
- } else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(u + 6, c);
- } else if ("Deprecated".equals(attrName)) {
- access |= Opcodes.ACC_DEPRECATED;
- } else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = u + 6;
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = u + 6;
- } else {
- attr = readAttribute(attrs,
- attrName,
- u + 6,
- readInt(u + 2),
- c,
- -1,
- null);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
+ for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+ u = readMethod(classVisitor, context, u);
+ }
+
+ // visits the end of the class
+ classVisitor.visitEnd();
+ }
+
+ /**
+ * Reads a field and makes the given visitor visit it.
+ *
+ * @param classVisitor
+ * the visitor that must visit the field.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the field in the class file.
+ * @return the offset of the first byte following the field in the class.
+ */
+ private int readField(final ClassVisitor classVisitor,
+ final Context context, int u) {
+ // reads the field declaration
+ char[] c = context.buffer;
+ int access = readUnsignedShort(u);
+ String name = readUTF8(u + 2, c);
+ String desc = readUTF8(u + 4, c);
+ u += 6;
+
+ // reads the field attributes
+ String signature = null;
+ int anns = 0;
+ int ianns = 0;
+ Object value = null;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ // tests are sorted in decreasing frequency order
+ // (based on frequencies observed on typical classes)
+ if ("ConstantValue".equals(attrName)) {
+ int item = readUnsignedShort(u + 8);
+ value = item == 0 ? null : readConst(item, c);
+ } else if (SIGNATURES && "Signature".equals(attrName)) {
+ signature = readUTF8(u + 8, c);
+ } else if ("Deprecated".equals(attrName)) {
+ access |= Opcodes.ACC_DEPRECATED;
+ } else if ("Synthetic".equals(attrName)) {
+ access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
+ } else {
+ Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
- u += 6 + readInt(u + 2);
}
- // visits the field
- FieldVisitor fv = classVisitor.visitField(access,
- name,
- desc,
- signature,
- fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
- // visits the field annotations and attributes
- if (fv != null) {
- if (ANNOTATIONS) {
- for (j = 1; j >= 0; --j) {
- v = j == 0 ? ianns : anns;
- if (v != 0) {
- k = readUnsignedShort(v);
- v += 2;
- for (; k > 0; --k) {
- v = readAnnotationValues(v + 2,
- c,
- true,
- fv.visitAnnotation(readUTF8(v, c), j != 0));
- }
- }
- }
- }
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- fv.visitAttribute(cattrs);
- cattrs = attr;
- }
- fv.visitEnd();
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
+
+ // visits the field declaration
+ FieldVisitor fv = classVisitor.visitField(access, name, desc,
+ signature, value);
+ if (fv == null) {
+ return u;
+ }
+
+ // visits the field annotations
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ fv.visitAnnotation(readUTF8(v, c), false));
}
}
- // visits the methods
- i = readUnsignedShort(u);
- u += 2;
- for (; i > 0; --i) {
- int u0 = u + 6;
- access = readUnsignedShort(u);
- name = readUTF8(u + 2, c);
- desc = readUTF8(u + 4, c);
- signature = null;
- anns = 0;
- ianns = 0;
- int dann = 0;
- int mpanns = 0;
- int impanns = 0;
- cattrs = null;
- v = 0;
- w = 0;
-
- // looks for Code and Exceptions attributes
- j = readUnsignedShort(u + 6);
- u += 8;
- for (; j > 0; --j) {
- attrName = readUTF8(u, c);
- int attrSize = readInt(u + 2);
- u += 6;
- // tests are sorted in decreasing frequency order
- // (based on frequencies observed on typical classes)
- if ("Code".equals(attrName)) {
- if (!skipCode) {
- v = u;
- }
- } else if ("Exceptions".equals(attrName)) {
- w = u;
- } else if (SIGNATURES && "Signature".equals(attrName)) {
- signature = readUTF8(u, c);
- } else if ("Deprecated".equals(attrName)) {
- access |= Opcodes.ACC_DEPRECATED;
- } else if (ANNOTATIONS && "RuntimeVisibleAnnotations".equals(attrName)) {
- anns = u;
- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
- dann = u;
- } else if ("Synthetic".equals(attrName)) {
- access |= Opcodes.ACC_SYNTHETIC | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
- } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
- ianns = u;
- } else if (ANNOTATIONS && "RuntimeVisibleParameterAnnotations".equals(attrName))
- {
- mpanns = u;
- } else if (ANNOTATIONS && "RuntimeInvisibleParameterAnnotations".equals(attrName))
- {
- impanns = u;
- } else {
- attr = readAttribute(attrs,
- attrName,
- u,
- attrSize,
- c,
- -1,
- null);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
+ // visits the field attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ fv.visitAttribute(attributes);
+ attributes = attr;
+ }
+
+ // visits the end of the field
+ fv.visitEnd();
+
+ return u;
+ }
+
+ /**
+ * Reads a method and makes the given visitor visit it.
+ *
+ * @param classVisitor
+ * the visitor that must visit the method.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the method in the class file.
+ * @return the offset of the first byte following the method in the class.
+ */
+ private int readMethod(final ClassVisitor classVisitor,
+ final Context context, int u) {
+ // reads the method declaration
+ char[] c = context.buffer;
+ int access = readUnsignedShort(u);
+ String name = readUTF8(u + 2, c);
+ String desc = readUTF8(u + 4, c);
+ u += 6;
+
+ // reads the method attributes
+ int code = 0;
+ int exception = 0;
+ String[] exceptions = null;
+ String signature = null;
+ int anns = 0;
+ int ianns = 0;
+ int dann = 0;
+ int mpanns = 0;
+ int impanns = 0;
+ int firstAttribute = u;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ // tests are sorted in decreasing frequency order
+ // (based on frequencies observed on typical classes)
+ if ("Code".equals(attrName)) {
+ if ((context.flags & SKIP_CODE) == 0) {
+ code = u + 8;
}
- u += attrSize;
- }
- // reads declared exceptions
- String[] exceptions;
- if (w == 0) {
- exceptions = null;
+ } else if ("Exceptions".equals(attrName)) {
+ exceptions = new String[readUnsignedShort(u + 8)];
+ exception = u + 10;
+ for (int j = 0; j < exceptions.length; ++j) {
+ exceptions[j] = readClass(exception, c);
+ exception += 2;
+ }
+ } else if (SIGNATURES && "Signature".equals(attrName)) {
+ signature = readUTF8(u + 8, c);
+ } else if ("Deprecated".equals(attrName)) {
+ access |= Opcodes.ACC_DEPRECATED;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleAnnotations".equals(attrName)) {
+ anns = u + 8;
+ } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+ dann = u + 8;
+ } else if ("Synthetic".equals(attrName)) {
+ access |= Opcodes.ACC_SYNTHETIC
+ | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleAnnotations".equals(attrName)) {
+ ianns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+ mpanns = u + 8;
+ } else if (ANNOTATIONS
+ && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+ impanns = u + 8;
} else {
- exceptions = new String[readUnsignedShort(w)];
- w += 2;
- for (j = 0; j < exceptions.length; ++j) {
- exceptions[j] = readClass(w, c);
- w += 2;
+ Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+ readInt(u + 4), c, -1, null);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
}
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
- // visits the method's code, if any
- MethodVisitor mv = classVisitor.visitMethod(access,
- name,
- desc,
- signature,
- exceptions);
+ // visits the method declaration
+ MethodVisitor mv = classVisitor.visitMethod(access, name, desc,
+ signature, exceptions);
+ if (mv == null) {
+ return u;
+ }
- if (mv != null) {
- /*
- * if the returned MethodVisitor is in fact a MethodWriter, it
- * means there is no method adapter between the reader and the
- * writer. If, in addition, the writer's constant pool was
- * copied from this reader (mw.cw.cr == this), and the signature
- * and exceptions of the method have not been changed, then it
- * is possible to skip all visit events and just copy the
- * original code of the method to the writer (the access, name
- * and descriptor can have been changed, this is not important
- * since they are not copied as is from the reader).
- */
- if (WRITER && mv instanceof MethodWriter) {
- MethodWriter mw = (MethodWriter) mv;
- if (mw.cw.cr == this) {
- if (signature == mw.signature) {
- boolean sameExceptions = false;
- if (exceptions == null) {
- sameExceptions = mw.exceptionCount == 0;
- } else {
- if (exceptions.length == mw.exceptionCount) {
- sameExceptions = true;
- for (j = exceptions.length - 1; j >= 0; --j)
- {
- w -= 2;
- if (mw.exceptions[j] != readUnsignedShort(w))
- {
- sameExceptions = false;
- break;
- }
- }
- }
- }
- if (sameExceptions) {
- /*
- * we do not copy directly the code into
- * MethodWriter to save a byte array copy
- * operation. The real copy will be done in
- * ClassWriter.toByteArray().
- */
- mw.classReaderOffset = u0;
- mw.classReaderLength = u - u0;
- continue;
- }
+ /*
+ * if the returned MethodVisitor is in fact a MethodWriter, it means
+ * there is no method adapter between the reader and the writer. If, in
+ * addition, the writer's constant pool was copied from this reader
+ * (mw.cw.cr == this), and the signature and exceptions of the method
+ * have not been changed, then it is possible to skip all visit events
+ * and just copy the original code of the method to the writer (the
+ * access, name and descriptor can have been changed, this is not
+ * important since they are not copied as is from the reader).
+ */
+ if (WRITER && mv instanceof MethodWriter) {
+ MethodWriter mw = (MethodWriter) mv;
+ if (mw.cw.cr == this && signature == mw.signature) {
+ boolean sameExceptions = false;
+ if (exceptions == null) {
+ sameExceptions = mw.exceptionCount == 0;
+ } else if (exceptions.length == mw.exceptionCount) {
+ sameExceptions = true;
+ for (int j = exceptions.length - 1; j >= 0; --j) {
+ exception -= 2;
+ if (mw.exceptions[j] != readUnsignedShort(exception)) {
+ sameExceptions = false;
+ break;
}
}
}
-
- if (ANNOTATIONS && dann != 0) {
- AnnotationVisitor dv = mv.visitAnnotationDefault();
- readAnnotationValue(dann, c, null, dv);
- if (dv != null) {
- dv.visitEnd();
- }
- }
- if (ANNOTATIONS) {
- for (j = 1; j >= 0; --j) {
- w = j == 0 ? ianns : anns;
- if (w != 0) {
- k = readUnsignedShort(w);
- w += 2;
- for (; k > 0; --k) {
- w = readAnnotationValues(w + 2,
- c,
- true,
- mv.visitAnnotation(readUTF8(w, c), j != 0));
- }
- }
- }
+ if (sameExceptions) {
+ /*
+ * we do not copy directly the code into MethodWriter to
+ * save a byte array copy operation. The real copy will be
+ * done in ClassWriter.toByteArray().
+ */
+ mw.classReaderOffset = firstAttribute;
+ mw.classReaderLength = u - firstAttribute;
+ return u;
}
- if (ANNOTATIONS && mpanns != 0) {
- readParameterAnnotations(mpanns, desc, c, true, mv);
+ }
+ }
+
+ // visits the method annotations
+ if (ANNOTATIONS && dann != 0) {
+ AnnotationVisitor dv = mv.visitAnnotationDefault();
+ readAnnotationValue(dann, c, null, dv);
+ if (dv != null) {
+ dv.visitEnd();
+ }
+ }
+ if (ANNOTATIONS && anns != 0) {
+ for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitAnnotation(readUTF8(v, c), true));
+ }
+ }
+ if (ANNOTATIONS && ianns != 0) {
+ for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+ v = readAnnotationValues(v + 2, c, true,
+ mv.visitAnnotation(readUTF8(v, c), false));
+ }
+ }
+ if (ANNOTATIONS && mpanns != 0) {
+ readParameterAnnotations(mpanns, desc, c, true, mv);
+ }
+ if (ANNOTATIONS && impanns != 0) {
+ readParameterAnnotations(impanns, desc, c, false, mv);
+ }
+
+ // visits the method attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ mv.visitAttribute(attributes);
+ attributes = attr;
+ }
+
+ // visits the method code
+ if (code != 0) {
+ context.access = access;
+ context.name = name;
+ context.desc = desc;
+ mv.visitCode();
+ readCode(mv, context, code);
+ }
+
+ // visits the end of the method
+ mv.visitEnd();
+
+ return u;
+ }
+
+ /**
+ * Reads the bytecode of a method and makes the given visitor visit it.
+ *
+ * @param mv
+ * the visitor that must visit the method's code.
+ * @param context
+ * information about the class being parsed.
+ * @param u
+ * the start offset of the code attribute in the class file.
+ */
+ private void readCode(final MethodVisitor mv, final Context context, int u) {
+ // reads the header
+ byte[] b = this.b;
+ char[] c = context.buffer;
+ int maxStack = readUnsignedShort(u);
+ int maxLocals = readUnsignedShort(u + 2);
+ int codeLength = readInt(u + 4);
+ u += 8;
+
+ // reads the bytecode to find the labels
+ int codeStart = u;
+ int codeEnd = u + codeLength;
+ Label[] labels = new Label[codeLength + 2];
+ readLabel(codeLength + 1, labels);
+ while (u < codeEnd) {
+ int offset = u - codeStart;
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ case ClassWriter.IMPLVAR_INSN:
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ readLabel(offset + readShort(u + 1), labels);
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ readLabel(offset + readInt(u + 1), labels);
+ u += 5;
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ u += 6;
+ } else {
+ u += 4;
}
- if (ANNOTATIONS && impanns != 0) {
- readParameterAnnotations(impanns, desc, c, false, mv);
+ break;
+ case ClassWriter.TABL_INSN:
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ readLabel(offset + readInt(u), labels);
+ for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
+ readLabel(offset + readInt(u + 12), labels);
+ u += 4;
}
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- mv.visitAttribute(cattrs);
- cattrs = attr;
+ u += 12;
+ break;
+ case ClassWriter.LOOK_INSN:
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ readLabel(offset + readInt(u), labels);
+ for (int i = readInt(u + 4); i > 0; --i) {
+ readLabel(offset + readInt(u + 12), labels);
+ u += 8;
}
+ u += 8;
+ break;
+ case ClassWriter.VAR_INSN:
+ case ClassWriter.SBYTE_INSN:
+ case ClassWriter.LDC_INSN:
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ case ClassWriter.LDCW_INSN:
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.TYPE_INSN:
+ case ClassWriter.IINC_INSN:
+ u += 3;
+ break;
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
+ u += 5;
+ break;
+ // case MANA_INSN:
+ default:
+ u += 4;
+ break;
}
+ }
- if (mv != null && v != 0) {
- int maxStack = readUnsignedShort(v);
- int maxLocals = readUnsignedShort(v + 2);
- int codeLength = readInt(v + 4);
- v += 8;
+ // reads the try catch entries to find the labels, and also visits them
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ Label start = readLabel(readUnsignedShort(u + 2), labels);
+ Label end = readLabel(readUnsignedShort(u + 4), labels);
+ Label handler = readLabel(readUnsignedShort(u + 6), labels);
+ String type = readUTF8(items[readUnsignedShort(u + 8)], c);
+ mv.visitTryCatchBlock(start, end, handler, type);
+ u += 8;
+ }
+ u += 2;
- int codeStart = v;
- int codeEnd = v + codeLength;
-
- mv.visitCode();
-
- // 1st phase: finds the labels
- int label;
- Label[] labels = new Label[codeLength + 2];
- readLabel(codeLength + 1, labels);
- while (v < codeEnd) {
- w = v - codeStart;
- int opcode = b[v] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- v += 1;
- break;
- case ClassWriter.LABEL_INSN:
- readLabel(w + readShort(v + 1), labels);
- v += 3;
- break;
- case ClassWriter.LABELW_INSN:
- readLabel(w + readInt(v + 1), labels);
- v += 5;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[v + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- v += 6;
- } else {
- v += 4;
- }
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes*
- v = v + 4 - (w & 3);
- // reads instruction
- readLabel(w + readInt(v), labels);
- j = readInt(v + 8) - readInt(v + 4) + 1;
- v += 12;
- for (; j > 0; --j) {
- readLabel(w + readInt(v), labels);
- v += 4;
- }
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes*
- v = v + 4 - (w & 3);
- // reads instruction
- readLabel(w + readInt(v), labels);
- j = readInt(v + 4);
- v += 8;
- for (; j > 0; --j) {
- readLabel(w + readInt(v + 4), labels);
- v += 8;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- v += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- v += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- v += 5;
- break;
- // case MANA_INSN:
- default:
- v += 4;
- break;
- }
- }
- // parses the try catch entries
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- Label start = readLabel(readUnsignedShort(v), labels);
- Label end = readLabel(readUnsignedShort(v + 2), labels);
- Label handler = readLabel(readUnsignedShort(v + 4), labels);
- int type = readUnsignedShort(v + 6);
- if (type == 0) {
- mv.visitTryCatchBlock(start, end, handler, null);
- } else {
- mv.visitTryCatchBlock(start,
- end,
- handler,
- readUTF8(items[type], c));
- }
- v += 8;
- }
- // parses the local variable, line number tables, and code
- // attributes
- int varTable = 0;
- int varTypeTable = 0;
- int stackMap = 0;
- int stackMapSize = 0;
- int frameCount = 0;
- int frameMode = 0;
- int frameOffset = 0;
- int frameLocalCount = 0;
- int frameLocalDiff = 0;
- int frameStackCount = 0;
- Object[] frameLocal = null;
- Object[] frameStack = null;
- boolean zip = true;
- cattrs = null;
- j = readUnsignedShort(v);
- v += 2;
- for (; j > 0; --j) {
- attrName = readUTF8(v, c);
- if ("LocalVariableTable".equals(attrName)) {
- if (!skipDebug) {
- varTable = v + 6;
- k = readUnsignedShort(v + 6);
- w = v + 8;
- for (; k > 0; --k) {
- label = readUnsignedShort(w);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- label += readUnsignedShort(w + 2);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- w += 10;
- }
- }
- } else if ("LocalVariableTypeTable".equals(attrName)) {
- varTypeTable = v + 6;
- } else if ("LineNumberTable".equals(attrName)) {
- if (!skipDebug) {
- k = readUnsignedShort(v + 6);
- w = v + 8;
- for (; k > 0; --k) {
- label = readUnsignedShort(w);
- if (labels[label] == null) {
- readLabel(label, labels).status |= Label.DEBUG;
- }
- labels[label].line = readUnsignedShort(w + 2);
- w += 4;
- }
- }
- } else if (FRAMES && "StackMapTable".equals(attrName)) {
- if ((flags & SKIP_FRAMES) == 0) {
- stackMap = v + 8;
- stackMapSize = readInt(v + 2);
- frameCount = readUnsignedShort(v + 6);
+ // reads the code attributes
+ int varTable = 0;
+ int varTypeTable = 0;
+ boolean zip = true;
+ boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
+ int stackMap = 0;
+ int stackMapSize = 0;
+ int frameCount = 0;
+ Context frame = null;
+ Attribute attributes = null;
+
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ String attrName = readUTF8(u + 2, c);
+ if ("LocalVariableTable".equals(attrName)) {
+ if ((context.flags & SKIP_DEBUG) == 0) {
+ varTable = u + 8;
+ for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+ int label = readUnsignedShort(v + 10);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
}
- /*
- * here we do not extract the labels corresponding to
- * the attribute content. This would require a full
- * parsing of the attribute, which would need to be
- * repeated in the second phase (see below). Instead the
- * content of the attribute is read one frame at a time
- * (i.e. after a frame has been visited, the next frame
- * is read), and the labels it contains are also
- * extracted one frame at a time. Thanks to the ordering
- * of frames, having only a "one frame lookahead" is not
- * a problem, i.e. it is not possible to see an offset
- * smaller than the offset of the current insn and for
- * which no Label exist.
- */
- /*
- * This is not true for UNINITIALIZED type offsets. We
- * solve this by parsing the stack map table without a
- * full decoding (see below).
- */
- } else if (FRAMES && "StackMap".equals(attrName)) {
- if ((flags & SKIP_FRAMES) == 0) {
- stackMap = v + 8;
- stackMapSize = readInt(v + 2);
- frameCount = readUnsignedShort(v + 6);
- zip = false;
- }
- /*
- * IMPORTANT! here we assume that the frames are
- * ordered, as in the StackMapTable attribute, although
- * this is not guaranteed by the attribute format.
- */
- } else {
- for (k = 0; k < attrs.length; ++k) {
- if (attrs[k].type.equals(attrName)) {
- attr = attrs[k].read(this,
- v + 6,
- readInt(v + 2),
- c,
- codeStart - 8,
- labels);
- if (attr != null) {
- attr.next = cattrs;
- cattrs = attr;
- }
- }
+ label += readUnsignedShort(v + 12);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
}
+ v += 10;
}
- v += 6 + readInt(v + 2);
}
-
- // 2nd phase: visits each instruction
- if (FRAMES && stackMap != 0) {
- // creates the very first (implicit) frame from the method
- // descriptor
- frameLocal = new Object[maxLocals];
- frameStack = new Object[maxStack];
- if (unzip) {
- int local = 0;
- if ((access & Opcodes.ACC_STATIC) == 0) {
- if ("<init>".equals(name)) {
- frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
- } else {
- frameLocal[local++] = readClass(header + 2, c);
- }
- }
- j = 1;
- loop: while (true) {
- k = j;
- switch (desc.charAt(j++)) {
- case 'Z':
- case 'C':
- case 'B':
- case 'S':
- case 'I':
- frameLocal[local++] = Opcodes.INTEGER;
- break;
- case 'F':
- frameLocal[local++] = Opcodes.FLOAT;
- break;
- case 'J':
- frameLocal[local++] = Opcodes.LONG;
- break;
- case 'D':
- frameLocal[local++] = Opcodes.DOUBLE;
- break;
- case '[':
- while (desc.charAt(j) == '[') {
- ++j;
- }
- if (desc.charAt(j) == 'L') {
- ++j;
- while (desc.charAt(j) != ';') {
- ++j;
- }
- }
- frameLocal[local++] = desc.substring(k, ++j);
- break;
- case 'L':
- while (desc.charAt(j) != ';') {
- ++j;
- }
- frameLocal[local++] = desc.substring(k + 1,
- j++);
- break;
- default:
- break loop;
- }
+ } else if ("LocalVariableTypeTable".equals(attrName)) {
+ varTypeTable = u + 8;
+ } else if ("LineNumberTable".equals(attrName)) {
+ if ((context.flags & SKIP_DEBUG) == 0) {
+ for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+ int label = readUnsignedShort(v + 10);
+ if (labels[label] == null) {
+ readLabel(label, labels).status |= Label.DEBUG;
}
- frameLocalCount = local;
+ labels[label].line = readUnsignedShort(v + 12);
+ v += 4;
}
- /*
- * for the first explicit frame the offset is not
- * offset_delta + 1 but only offset_delta; setting the
- * implicit frame offset to -1 allow the use of the
- * "offset_delta + 1" rule in all cases
- */
- frameOffset = -1;
- /*
- * Finds labels for UNINITIALIZED frame types. Instead of
- * decoding each element of the stack map table, we look
- * for 3 consecutive bytes that "look like" an UNINITIALIZED
- * type (tag 8, offset within code bounds, NEW instruction
- * at this offset). We may find false positives (i.e. not
- * real UNINITIALIZED types), but this should be rare, and
- * the only consequence will be the creation of an unneeded
- * label. This is better than creating a label for each NEW
- * instruction, and faster than fully decoding the whole
- * stack map table.
- */
- for (j = stackMap; j < stackMap + stackMapSize - 2; ++j) {
- if (b[j] == 8) { // UNINITIALIZED FRAME TYPE
- k = readUnsignedShort(j + 1);
- if (k >= 0 && k < codeLength) { // potential offset
- if ((b[codeStart + k] & 0xFF) == Opcodes.NEW) { // NEW at this offset
- readLabel(k, labels);
- }
- }
+ }
+ } else if (FRAMES && "StackMapTable".equals(attrName)) {
+ if ((context.flags & SKIP_FRAMES) == 0) {
+ stackMap = u + 10;
+ stackMapSize = readInt(u + 4);
+ frameCount = readUnsignedShort(u + 8);
+ }
+ /*
+ * here we do not extract the labels corresponding to the
+ * attribute content. This would require a full parsing of the
+ * attribute, which would need to be repeated in the second
+ * phase (see below). Instead the content of the attribute is
+ * read one frame at a time (i.e. after a frame has been
+ * visited, the next frame is read), and the labels it contains
+ * are also extracted one frame at a time. Thanks to the
+ * ordering of frames, having only a "one frame lookahead" is
+ * not a problem, i.e. it is not possible to see an offset
+ * smaller than the offset of the current insn and for which no
+ * Label exist.
+ */
+ /*
+ * This is not true for UNINITIALIZED type offsets. We solve
+ * this by parsing the stack map table without a full decoding
+ * (see below).
+ */
+ } else if (FRAMES && "StackMap".equals(attrName)) {
+ if ((context.flags & SKIP_FRAMES) == 0) {
+ zip = false;
+ stackMap = u + 10;
+ stackMapSize = readInt(u + 4);
+ frameCount = readUnsignedShort(u + 8);
+ }
+ /*
+ * IMPORTANT! here we assume that the frames are ordered, as in
+ * the StackMapTable attribute, although this is not guaranteed
+ * by the attribute format.
+ */
+ } else {
+ for (int j = 0; j < context.attrs.length; ++j) {
+ if (context.attrs[j].type.equals(attrName)) {
+ Attribute attr = context.attrs[j].read(this, u + 8,
+ readInt(u + 4), c, codeStart - 8, labels);
+ if (attr != null) {
+ attr.next = attributes;
+ attributes = attr;
}
}
}
- v = codeStart;
- Label l;
- while (v < codeEnd) {
- w = v - codeStart;
-
- l = labels[w];
- if (l != null) {
- mv.visitLabel(l);
- if (!skipDebug && l.line > 0) {
- mv.visitLineNumber(l.line, l);
+ }
+ u += 6 + readInt(u + 4);
+ }
+ u += 2;
+
+ // generates the first (implicit) stack map frame
+ if (FRAMES && stackMap != 0) {
+ /*
+ * for the first explicit frame the offset is not offset_delta + 1
+ * but only offset_delta; setting the implicit frame offset to -1
+ * allow the use of the "offset_delta + 1" rule in all cases
+ */
+ frame = context;
+ frame.offset = -1;
+ frame.mode = 0;
+ frame.localCount = 0;
+ frame.localDiff = 0;
+ frame.stackCount = 0;
+ frame.local = new Object[maxLocals];
+ frame.stack = new Object[maxStack];
+ if (unzip) {
+ getImplicitFrame(context);
+ }
+ /*
+ * Finds labels for UNINITIALIZED frame types. Instead of decoding
+ * each element of the stack map table, we look for 3 consecutive
+ * bytes that "look like" an UNINITIALIZED type (tag 8, offset
+ * within code bounds, NEW instruction at this offset). We may find
+ * false positives (i.e. not real UNINITIALIZED types), but this
+ * should be rare, and the only consequence will be the creation of
+ * an unneeded label. This is better than creating a label for each
+ * NEW instruction, and faster than fully decoding the whole stack
+ * map table.
+ */
+ for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
+ if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
+ int v = readUnsignedShort(i + 1);
+ if (v >= 0 && v < codeLength) {
+ if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
+ readLabel(v, labels);
}
}
+ }
+ }
+ }
- while (FRAMES && frameLocal != null
- && (frameOffset == w || frameOffset == -1))
- {
- // if there is a frame for this offset,
- // makes the visitor visit it,
- // and reads the next frame if there is one.
- if (!zip || unzip) {
- mv.visitFrame(Opcodes.F_NEW,
- frameLocalCount,
- frameLocal,
- frameStackCount,
- frameStack);
- } else if (frameOffset != -1) {
- mv.visitFrame(frameMode,
- frameLocalDiff,
- frameLocal,
- frameStackCount,
- frameStack);
- }
+ // visits the instructions
+ u = codeStart;
+ while (u < codeEnd) {
+ int offset = u - codeStart;
+
+ // visits the label and line number for this offset, if any
+ Label l = labels[offset];
+ if (l != null) {
+ mv.visitLabel(l);
+ if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
+ mv.visitLineNumber(l.line, l);
+ }
+ }
- if (frameCount > 0) {
- int tag, delta, n;
- if (zip) {
- tag = b[stackMap++] & 0xFF;
- } else {
- tag = MethodWriter.FULL_FRAME;
- frameOffset = -1;
- }
- frameLocalDiff = 0;
- if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
- {
- delta = tag;
- frameMode = Opcodes.F_SAME;
- frameStackCount = 0;
- } else if (tag < MethodWriter.RESERVED) {
- delta = tag
- - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
- stackMap = readFrameType(frameStack,
- 0,
- stackMap,
- c,
- labels);
- frameMode = Opcodes.F_SAME1;
- frameStackCount = 1;
- } else {
- delta = readUnsignedShort(stackMap);
- stackMap += 2;
- if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- {
- stackMap = readFrameType(frameStack,
- 0,
- stackMap,
- c,
- labels);
- frameMode = Opcodes.F_SAME1;
- frameStackCount = 1;
- } else if (tag >= MethodWriter.CHOP_FRAME
- && tag < MethodWriter.SAME_FRAME_EXTENDED)
- {
- frameMode = Opcodes.F_CHOP;
- frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
- - tag;
- frameLocalCount -= frameLocalDiff;
- frameStackCount = 0;
- } else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
- {
- frameMode = Opcodes.F_SAME;
- frameStackCount = 0;
- } else if (tag < MethodWriter.FULL_FRAME) {
- j = unzip ? frameLocalCount : 0;
- for (k = tag
- - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
- {
- stackMap = readFrameType(frameLocal,
- j++,
- stackMap,
- c,
- labels);
- }
- frameMode = Opcodes.F_APPEND;
- frameLocalDiff = tag
- - MethodWriter.SAME_FRAME_EXTENDED;
- frameLocalCount += frameLocalDiff;
- frameStackCount = 0;
- } else { // if (tag == FULL_FRAME) {
- frameMode = Opcodes.F_FULL;
- n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
- stackMap += 2;
- for (j = 0; n > 0; n--) {
- stackMap = readFrameType(frameLocal,
- j++,
- stackMap,
- c,
- labels);
- }
- n = frameStackCount = readUnsignedShort(stackMap);
- stackMap += 2;
- for (j = 0; n > 0; n--) {
- stackMap = readFrameType(frameStack,
- j++,
- stackMap,
- c,
- labels);
- }
- }
- }
- frameOffset += delta + 1;
- readLabel(frameOffset, labels);
-
- --frameCount;
- } else {
- frameLocal = null;
- }
+ // visits the frame for this offset, if any
+ while (FRAMES && frame != null
+ && (frame.offset == offset || frame.offset == -1)) {
+ // if there is a frame for this offset, makes the visitor visit
+ // it, and reads the next frame if there is one.
+ if (frame.offset != -1) {
+ if (!zip || unzip) {
+ mv.visitFrame(Opcodes.F_NEW, frame.localCount,
+ frame.local, frame.stackCount, frame.stack);
+ } else {
+ mv.visitFrame(frame.mode, frame.localDiff, frame.local,
+ frame.stackCount, frame.stack);
}
+ }
+ if (frameCount > 0) {
+ stackMap = readFrame(stackMap, zip, unzip, labels, frame);
+ --frameCount;
+ } else {
+ frame = null;
+ }
+ }
- int opcode = b[v] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- mv.visitInsn(opcode);
- v += 1;
- break;
- case ClassWriter.IMPLVAR_INSN:
- if (opcode > Opcodes.ISTORE) {
- opcode -= 59; // ISTORE_0
- mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
- opcode & 0x3);
- } else {
- opcode -= 26; // ILOAD_0
- mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2),
- opcode & 0x3);
- }
- v += 1;
- break;
- case ClassWriter.LABEL_INSN:
- mv.visitJumpInsn(opcode, labels[w
- + readShort(v + 1)]);
- v += 3;
- break;
- case ClassWriter.LABELW_INSN:
- mv.visitJumpInsn(opcode - 33, labels[w
- + readInt(v + 1)]);
- v += 5;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[v + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- mv.visitIincInsn(readUnsignedShort(v + 2),
- readShort(v + 4));
- v += 6;
- } else {
- mv.visitVarInsn(opcode,
- readUnsignedShort(v + 2));
- v += 4;
- }
- break;
- case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = v + 4 - (w & 3);
- // reads instruction
- label = w + readInt(v);
- int min = readInt(v + 4);
- int max = readInt(v + 8);
- v += 12;
- Label[] table = new Label[max - min + 1];
- for (j = 0; j < table.length; ++j) {
- table[j] = labels[w + readInt(v)];
- v += 4;
- }
- mv.visitTableSwitchInsn(min,
- max,
- labels[label],
- table);
- break;
- case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = v + 4 - (w & 3);
- // reads instruction
- label = w + readInt(v);
- j = readInt(v + 4);
- v += 8;
- int[] keys = new int[j];
- Label[] values = new Label[j];
- for (j = 0; j < keys.length; ++j) {
- keys[j] = readInt(v);
- values[j] = labels[w + readInt(v + 4)];
- v += 8;
- }
- mv.visitLookupSwitchInsn(labels[label],
- keys,
- values);
- break;
- case ClassWriter.VAR_INSN:
- mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
- v += 2;
- break;
- case ClassWriter.SBYTE_INSN:
- mv.visitIntInsn(opcode, b[v + 1]);
- v += 2;
- break;
- case ClassWriter.SHORT_INSN:
- mv.visitIntInsn(opcode, readShort(v + 1));
- v += 3;
- break;
- case ClassWriter.LDC_INSN:
- mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
- v += 2;
- break;
- case ClassWriter.LDCW_INSN:
- mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
- c));
- v += 3;
- break;
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.ITFMETH_INSN: {
- int cpIndex = items[readUnsignedShort(v + 1)];
- String iowner = readClass(cpIndex, c);
- cpIndex = items[readUnsignedShort(cpIndex + 2)];
- String iname = readUTF8(cpIndex, c);
- String idesc = readUTF8(cpIndex + 2, c);
- if (opcode < Opcodes.INVOKEVIRTUAL) {
- mv.visitFieldInsn(opcode, iowner, iname, idesc);
- } else {
- mv.visitMethodInsn(opcode, iowner, iname, idesc);
- }
- if (opcode == Opcodes.INVOKEINTERFACE) {
- v += 5;
- } else {
- v += 3;
- }
- break;
- }
- case ClassWriter.INDYMETH_INSN: {
- int cpIndex = items[readUnsignedShort(v + 1)];
- int bsmIndex = bootstrapMethods[readUnsignedShort(cpIndex)];
- cpIndex = items[readUnsignedShort(cpIndex + 2)];
- String iname = readUTF8(cpIndex, c);
- String idesc = readUTF8(cpIndex + 2, c);
-
- int mhIndex = readUnsignedShort(bsmIndex);
- Handle bsm = (Handle) readConst(mhIndex, c);
- int bsmArgCount = readUnsignedShort(bsmIndex + 2);
- Object[] bsmArgs = new Object[bsmArgCount];
- bsmIndex += 4;
- for(int a = 0; a < bsmArgCount; a++) {
- int argIndex = readUnsignedShort(bsmIndex);
- bsmArgs[a] = readConst(argIndex, c);
- bsmIndex += 2;
- }
- mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
-
- v += 5;
- break;
- }
- case ClassWriter.TYPE_INSN:
- mv.visitTypeInsn(opcode, readClass(v + 1, c));
- v += 3;
- break;
- case ClassWriter.IINC_INSN:
- mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
- v += 3;
- break;
- // case MANA_INSN:
- default:
- mv.visitMultiANewArrayInsn(readClass(v + 1, c),
- b[v + 3] & 0xFF);
- v += 4;
- break;
- }
+ // visits the instruction at this offset
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ mv.visitInsn(opcode);
+ u += 1;
+ break;
+ case ClassWriter.IMPLVAR_INSN:
+ if (opcode > Opcodes.ISTORE) {
+ opcode -= 59; // ISTORE_0
+ mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
+ opcode & 0x3);
+ } else {
+ opcode -= 26; // ILOAD_0
+ mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
}
- l = labels[codeEnd - codeStart];
- if (l != null) {
- mv.visitLabel(l);
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+ u += 5;
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
+ u += 6;
+ } else {
+ mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
+ u += 4;
}
- // visits the local variable tables
- if (!skipDebug && varTable != 0) {
- int[] typeTable = null;
- if (varTypeTable != 0) {
- k = readUnsignedShort(varTypeTable) * 3;
- w = varTypeTable + 2;
- typeTable = new int[k];
- while (k > 0) {
- typeTable[--k] = w + 6; // signature
- typeTable[--k] = readUnsignedShort(w + 8); // index
- typeTable[--k] = readUnsignedShort(w); // start
- w += 10;
- }
- }
- k = readUnsignedShort(varTable);
- w = varTable + 2;
- for (; k > 0; --k) {
- int start = readUnsignedShort(w);
- int length = readUnsignedShort(w + 2);
- int index = readUnsignedShort(w + 8);
- String vsignature = null;
- if (typeTable != null) {
- for (int a = 0; a < typeTable.length; a += 3) {
- if (typeTable[a] == start
- && typeTable[a + 1] == index)
- {
- vsignature = readUTF8(typeTable[a + 2], c);
- break;
- }
- }
- }
- mv.visitLocalVariable(readUTF8(w + 4, c),
- readUTF8(w + 6, c),
- vsignature,
- labels[start],
- labels[start + length],
- index);
- w += 10;
- }
+ break;
+ case ClassWriter.TABL_INSN: {
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ int label = offset + readInt(u);
+ int min = readInt(u + 4);
+ int max = readInt(u + 8);
+ Label[] table = new Label[max - min + 1];
+ u += 12;
+ for (int i = 0; i < table.length; ++i) {
+ table[i] = labels[offset + readInt(u)];
+ u += 4;
+ }
+ mv.visitTableSwitchInsn(min, max, labels[label], table);
+ break;
+ }
+ case ClassWriter.LOOK_INSN: {
+ // skips 0 to 3 padding bytes
+ u = u + 4 - (offset & 3);
+ // reads instruction
+ int label = offset + readInt(u);
+ int len = readInt(u + 4);
+ int[] keys = new int[len];
+ Label[] values = new Label[len];
+ u += 8;
+ for (int i = 0; i < len; ++i) {
+ keys[i] = readInt(u);
+ values[i] = labels[offset + readInt(u + 4)];
+ u += 8;
+ }
+ mv.visitLookupSwitchInsn(labels[label], keys, values);
+ break;
+ }
+ case ClassWriter.VAR_INSN:
+ mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
+ u += 2;
+ break;
+ case ClassWriter.SBYTE_INSN:
+ mv.visitIntInsn(opcode, b[u + 1]);
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ mv.visitIntInsn(opcode, readShort(u + 1));
+ u += 3;
+ break;
+ case ClassWriter.LDC_INSN:
+ mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
+ u += 2;
+ break;
+ case ClassWriter.LDCW_INSN:
+ mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
+ u += 3;
+ break;
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.ITFMETH_INSN: {
+ int cpIndex = items[readUnsignedShort(u + 1)];
+ String iowner = readClass(cpIndex, c);
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String iname = readUTF8(cpIndex, c);
+ String idesc = readUTF8(cpIndex + 2, c);
+ if (opcode < Opcodes.INVOKEVIRTUAL) {
+ mv.visitFieldInsn(opcode, iowner, iname, idesc);
+ } else {
+ mv.visitMethodInsn(opcode, iowner, iname, idesc);
}
- // visits the other attributes
- while (cattrs != null) {
- attr = cattrs.next;
- cattrs.next = null;
- mv.visitAttribute(cattrs);
- cattrs = attr;
+ if (opcode == Opcodes.INVOKEINTERFACE) {
+ u += 5;
+ } else {
+ u += 3;
}
- // visits the max stack and max locals values
- mv.visitMaxs(maxStack, maxLocals);
+ break;
}
+ case ClassWriter.INDYMETH_INSN: {
+ int cpIndex = items[readUnsignedShort(u + 1)];
+ int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
+ Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
+ int bsmArgCount = readUnsignedShort(bsmIndex + 2);
+ Object[] bsmArgs = new Object[bsmArgCount];
+ bsmIndex += 4;
+ for (int i = 0; i < bsmArgCount; i++) {
+ bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
+ bsmIndex += 2;
+ }
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String iname = readUTF8(cpIndex, c);
+ String idesc = readUTF8(cpIndex + 2, c);
+ mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
+ u += 5;
+ break;
+ }
+ case ClassWriter.TYPE_INSN:
+ mv.visitTypeInsn(opcode, readClass(u + 1, c));
+ u += 3;
+ break;
+ case ClassWriter.IINC_INSN:
+ mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
+ u += 3;
+ break;
+ // case MANA_INSN:
+ default:
+ mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
+ u += 4;
+ break;
+ }
+ }
+ if (labels[codeLength] != null) {
+ mv.visitLabel(labels[codeLength]);
+ }
- if (mv != null) {
- mv.visitEnd();
+ // visits the local variable tables
+ if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
+ int[] typeTable = null;
+ if (varTypeTable != 0) {
+ u = varTypeTable + 2;
+ typeTable = new int[readUnsignedShort(varTypeTable) * 3];
+ for (int i = typeTable.length; i > 0;) {
+ typeTable[--i] = u + 6; // signature
+ typeTable[--i] = readUnsignedShort(u + 8); // index
+ typeTable[--i] = readUnsignedShort(u); // start
+ u += 10;
+ }
+ }
+ u = varTable + 2;
+ for (int i = readUnsignedShort(varTable); i > 0; --i) {
+ int start = readUnsignedShort(u);
+ int length = readUnsignedShort(u + 2);
+ int index = readUnsignedShort(u + 8);
+ String vsignature = null;
+ if (typeTable != null) {
+ for (int j = 0; j < typeTable.length; j += 3) {
+ if (typeTable[j] == start && typeTable[j + 1] == index) {
+ vsignature = readUTF8(typeTable[j + 2], c);
+ break;
+ }
+ }
+ }
+ mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
+ vsignature, labels[start], labels[start + length],
+ index);
+ u += 10;
}
}
- // visits the end of the class
- classVisitor.visitEnd();
+ // visits the code attributes
+ while (attributes != null) {
+ Attribute attr = attributes.next;
+ attributes.next = null;
+ mv.visitAttribute(attributes);
+ attributes = attr;
+ }
+
+ // visits the max stack and max locals values
+ mv.visitMaxs(maxStack, maxLocals);
}
/**
* Reads parameter annotations and makes the given visitor visit them.
*
- * @param v start offset in {@link #b b} of the annotations to be read.
- * @param desc the method descriptor.
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param visible <tt>true</tt> if the annotations to be read are visible
- * at runtime.
- * @param mv the visitor that must visit the annotations.
+ * @param v
+ * start offset in {@link #b b} of the annotations to be read.
+ * @param desc
+ * the method descriptor.
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param visible
+ * <tt>true</tt> if the annotations to be read are visible at
+ * runtime.
+ * @param mv
+ * the visitor that must visit the annotations.
*/
- private void readParameterAnnotations(
- int v,
- final String desc,
- final char[] buf,
- final boolean visible,
- final MethodVisitor mv)
- {
+ private void readParameterAnnotations(int v, final String desc,
+ final char[] buf, final boolean visible, final MethodVisitor mv) {
int i;
int n = b[v++] & 0xFF;
// workaround for a bug in javac (javac compiler generates a parameter
@@ -1679,21 +1458,22 @@ public class ClassReader {
/**
* Reads the values of an annotation and makes the given visitor visit them.
*
- * @param v the start offset in {@link #b b} of the values to be read
- * (including the unsigned short that gives the number of values).
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param named if the annotation values are named or not.
- * @param av the visitor that must visit the values.
+ * @param v
+ * the start offset in {@link #b b} of the values to be read
+ * (including the unsigned short that gives the number of
+ * values).
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param named
+ * if the annotation values are named or not.
+ * @param av
+ * the visitor that must visit the values.
* @return the end offset of the annotation values.
*/
- private int readAnnotationValues(
- int v,
- final char[] buf,
- final boolean named,
- final AnnotationVisitor av)
- {
+ private int readAnnotationValues(int v, final char[] buf,
+ final boolean named, final AnnotationVisitor av) {
int i = readUnsignedShort(v);
v += 2;
if (named) {
@@ -1714,210 +1494,371 @@ public class ClassReader {
/**
* Reads a value of an annotation and makes the given visitor visit it.
*
- * @param v the start offset in {@link #b b} of the value to be read (<i>not
- * including the value name constant pool index</i>).
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param name the name of the value to be read.
- * @param av the visitor that must visit the value.
+ * @param v
+ * the start offset in {@link #b b} of the value to be read
+ * (<i>not including the value name constant pool index</i>).
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param name
+ * the name of the value to be read.
+ * @param av
+ * the visitor that must visit the value.
* @return the end offset of the annotation value.
*/
- private int readAnnotationValue(
- int v,
- final char[] buf,
- final String name,
- final AnnotationVisitor av)
- {
+ private int readAnnotationValue(int v, final char[] buf, final String name,
+ final AnnotationVisitor av) {
int i;
if (av == null) {
switch (b[v] & 0xFF) {
- case 'e': // enum_const_value
- return v + 5;
- case '@': // annotation_value
- return readAnnotationValues(v + 3, buf, true, null);
- case '[': // array_value
- return readAnnotationValues(v + 1, buf, false, null);
- default:
- return v + 3;
+ case 'e': // enum_const_value
+ return v + 5;
+ case '@': // annotation_value
+ return readAnnotationValues(v + 3, buf, true, null);
+ case '[': // array_value
+ return readAnnotationValues(v + 1, buf, false, null);
+ default:
+ return v + 3;
}
}
switch (b[v++] & 0xFF) {
- case 'I': // pointer to CONSTANT_Integer
- case 'J': // pointer to CONSTANT_Long
- case 'F': // pointer to CONSTANT_Float
- case 'D': // pointer to CONSTANT_Double
- av.visit(name, readConst(readUnsignedShort(v), buf));
- v += 2;
- break;
- case 'B': // pointer to CONSTANT_Byte
- av.visit(name,
- new Byte((byte) readInt(items[readUnsignedShort(v)])));
- v += 2;
- break;
- case 'Z': // pointer to CONSTANT_Boolean
- av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
- ? Boolean.FALSE
- : Boolean.TRUE);
- v += 2;
- break;
- case 'S': // pointer to CONSTANT_Short
- av.visit(name,
- new Short((short) readInt(items[readUnsignedShort(v)])));
- v += 2;
+ case 'I': // pointer to CONSTANT_Integer
+ case 'J': // pointer to CONSTANT_Long
+ case 'F': // pointer to CONSTANT_Float
+ case 'D': // pointer to CONSTANT_Double
+ av.visit(name, readConst(readUnsignedShort(v), buf));
+ v += 2;
+ break;
+ case 'B': // pointer to CONSTANT_Byte
+ av.visit(name,
+ new Byte((byte) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 'Z': // pointer to CONSTANT_Boolean
+ av.visit(name,
+ readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
+ : Boolean.TRUE);
+ v += 2;
+ break;
+ case 'S': // pointer to CONSTANT_Short
+ av.visit(name, new Short(
+ (short) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 'C': // pointer to CONSTANT_Char
+ av.visit(name, new Character(
+ (char) readInt(items[readUnsignedShort(v)])));
+ v += 2;
+ break;
+ case 's': // pointer to CONSTANT_Utf8
+ av.visit(name, readUTF8(v, buf));
+ v += 2;
+ break;
+ case 'e': // enum_const_value
+ av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
+ v += 4;
+ break;
+ case 'c': // class_info
+ av.visit(name, Type.getType(readUTF8(v, buf)));
+ v += 2;
+ break;
+ case '@': // annotation_value
+ v = readAnnotationValues(v + 2, buf, true,
+ av.visitAnnotation(name, readUTF8(v, buf)));
+ break;
+ case '[': // array_value
+ int size = readUnsignedShort(v);
+ v += 2;
+ if (size == 0) {
+ return readAnnotationValues(v - 2, buf, false,
+ av.visitArray(name));
+ }
+ switch (this.b[v++] & 0xFF) {
+ case 'B':
+ byte[] bv = new byte[size];
+ for (i = 0; i < size; i++) {
+ bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, bv);
+ --v;
break;
- case 'C': // pointer to CONSTANT_Char
- av.visit(name,
- new Character((char) readInt(items[readUnsignedShort(v)])));
- v += 2;
+ case 'Z':
+ boolean[] zv = new boolean[size];
+ for (i = 0; i < size; i++) {
+ zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
+ v += 3;
+ }
+ av.visit(name, zv);
+ --v;
break;
- case 's': // pointer to CONSTANT_Utf8
- av.visit(name, readUTF8(v, buf));
- v += 2;
+ case 'S':
+ short[] sv = new short[size];
+ for (i = 0; i < size; i++) {
+ sv[i] = (short) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, sv);
+ --v;
break;
- case 'e': // enum_const_value
- av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
- v += 4;
+ case 'C':
+ char[] cv = new char[size];
+ for (i = 0; i < size; i++) {
+ cv[i] = (char) readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, cv);
+ --v;
break;
- case 'c': // class_info
- av.visit(name, Type.getType(readUTF8(v, buf)));
- v += 2;
+ case 'I':
+ int[] iv = new int[size];
+ for (i = 0; i < size; i++) {
+ iv[i] = readInt(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, iv);
+ --v;
break;
- case '@': // annotation_value
- v = readAnnotationValues(v + 2,
- buf,
- true,
- av.visitAnnotation(name, readUTF8(v, buf)));
+ case 'J':
+ long[] lv = new long[size];
+ for (i = 0; i < size; i++) {
+ lv[i] = readLong(items[readUnsignedShort(v)]);
+ v += 3;
+ }
+ av.visit(name, lv);
+ --v;
break;
- case '[': // array_value
- int size = readUnsignedShort(v);
- v += 2;
- if (size == 0) {
- return readAnnotationValues(v - 2,
- buf,
- false,
- av.visitArray(name));
+ case 'F':
+ float[] fv = new float[size];
+ for (i = 0; i < size; i++) {
+ fv[i] = Float
+ .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
+ v += 3;
}
- switch (this.b[v++] & 0xFF) {
- case 'B':
- byte[] bv = new byte[size];
- for (i = 0; i < size; i++) {
- bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, bv);
- --v;
- break;
- case 'Z':
- boolean[] zv = new boolean[size];
- for (i = 0; i < size; i++) {
- zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
- v += 3;
- }
- av.visit(name, zv);
- --v;
- break;
- case 'S':
- short[] sv = new short[size];
- for (i = 0; i < size; i++) {
- sv[i] = (short) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, sv);
- --v;
- break;
- case 'C':
- char[] cv = new char[size];
- for (i = 0; i < size; i++) {
- cv[i] = (char) readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, cv);
- --v;
- break;
- case 'I':
- int[] iv = new int[size];
- for (i = 0; i < size; i++) {
- iv[i] = readInt(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, iv);
- --v;
- break;
- case 'J':
- long[] lv = new long[size];
- for (i = 0; i < size; i++) {
- lv[i] = readLong(items[readUnsignedShort(v)]);
- v += 3;
- }
- av.visit(name, lv);
- --v;
- break;
- case 'F':
- float[] fv = new float[size];
- for (i = 0; i < size; i++) {
- fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
- v += 3;
- }
- av.visit(name, fv);
- --v;
- break;
- case 'D':
- double[] dv = new double[size];
- for (i = 0; i < size; i++) {
- dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
- v += 3;
- }
- av.visit(name, dv);
- --v;
- break;
- default:
- v = readAnnotationValues(v - 3,
- buf,
- false,
- av.visitArray(name));
+ av.visit(name, fv);
+ --v;
+ break;
+ case 'D':
+ double[] dv = new double[size];
+ for (i = 0; i < size; i++) {
+ dv[i] = Double
+ .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
+ v += 3;
}
+ av.visit(name, dv);
+ --v;
+ break;
+ default:
+ v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
+ }
}
return v;
}
- private int readFrameType(
- final Object[] frame,
- final int index,
- int v,
- final char[] buf,
- final Label[] labels)
- {
- int type = b[v++] & 0xFF;
- switch (type) {
- case 0:
- frame[index] = Opcodes.TOP;
- break;
- case 1:
- frame[index] = Opcodes.INTEGER;
- break;
- case 2:
- frame[index] = Opcodes.FLOAT;
+ /**
+ * Computes the implicit frame of the method currently being parsed (as
+ * defined in the given {@link Context}) and stores it in the given context.
+ *
+ * @param frame
+ * information about the class being parsed.
+ */
+ private void getImplicitFrame(final Context frame) {
+ String desc = frame.desc;
+ Object[] locals = frame.local;
+ int local = 0;
+ if ((frame.access & Opcodes.ACC_STATIC) == 0) {
+ if ("<init>".equals(frame.name)) {
+ locals[local++] = Opcodes.UNINITIALIZED_THIS;
+ } else {
+ locals[local++] = readClass(header + 2, frame.buffer);
+ }
+ }
+ int i = 1;
+ loop: while (true) {
+ int j = i;
+ switch (desc.charAt(i++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ locals[local++] = Opcodes.INTEGER;
break;
- case 3:
- frame[index] = Opcodes.DOUBLE;
+ case 'F':
+ locals[local++] = Opcodes.FLOAT;
break;
- case 4:
- frame[index] = Opcodes.LONG;
+ case 'J':
+ locals[local++] = Opcodes.LONG;
break;
- case 5:
- frame[index] = Opcodes.NULL;
+ case 'D':
+ locals[local++] = Opcodes.DOUBLE;
break;
- case 6:
- frame[index] = Opcodes.UNINITIALIZED_THIS;
+ case '[':
+ while (desc.charAt(i) == '[') {
+ ++i;
+ }
+ if (desc.charAt(i) == 'L') {
+ ++i;
+ while (desc.charAt(i) != ';') {
+ ++i;
+ }
+ }
+ locals[local++] = desc.substring(j, ++i);
break;
- case 7: // Object
- frame[index] = readClass(v, buf);
- v += 2;
+ case 'L':
+ while (desc.charAt(i) != ';') {
+ ++i;
+ }
+ locals[local++] = desc.substring(j + 1, i++);
break;
- default: // Uninitialized
- frame[index] = readLabel(readUnsignedShort(v), labels);
- v += 2;
+ default:
+ break loop;
+ }
+ }
+ frame.localCount = local;
+ }
+
+ /**
+ * Reads a stack map frame and stores the result in the given
+ * {@link Context} object.
+ *
+ * @param stackMap
+ * the start offset of a stack map frame in the class file.
+ * @param zip
+ * if the stack map frame at stackMap is compressed or not.
+ * @param unzip
+ * if the stack map frame must be uncompressed.
+ * @param labels
+ * the labels of the method currently being parsed, indexed by
+ * their offset. A new label for the parsed stack map frame is
+ * stored in this array if it does not already exist.
+ * @param frame
+ * where the parsed stack map frame must be stored.
+ * @return the offset of the first byte following the parsed frame.
+ */
+ private int readFrame(int stackMap, boolean zip, boolean unzip,
+ Label[] labels, Context frame) {
+ char[] c = frame.buffer;
+ int tag;
+ int delta;
+ if (zip) {
+ tag = b[stackMap++] & 0xFF;
+ } else {
+ tag = MethodWriter.FULL_FRAME;
+ frame.offset = -1;
+ }
+ frame.localDiff = 0;
+ if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+ delta = tag;
+ frame.mode = Opcodes.F_SAME;
+ frame.stackCount = 0;
+ } else if (tag < MethodWriter.RESERVED) {
+ delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
+ stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+ frame.mode = Opcodes.F_SAME1;
+ frame.stackCount = 1;
+ } else {
+ delta = readUnsignedShort(stackMap);
+ stackMap += 2;
+ if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+ stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+ frame.mode = Opcodes.F_SAME1;
+ frame.stackCount = 1;
+ } else if (tag >= MethodWriter.CHOP_FRAME
+ && tag < MethodWriter.SAME_FRAME_EXTENDED) {
+ frame.mode = Opcodes.F_CHOP;
+ frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
+ frame.localCount -= frame.localDiff;
+ frame.stackCount = 0;
+ } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
+ frame.mode = Opcodes.F_SAME;
+ frame.stackCount = 0;
+ } else if (tag < MethodWriter.FULL_FRAME) {
+ int local = unzip ? frame.localCount : 0;
+ for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
+ stackMap = readFrameType(frame.local, local++, stackMap, c,
+ labels);
+ }
+ frame.mode = Opcodes.F_APPEND;
+ frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
+ frame.localCount += frame.localDiff;
+ frame.stackCount = 0;
+ } else { // if (tag == FULL_FRAME) {
+ frame.mode = Opcodes.F_FULL;
+ int n = readUnsignedShort(stackMap);
+ stackMap += 2;
+ frame.localDiff = n;
+ frame.localCount = n;
+ for (int local = 0; n > 0; n--) {
+ stackMap = readFrameType(frame.local, local++, stackMap, c,
+ labels);
+ }
+ n = readUnsignedShort(stackMap);
+ stackMap += 2;
+ frame.stackCount = n;
+ for (int stack = 0; n > 0; n--) {
+ stackMap = readFrameType(frame.stack, stack++, stackMap, c,
+ labels);
+ }
+ }
+ }
+ frame.offset += delta + 1;
+ readLabel(frame.offset, labels);
+ return stackMap;
+ }
+
+ /**
+ * Reads a stack map frame type and stores it at the given index in the
+ * given array.
+ *
+ * @param frame
+ * the array where the parsed type must be stored.
+ * @param index
+ * the index in 'frame' where the parsed type must be stored.
+ * @param v
+ * the start offset of the stack map frame type to read.
+ * @param buf
+ * a buffer to read strings.
+ * @param labels
+ * the labels of the method currently being parsed, indexed by
+ * their offset. If the parsed type is an Uninitialized type, a
+ * new label for the corresponding NEW instruction is stored in
+ * this array if it does not already exist.
+ * @return the offset of the first byte after the parsed type.
+ */
+ private int readFrameType(final Object[] frame, final int index, int v,
+ final char[] buf, final Label[] labels) {
+ int type = b[v++] & 0xFF;
+ switch (type) {
+ case 0:
+ frame[index] = Opcodes.TOP;
+ break;
+ case 1:
+ frame[index] = Opcodes.INTEGER;
+ break;
+ case 2:
+ frame[index] = Opcodes.FLOAT;
+ break;
+ case 3:
+ frame[index] = Opcodes.DOUBLE;
+ break;
+ case 4:
+ frame[index] = Opcodes.LONG;
+ break;
+ case 5:
+ frame[index] = Opcodes.NULL;
+ break;
+ case 6:
+ frame[index] = Opcodes.UNINITIALIZED_THIS;
+ break;
+ case 7: // Object
+ frame[index] = readClass(v, buf);
+ v += 2;
+ break;
+ default: // Uninitialized
+ frame[index] = readLabel(readUnsignedShort(v), labels);
+ v += 2;
}
return v;
}
@@ -1927,10 +1868,12 @@ public class ClassReader {
* implementation of this method creates a label for the given offset if it
* has not been already created.
*
- * @param offset a bytecode offset in a method.
- * @param labels the already created labels, indexed by their offset. If a
- * label already exists for offset this method must not create a new
- * one. Otherwise it must store the new label in this array.
+ * @param offset
+ * a bytecode offset in a method.
+ * @param labels
+ * the already created labels, indexed by their offset. If a
+ * label already exists for offset this method must not create a
+ * new one. Otherwise it must store the new label in this array.
* @return a non null Label, which must be equal to labels[offset].
*/
protected Label readLabel(int offset, Label[] labels) {
@@ -1941,39 +1884,67 @@ public class ClassReader {
}
/**
+ * Returns the start index of the attribute_info structure of this class.
+ *
+ * @return the start index of the attribute_info structure of this class.
+ */
+ private int getAttributes() {
+ // skips the header
+ int u = header + 8 + readUnsignedShort(header + 6) * 2;
+ // skips fields and methods
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+ u += 6 + readInt(u + 12);
+ }
+ u += 8;
+ }
+ u += 2;
+ for (int i = readUnsignedShort(u); i > 0; --i) {
+ for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+ u += 6 + readInt(u + 12);
+ }
+ u += 8;
+ }
+ // the attribute_info structure starts just after the methods
+ return u + 2;
+ }
+
+ /**
* Reads an attribute in {@link #b b}.
*
- * @param attrs prototypes of the attributes that must be parsed during the
- * visit of the class. Any attribute whose type is not equal to the
- * type of one the prototypes is ignored (i.e. an empty
- * {@link Attribute} instance is returned).
- * @param type the type of the attribute.
- * @param off index of the first byte of the attribute's content in
- * {@link #b b}. The 6 attribute header bytes, containing the type
- * and the length of the attribute, are not taken into account here
- * (they have already been read).
- * @param len the length of the attribute's content.
- * @param buf buffer to be used to call {@link #readUTF8 readUTF8},
- * {@link #readClass(int,char[]) readClass} or
- * {@link #readConst readConst}.
- * @param codeOff index of the first byte of code's attribute content in
- * {@link #b b}, or -1 if the attribute to be read is not a code
- * attribute. The 6 attribute header bytes, containing the type and
- * the length of the attribute, are not taken into account here.
- * @param labels the labels of the method's code, or <tt>null</tt> if the
- * attribute to be read is not a code attribute.
+ * @param attrs
+ * prototypes of the attributes that must be parsed during the
+ * visit of the class. Any attribute whose type is not equal to
+ * the type of one the prototypes is ignored (i.e. an empty
+ * {@link Attribute} instance is returned).
+ * @param type
+ * the type of the attribute.
+ * @param off
+ * index of the first byte of the attribute's content in
+ * {@link #b b}. The 6 attribute header bytes, containing the
+ * type and the length of the attribute, are not taken into
+ * account here (they have already been read).
+ * @param len
+ * the length of the attribute's content.
+ * @param buf
+ * buffer to be used to call {@link #readUTF8 readUTF8},
+ * {@link #readClass(int,char[]) readClass} or {@link #readConst
+ * readConst}.
+ * @param codeOff
+ * index of the first byte of code's attribute content in
+ * {@link #b b}, or -1 if the attribute to be read is not a code
+ * attribute. The 6 attribute header bytes, containing the type
+ * and the length of the attribute, are not taken into account
+ * here.
+ * @param labels
+ * the labels of the method's code, or <tt>null</tt> if the
+ * attribute to be read is not a code attribute.
* @return the attribute that has been read, or <tt>null</tt> to skip this
* attribute.
*/
- private Attribute readAttribute(
- final Attribute[] attrs,
- final String type,
- final int off,
- final int len,
- final char[] buf,
- final int codeOff,
- final Label[] labels)
- {
+ private Attribute readAttribute(final Attribute[] attrs, final String type,
+ final int off, final int len, final char[] buf, final int codeOff,
+ final Label[] labels) {
for (int i = 0; i < attrs.length; ++i) {
if (attrs[i].type.equals(type)) {
return attrs[i].read(this, off, len, buf, codeOff, labels);
@@ -1987,9 +1958,9 @@ public class ClassReader {
// ------------------------------------------------------------------------
/**
- * Returns the number of constant pool items in {@link #b b}.
+ * Returns the number of constant pool items in {@link #b b}.
*
- * @return the number of constant pool items in {@link #b b}.
+ * @return the number of constant pool items in {@link #b b}.
*/
public int getItemCount() {
return items.length;
@@ -2000,7 +1971,8 @@ public class ClassReader {
* one. <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param item the index a constant pool item.
+ * @param item
+ * the index a constant pool item.
* @return the start index of the constant pool item in {@link #b b}, plus
* one.
*/
@@ -2024,7 +1996,8 @@ public class ClassReader {
* {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.</i>
*
- * @param index the start index of the value to be read in {@link #b b}.
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readByte(final int index) {
@@ -2032,11 +2005,12 @@ public class ClassReader {
}
/**
- * Reads an unsigned short value in {@link #b b}. <i>This method is
- * intended for {@link Attribute} sub classes, and is normally not needed by
- * class generators or adapters.</i>
+ * Reads an unsigned short value in {@link #b b}. <i>This method is intended
+ * for {@link Attribute} sub classes, and is normally not needed by class
+ * generators or adapters.</i>
*
- * @param index the start index of the value to be read in {@link #b b}.
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readUnsignedShort(final int index) {
@@ -2049,7 +2023,8 @@ public class ClassReader {
* for {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.</i>
*
- * @param index the start index of the value to be read in {@link #b b}.
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public short readShort(final int index) {
@@ -2062,7 +2037,8 @@ public class ClassReader {
* {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.</i>
*
- * @param index the start index of the value to be read in {@link #b b}.
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public int readInt(final int index) {
@@ -2072,11 +2048,12 @@ public class ClassReader {
}
/**
- * Reads a signed long value in {@link #b b}. <i>This method is intended
- * for {@link Attribute} sub classes, and is normally not needed by class
+ * Reads a signed long value in {@link #b b}. <i>This method is intended for
+ * {@link Attribute} sub classes, and is normally not needed by class
* generators or adapters.</i>
*
- * @param index the start index of the value to be read in {@link #b b}.
+ * @param index
+ * the start index of the value to be read in {@link #b b}.
* @return the read value.
*/
public long readLong(final int index) {
@@ -2090,14 +2067,19 @@ public class ClassReader {
* is intended for {@link Attribute} sub classes, and is normally not needed
* by class generators or adapters.</i>
*
- * @param index the start index of an unsigned short value in {@link #b b},
- * whose value is the index of an UTF8 constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of an UTF8 constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified UTF8 item.
*/
public String readUTF8(int index, final char[] buf) {
int item = readUnsignedShort(index);
+ if (index == 0 || item == 0) {
+ return null;
+ }
String s = strings[item];
if (s != null) {
return s;
@@ -2109,10 +2091,13 @@ public class ClassReader {
/**
* Reads UTF8 string in {@link #b b}.
*
- * @param index start offset of the UTF8 string to be read.
- * @param utfLen length of the UTF8 string to be read.
- * @param buf buffer to be used to read the string. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param index
+ * start offset of the UTF8 string to be read.
+ * @param utfLen
+ * length of the UTF8 string to be read.
+ * @param buf
+ * buffer to be used to read the string. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified UTF8 string.
*/
private String readUTF(int index, final int utfLen, final char[] buf) {
@@ -2125,28 +2110,28 @@ public class ClassReader {
while (index < endIndex) {
c = b[index++];
switch (st) {
- case 0:
- c = c & 0xFF;
- if (c < 0x80) { // 0xxxxxxx
- buf[strLen++] = (char) c;
- } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
- cc = (char) (c & 0x1F);
- st = 1;
- } else { // 1110 xxxx 10xx xxxx 10xx xxxx
- cc = (char) (c & 0x0F);
- st = 2;
- }
- break;
+ case 0:
+ c = c & 0xFF;
+ if (c < 0x80) { // 0xxxxxxx
+ buf[strLen++] = (char) c;
+ } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
+ cc = (char) (c & 0x1F);
+ st = 1;
+ } else { // 1110 xxxx 10xx xxxx 10xx xxxx
+ cc = (char) (c & 0x0F);
+ st = 2;
+ }
+ break;
- case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
- buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
- st = 0;
- break;
+ case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
+ buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
+ st = 0;
+ break;
- case 2: // byte 2 of 3-byte char
- cc = (char) ((cc << 6) | (c & 0x3F));
- st = 1;
- break;
+ case 2: // byte 2 of 3-byte char
+ cc = (char) ((cc << 6) | (c & 0x3F));
+ st = 1;
+ break;
}
}
return new String(buf, 0, strLen);
@@ -2157,10 +2142,12 @@ public class ClassReader {
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
*
- * @param index the start index of an unsigned short value in {@link #b b},
- * whose value is the index of a class constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param index
+ * the start index of an unsigned short value in {@link #b b},
+ * whose value is the index of a class constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the String corresponding to the specified class item.
*/
public String readClass(final int index, final char[] buf) {
@@ -2175,9 +2162,11 @@ public class ClassReader {
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
- * @param item the index of a constant pool item.
- * @param buf buffer to be used to read the item. This buffer must be
- * sufficiently large. It is not automatically resized.
+ * @param item
+ * the index of a constant pool item.
+ * @param buf
+ * buffer to be used to read the item. This buffer must be
+ * sufficiently large. It is not automatically resized.
* @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
* {@link String}, {@link Type} or {@link Handle} corresponding to
* the given constant pool item.
@@ -2185,32 +2174,29 @@ public class ClassReader {
public Object readConst(final int item, final char[] buf) {
int index = items[item];
switch (b[index - 1]) {
- case ClassWriter.INT:
- return new Integer(readInt(index));
- case ClassWriter.FLOAT:
- return new Float(Float.intBitsToFloat(readInt(index)));
- case ClassWriter.LONG:
- return new Long(readLong(index));
- case ClassWriter.DOUBLE:
- return new Double(Double.longBitsToDouble(readLong(index)));
- case ClassWriter.CLASS:
- return Type.getObjectType(readUTF8(index, buf));
- case ClassWriter.STR:
- return readUTF8(index, buf);
- case ClassWriter.MTYPE:
- return Type.getMethodType(readUTF8(index, buf));
-
- //case ClassWriter.HANDLE_BASE + [1..9]:
- default: {
- int tag = readByte(index);
- int[] items = this.items;
- int cpIndex = items[readUnsignedShort(index + 1)];
- String owner = readClass(cpIndex, buf);
- cpIndex = items[readUnsignedShort(cpIndex + 2)];
- String name = readUTF8(cpIndex, buf);
- String desc = readUTF8(cpIndex + 2, buf);
- return new Handle(tag, owner, name, desc);
- }
+ case ClassWriter.INT:
+ return new Integer(readInt(index));
+ case ClassWriter.FLOAT:
+ return new Float(Float.intBitsToFloat(readInt(index)));
+ case ClassWriter.LONG:
+ return new Long(readLong(index));
+ case ClassWriter.DOUBLE:
+ return new Double(Double.longBitsToDouble(readLong(index)));
+ case ClassWriter.CLASS:
+ return Type.getObjectType(readUTF8(index, buf));
+ case ClassWriter.STR:
+ return readUTF8(index, buf);
+ case ClassWriter.MTYPE:
+ return Type.getMethodType(readUTF8(index, buf));
+ default: // case ClassWriter.HANDLE_BASE + [1..9]:
+ int tag = readByte(index);
+ int[] items = this.items;
+ int cpIndex = items[readUnsignedShort(index + 1)];
+ String owner = readClass(cpIndex, buf);
+ cpIndex = items[readUnsignedShort(cpIndex + 2)];
+ String name = readUTF8(cpIndex, buf);
+ String desc = readUTF8(cpIndex + 2, buf);
+ return new Handle(tag, owner, name, desc);
}
}
}
diff --git a/src/asm/scala/tools/asm/ClassVisitor.java b/src/asm/scala/tools/asm/ClassVisitor.java
index ae38ae0ab9..3fc364d5e5 100644
--- a/src/asm/scala/tools/asm/ClassVisitor.java
+++ b/src/asm/scala/tools/asm/ClassVisitor.java
@@ -30,11 +30,11 @@
package scala.tools.asm;
/**
- * A visitor to visit a Java class. The methods of this class must be called
- * in the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
+ * A visitor to visit a Java class. The methods of this class must be called in
+ * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
- * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> |
- * <tt>visitField</tt> | <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
+ * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> |
+ * <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
*
* @author Eric Bruneton
*/
@@ -55,8 +55,9 @@ public abstract class ClassVisitor {
/**
* Constructs a new {@link ClassVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public ClassVisitor(final int api) {
this(api, null);
@@ -65,15 +66,17 @@ public abstract class ClassVisitor {
/**
* Constructs a new {@link ClassVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param cv the class visitor to which this visitor must delegate method
- * calls. May be null.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param cv
+ * the class visitor to which this visitor must delegate method
+ * calls. May be null.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
- /*if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4) {
throw new IllegalArgumentException();
- }*/
+ }
this.api = api;
this.cv = cv;
}
@@ -81,30 +84,30 @@ public abstract class ClassVisitor {
/**
* Visits the header of the class.
*
- * @param version the class version.
- * @param access the class's access flags (see {@link Opcodes}). This
- * parameter also indicates if the class is deprecated.
- * @param name the internal name of the class (see
- * {@link Type#getInternalName() getInternalName}).
- * @param signature the signature of this class. May be <tt>null</tt> if
- * the class is not a generic one, and does not extend or implement
- * generic classes or interfaces.
- * @param superName the internal of name of the super class (see
- * {@link Type#getInternalName() getInternalName}). For interfaces,
- * the super class is {@link Object}. May be <tt>null</tt>, but
- * only for the {@link Object} class.
- * @param interfaces the internal names of the class's interfaces (see
- * {@link Type#getInternalName() getInternalName}). May be
- * <tt>null</tt>.
+ * @param version
+ * the class version.
+ * @param access
+ * the class's access flags (see {@link Opcodes}). This parameter
+ * also indicates if the class is deprecated.
+ * @param name
+ * the internal name of the class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param signature
+ * the signature of this class. May be <tt>null</tt> if the class
+ * is not a generic one, and does not extend or implement generic
+ * classes or interfaces.
+ * @param superName
+ * the internal of name of the super class (see
+ * {@link Type#getInternalName() getInternalName}). For
+ * interfaces, the super class is {@link Object}. May be
+ * <tt>null</tt>, but only for the {@link Object} class.
+ * @param interfaces
+ * the internal names of the class's interfaces (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * <tt>null</tt>.
*/
- public void visit(
- int version,
- int access,
- String name,
- String signature,
- String superName,
- String[] interfaces)
- {
+ public void visit(int version, int access, String name, String signature,
+ String superName, String[] interfaces) {
if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces);
}
@@ -113,11 +116,13 @@ public abstract class ClassVisitor {
/**
* Visits the source of the class.
*
- * @param source the name of the source file from which the class was
- * compiled. May be <tt>null</tt>.
- * @param debug additional debug information to compute the correspondance
- * between source and compiled elements of the class. May be
- * <tt>null</tt>.
+ * @param source
+ * the name of the source file from which the class was compiled.
+ * May be <tt>null</tt>.
+ * @param debug
+ * additional debug information to compute the correspondance
+ * between source and compiled elements of the class. May be
+ * <tt>null</tt>.
*/
public void visitSource(String source, String debug) {
if (cv != null) {
@@ -129,16 +134,19 @@ public abstract class ClassVisitor {
* Visits the enclosing class of the class. This method must be called only
* if the class has an enclosing class.
*
- * @param owner internal name of the enclosing class of the class.
- * @param name the name of the method that contains the class, or
- * <tt>null</tt> if the class is not enclosed in a method of its
- * enclosing class.
- * @param desc the descriptor of the method that contains the class, or
- * <tt>null</tt> if the class is not enclosed in a method of its
- * enclosing class.
+ * @param owner
+ * internal name of the enclosing class of the class.
+ * @param name
+ * the name of the method that contains the class, or
+ * <tt>null</tt> if the class is not enclosed in a method of its
+ * enclosing class.
+ * @param desc
+ * the descriptor of the method that contains the class, or
+ * <tt>null</tt> if the class is not enclosed in a method of its
+ * enclosing class.
*/
public void visitOuterClass(String owner, String name, String desc) {
- if (cv != null) {
+ if (cv != null) {
cv.visitOuterClass(owner, name, desc);
}
}
@@ -146,8 +154,10 @@ public abstract class ClassVisitor {
/**
* Visits an annotation of the class.
*
- * @param desc the class descriptor of the annotation class.
- * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
@@ -161,7 +171,8 @@ public abstract class ClassVisitor {
/**
* Visits a non standard attribute of the class.
*
- * @param attr an attribute.
+ * @param attr
+ * an attribute.
*/
public void visitAttribute(Attribute attr) {
if (cv != null) {
@@ -173,23 +184,22 @@ public abstract class ClassVisitor {
* Visits information about an inner class. This inner class is not
* necessarily a member of the class being visited.
*
- * @param name the internal name of an inner class (see
- * {@link Type#getInternalName() getInternalName}).
- * @param outerName the internal name of the class to which the inner class
- * belongs (see {@link Type#getInternalName() getInternalName}). May
- * be <tt>null</tt> for not member classes.
- * @param innerName the (simple) name of the inner class inside its
- * enclosing class. May be <tt>null</tt> for anonymous inner
- * classes.
- * @param access the access flags of the inner class as originally declared
- * in the enclosing class.
+ * @param name
+ * the internal name of an inner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param outerName
+ * the internal name of the class to which the inner class
+ * belongs (see {@link Type#getInternalName() getInternalName}).
+ * May be <tt>null</tt> for not member classes.
+ * @param innerName
+ * the (simple) name of the inner class inside its enclosing
+ * class. May be <tt>null</tt> for anonymous inner classes.
+ * @param access
+ * the access flags of the inner class as originally declared in
+ * the enclosing class.
*/
- public void visitInnerClass(
- String name,
- String outerName,
- String innerName,
- int access)
- {
+ public void visitInnerClass(String name, String outerName,
+ String innerName, int access) {
if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access);
}
@@ -198,33 +208,32 @@ public abstract class ClassVisitor {
/**
* Visits a field of the class.
*
- * @param access the field's access flags (see {@link Opcodes}). This
- * parameter also indicates if the field is synthetic and/or
- * deprecated.
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type Type}).
- * @param signature the field's signature. May be <tt>null</tt> if the
- * field's type does not use generic types.
- * @param value the field's initial value. This parameter, which may be
- * <tt>null</tt> if the field does not have an initial value, must
- * be an {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} or a {@link String} (for <tt>int</tt>,
- * <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
- * respectively). <i>This parameter is only used for static fields</i>.
- * Its value is ignored for non static fields, which must be
- * initialized through bytecode instructions in constructors or
- * methods.
+ * @param access
+ * the field's access flags (see {@link Opcodes}). This parameter
+ * also indicates if the field is synthetic and/or deprecated.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type Type}).
+ * @param signature
+ * the field's signature. May be <tt>null</tt> if the field's
+ * type does not use generic types.
+ * @param value
+ * the field's initial value. This parameter, which may be
+ * <tt>null</tt> if the field does not have an initial value,
+ * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String} (for <tt>int</tt>,
+ * <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
+ * respectively). <i>This parameter is only used for static
+ * fields</i>. Its value is ignored for non static fields, which
+ * must be initialized through bytecode instructions in
+ * constructors or methods.
* @return a visitor to visit field annotations and attributes, or
- * <tt>null</tt> if this class visitor is not interested in
- * visiting these annotations and attributes.
+ * <tt>null</tt> if this class visitor is not interested in visiting
+ * these annotations and attributes.
*/
- public FieldVisitor visitField(
- int access,
- String name,
- String desc,
- String signature,
- Object value)
- {
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
if (cv != null) {
return cv.visitField(access, name, desc, signature, value);
}
@@ -233,31 +242,31 @@ public abstract class ClassVisitor {
/**
* Visits a method of the class. This method <i>must</i> return a new
- * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is
- * called, i.e., it should not return a previously returned visitor.
+ * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called,
+ * i.e., it should not return a previously returned visitor.
*
- * @param access the method's access flags (see {@link Opcodes}). This
- * parameter also indicates if the method is synthetic and/or
- * deprecated.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- * @param signature the method's signature. May be <tt>null</tt> if the
- * method parameters, return type and exceptions do not use generic
- * types.
- * @param exceptions the internal names of the method's exception classes
- * (see {@link Type#getInternalName() getInternalName}). May be
- * <tt>null</tt>.
+ * @param access
+ * the method's access flags (see {@link Opcodes}). This
+ * parameter also indicates if the method is synthetic and/or
+ * deprecated.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param signature
+ * the method's signature. May be <tt>null</tt> if the method
+ * parameters, return type and exceptions do not use generic
+ * types.
+ * @param exceptions
+ * the internal names of the method's exception classes (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * <tt>null</tt>.
* @return an object to visit the byte code of the method, or <tt>null</tt>
* if this class visitor is not interested in visiting the code of
* this method.
*/
- public MethodVisitor visitMethod(
- int access,
- String name,
- String desc,
- String signature,
- String[] exceptions)
- {
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions);
}
diff --git a/src/asm/scala/tools/asm/ClassWriter.java b/src/asm/scala/tools/asm/ClassWriter.java
index c7a0736b51..93ed7313c7 100644
--- a/src/asm/scala/tools/asm/ClassWriter.java
+++ b/src/asm/scala/tools/asm/ClassWriter.java
@@ -66,12 +66,18 @@ public class ClassWriter extends ClassVisitor {
public static final int COMPUTE_FRAMES = 2;
/**
- * Pseudo access flag to distinguish between the synthetic attribute and
- * the synthetic access flag.
+ * Pseudo access flag to distinguish between the synthetic attribute and the
+ * synthetic access flag.
*/
static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
/**
+ * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC.
+ */
+ static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE
+ / Opcodes.ACC_SYNTHETIC;
+
+ /**
* The type of instructions without any argument.
*/
static final int NOARG_INSN = 0;
@@ -238,8 +244,8 @@ public class ClassWriter extends ClassVisitor {
/**
* The base value for all CONSTANT_MethodHandle constant pool items.
- * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into
- * 9 different items.
+ * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
+ * different items.
*/
static final int HANDLE_BASE = 20;
@@ -266,9 +272,8 @@ public class ClassWriter extends ClassVisitor {
static final int TYPE_MERGED = 32;
/**
- * The type of BootstrapMethods items. These items are stored in a
- * special class attribute named BootstrapMethods and
- * not in the constant pool.
+ * The type of BootstrapMethods items. These items are stored in a special
+ * class attribute named BootstrapMethods and not in the constant pool.
*/
static final int BSM = 33;
@@ -327,10 +332,10 @@ public class ClassWriter extends ClassVisitor {
* necessarily be stored in the constant pool. This type table is used by
* the control flow and data flow analysis algorithm used to compute stack
* map frames from scratch. This array associates to each index <tt>i</tt>
- * the Item whose index is <tt>i</tt>. All Item objects stored in this
- * array are also stored in the {@link #items} hash table. These two arrays
- * allow to retrieve an Item from its index or, conversely, to get the index
- * of an Item from its value. Each Item stores an internal name in its
+ * the Item whose index is <tt>i</tt>. All Item objects stored in this array
+ * are also stored in the {@link #items} hash table. These two arrays allow
+ * to retrieve an Item from its index or, conversely, to get the index of an
+ * Item from its value. Each Item stores an internal name in its
* {@link Item#strVal1} field.
*/
Item[] typeTable;
@@ -439,16 +444,16 @@ public class ClassWriter extends ClassVisitor {
/**
* The fields of this class. These fields are stored in a linked list of
* {@link FieldWriter} objects, linked to each other by their
- * {@link FieldWriter#fv} field. This field stores the first element of
- * this list.
+ * {@link FieldWriter#fv} field. This field stores the first element of this
+ * list.
*/
FieldWriter firstField;
/**
* The fields of this class. These fields are stored in a linked list of
* {@link FieldWriter} objects, linked to each other by their
- * {@link FieldWriter#fv} field. This field stores the last element of
- * this list.
+ * {@link FieldWriter#fv} field. This field stores the last element of this
+ * list.
*/
FieldWriter lastField;
@@ -463,8 +468,8 @@ public class ClassWriter extends ClassVisitor {
/**
* The methods of this class. These methods are stored in a linked list of
* {@link MethodWriter} objects, linked to each other by their
- * {@link MethodWriter#mv} field. This field stores the last element of
- * this list.
+ * {@link MethodWriter#mv} field. This field stores the last element of this
+ * list.
*/
MethodWriter lastMethod;
@@ -584,8 +589,10 @@ public class ClassWriter extends ClassVisitor {
/**
* Constructs a new {@link ClassWriter} object.
*
- * @param flags option flags that can be used to modify the default behavior
- * of this class. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. See {@link #COMPUTE_MAXS},
+ * {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final int flags) {
super(Opcodes.ASM4);
@@ -606,26 +613,32 @@ public class ClassWriter extends ClassVisitor {
* "mostly add" bytecode transformations. These optimizations are the
* following:
*
- * <ul> <li>The constant pool from the original class is copied as is in the
- * new class, which saves time. New constant pool entries will be added at
- * the end if necessary, but unused constant pool entries <i>won't be
- * removed</i>.</li> <li>Methods that are not transformed are copied as is
- * in the new class, directly from the original class bytecode (i.e. without
- * emitting visit events for all the method instructions), which saves a
- * <i>lot</i> of time. Untransformed methods are detected by the fact that
- * the {@link ClassReader} receives {@link MethodVisitor} objects that come
- * from a {@link ClassWriter} (and not from any other {@link ClassVisitor}
- * instance).</li> </ul>
+ * <ul>
+ * <li>The constant pool from the original class is copied as is in the new
+ * class, which saves time. New constant pool entries will be added at the
+ * end if necessary, but unused constant pool entries <i>won't be
+ * removed</i>.</li>
+ * <li>Methods that are not transformed are copied as is in the new class,
+ * directly from the original class bytecode (i.e. without emitting visit
+ * events for all the method instructions), which saves a <i>lot</i> of
+ * time. Untransformed methods are detected by the fact that the
+ * {@link ClassReader} receives {@link MethodVisitor} objects that come from
+ * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
+ * instance).</li>
+ * </ul>
*
- * @param classReader the {@link ClassReader} used to read the original
- * class. It will be used to copy the entire constant pool from the
- * original class and also to copy other fragments of original
- * bytecode where applicable.
- * @param flags option flags that can be used to modify the default behavior
- * of this class. <i>These option flags do not affect methods that
- * are copied as is in the new class. This means that the maximum
- * stack size nor the stack frames will be computed for these
- * methods</i>. See {@link #COMPUTE_MAXS}, {@link #COMPUTE_FRAMES}.
+ * @param classReader
+ * the {@link ClassReader} used to read the original class. It
+ * will be used to copy the entire constant pool from the
+ * original class and also to copy other fragments of original
+ * bytecode where applicable.
+ * @param flags
+ * option flags that can be used to modify the default behavior
+ * of this class. <i>These option flags do not affect methods
+ * that are copied as is in the new class. This means that the
+ * maximum stack size nor the stack frames will be computed for
+ * these methods</i>. See {@link #COMPUTE_MAXS},
+ * {@link #COMPUTE_FRAMES}.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
this(flags);
@@ -638,14 +651,9 @@ public class ClassWriter extends ClassVisitor {
// ------------------------------------------------------------------------
@Override
- public final void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public final void visit(final int version, final int access,
+ final String name, final String signature, final String superName,
+ final String[] interfaces) {
this.version = version;
this.access = access;
this.name = newClass(name);
@@ -674,11 +682,8 @@ public class ClassWriter extends ClassVisitor {
}
@Override
- public final void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public final void visitOuterClass(final String owner, final String name,
+ final String desc) {
enclosingMethodOwner = newClass(owner);
if (name != null && desc != null) {
enclosingMethod = newNameType(name, desc);
@@ -686,10 +691,8 @@ public class ClassWriter extends ClassVisitor {
}
@Override
- public final AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public final AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -714,12 +717,8 @@ public class ClassWriter extends ClassVisitor {
}
@Override
- public final void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public final void visitInnerClass(final String name,
+ final String outerName, final String innerName, final int access) {
if (innerClasses == null) {
innerClasses = new ByteVector();
}
@@ -731,32 +730,16 @@ public class ClassWriter extends ClassVisitor {
}
@Override
- public final FieldVisitor visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public final FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
return new FieldWriter(this, access, name, desc, signature, value);
}
@Override
- public final MethodVisitor visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
- return new MethodWriter(this,
- access,
- name,
- desc,
- signature,
- exceptions,
- computeMaxs,
- computeFrames);
+ public final MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ return new MethodWriter(this, access, name, desc, signature,
+ exceptions, computeMaxs, computeFrames);
}
@Override
@@ -773,7 +756,7 @@ public class ClassWriter extends ClassVisitor {
* @return the bytecode of the class that was build with this class writer.
*/
public byte[] toByteArray() {
- if (index > Short.MAX_VALUE) {
+ if (index > 0xFFFF) {
throw new RuntimeException("Class file too large!");
}
// computes the real size of the bytecode of this class
@@ -793,8 +776,9 @@ public class ClassWriter extends ClassVisitor {
mb = (MethodWriter) mb.mv;
}
int attributeCount = 0;
- if (bootstrapMethods != null) { // we put it as first argument in order
- // to improve a bit ClassReader.copyBootstrapMethods
+ if (bootstrapMethods != null) {
+ // we put it as first attribute in order to improve a bit
+ // ClassReader.copyBootstrapMethods
++attributeCount;
size += 8 + bootstrapMethods.length;
newUTF8("BootstrapMethods");
@@ -824,12 +808,13 @@ public class ClassWriter extends ClassVisitor {
size += 6;
newUTF8("Deprecated");
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- ++attributeCount;
- size += 6;
- newUTF8("Synthetic");
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((version & 0xFFFF) < Opcodes.V1_5
+ || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ size += 6;
+ newUTF8("Synthetic");
+ }
}
if (innerClasses != null) {
++attributeCount;
@@ -856,9 +841,8 @@ public class ClassWriter extends ClassVisitor {
ByteVector out = new ByteVector(size);
out.putInt(0xCAFEBABE).putInt(version);
out.putShort(index).putByteArray(pool.data, 0, pool.length);
- int mask = Opcodes.ACC_DEPRECATED
- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
+ | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
out.putShort(access & ~mask).putShort(name).putShort(superName);
out.putShort(interfaceCount);
for (int i = 0; i < interfaceCount; ++i) {
@@ -877,9 +861,10 @@ public class ClassWriter extends ClassVisitor {
mb = (MethodWriter) mb.mv;
}
out.putShort(attributeCount);
- if (bootstrapMethods != null) { // should be the first class attribute ?
+ if (bootstrapMethods != null) {
out.putShort(newUTF8("BootstrapMethods"));
- out.putInt(bootstrapMethods.length + 2).putShort(bootstrapMethodsCount);
+ out.putInt(bootstrapMethods.length + 2).putShort(
+ bootstrapMethodsCount);
out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
}
if (ClassReader.SIGNATURES && signature != 0) {
@@ -900,10 +885,11 @@ public class ClassWriter extends ClassVisitor {
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(newUTF8("Deprecated")).putInt(0);
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- out.putShort(newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((version & 0xFFFF) < Opcodes.V1_5
+ || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(newUTF8("Synthetic")).putInt(0);
+ }
}
if (innerClasses != null) {
out.putShort(newUTF8("InnerClasses"));
@@ -937,10 +923,11 @@ public class ClassWriter extends ClassVisitor {
* Adds a number or string constant to the constant pool of the class being
* build. Does nothing if the constant pool already contains a similar item.
*
- * @param cst the value of the constant to be added to the constant pool.
- * This parameter must be an {@link Integer}, a {@link Float}, a
- * {@link Long}, a {@link Double}, a {@link String} or a
- * {@link Type}.
+ * @param cst
+ * the value of the constant to be added to the constant pool.
+ * This parameter must be an {@link Integer}, a {@link Float}, a
+ * {@link Long}, a {@link Double}, a {@link String} or a
+ * {@link Type}.
* @return a new or already existing constant item with the given value.
*/
Item newConstItem(final Object cst) {
@@ -973,12 +960,12 @@ public class ClassWriter extends ClassVisitor {
} else if (cst instanceof Type) {
Type t = (Type) cst;
int s = t.getSort();
- if (s == Type.ARRAY) {
- return newClassItem(t.getDescriptor());
- } else if (s == Type.OBJECT) {
+ if (s == Type.OBJECT) {
return newClassItem(t.getInternalName());
- } else { // s == Type.METHOD
+ } else if (s == Type.METHOD) {
return newMethodTypeItem(t.getDescriptor());
+ } else { // s == primitive type or array
+ return newClassItem(t.getDescriptor());
}
} else if (cst instanceof Handle) {
Handle h = (Handle) cst;
@@ -994,9 +981,10 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param cst the value of the constant to be added to the constant pool.
- * This parameter must be an {@link Integer}, a {@link Float}, a
- * {@link Long}, a {@link Double} or a {@link String}.
+ * @param cst
+ * the value of the constant to be added to the constant pool.
+ * This parameter must be an {@link Integer}, a {@link Float}, a
+ * {@link Long}, a {@link Double} or a {@link String}.
* @return the index of a new or already existing constant item with the
* given value.
*/
@@ -1010,7 +998,8 @@ public class ClassWriter extends ClassVisitor {
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
- * @param value the String value.
+ * @param value
+ * the String value.
* @return the index of a new or already existing UTF8 item.
*/
public int newUTF8(final String value) {
@@ -1030,7 +1019,8 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param value the internal name of the class.
+ * @param value
+ * the internal name of the class.
* @return a new or already existing class reference item.
*/
Item newClassItem(final String value) {
@@ -1050,7 +1040,8 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param value the internal name of the class.
+ * @param value
+ * the internal name of the class.
* @return the index of a new or already existing class reference item.
*/
public int newClass(final String value) {
@@ -1063,7 +1054,8 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param methodDesc method descriptor of the method type.
+ * @param methodDesc
+ * method descriptor of the method type.
* @return a new or already existing method type reference item.
*/
Item newMethodTypeItem(final String methodDesc) {
@@ -1083,7 +1075,8 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param methodDesc method descriptor of the method type.
+ * @param methodDesc
+ * method descriptor of the method type.
* @return the index of a new or already existing method type reference
* item.
*/
@@ -1097,33 +1090,34 @@ public class ClassWriter extends ClassVisitor {
* intended for {@link Attribute} sub classes, and is normally not needed by
* class generators or adapters.</i>
*
- * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
- * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
- * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
- * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
- * {@link Opcodes#H_NEWINVOKESPECIAL} or
- * {@link Opcodes#H_INVOKEINTERFACE}.
- * @param owner the internal name of the field or method owner class.
- * @param name the name of the field or method.
- * @param desc the descriptor of the field or method.
+ * @param tag
+ * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method owner class.
+ * @param name
+ * the name of the field or method.
+ * @param desc
+ * the descriptor of the field or method.
* @return a new or an already existing method type reference item.
*/
- Item newHandleItem(
- final int tag,
- final String owner,
- final String name,
- final String desc)
- {
+ Item newHandleItem(final int tag, final String owner, final String name,
+ final String desc) {
key4.set(HANDLE_BASE + tag, owner, name, desc);
Item result = get(key4);
if (result == null) {
if (tag <= Opcodes.H_PUTSTATIC) {
put112(HANDLE, tag, newField(owner, name, desc));
} else {
- put112(HANDLE, tag, newMethod(owner,
- name,
- desc,
- tag == Opcodes.H_INVOKEINTERFACE));
+ put112(HANDLE,
+ tag,
+ newMethod(owner, name, desc,
+ tag == Opcodes.H_INVOKEINTERFACE));
}
result = new Item(index++, key4);
put(result);
@@ -1132,29 +1126,30 @@ public class ClassWriter extends ClassVisitor {
}
/**
- * Adds a handle to the constant pool of the class being
- * build. Does nothing if the constant pool already contains a similar item.
- * <i>This method is intended for {@link Attribute} sub classes, and is
- * normally not needed by class generators or adapters.</i>
+ * Adds a handle to the constant pool of the class being build. Does nothing
+ * if the constant pool already contains a similar item. <i>This method is
+ * intended for {@link Attribute} sub classes, and is normally not needed by
+ * class generators or adapters.</i>
*
- * @param tag the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
- * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
- * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
- * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
- * {@link Opcodes#H_NEWINVOKESPECIAL} or
- * {@link Opcodes#H_INVOKEINTERFACE}.
- * @param owner the internal name of the field or method owner class.
- * @param name the name of the field or method.
- * @param desc the descriptor of the field or method.
+ * @param tag
+ * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+ * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+ * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method owner class.
+ * @param name
+ * the name of the field or method.
+ * @param desc
+ * the descriptor of the field or method.
* @return the index of a new or already existing method type reference
* item.
*/
- public int newHandle(
- final int tag,
- final String owner,
- final String name,
- final String desc)
- {
+ public int newHandle(final int tag, final String owner, final String name,
+ final String desc) {
return newHandleItem(tag, owner, name, desc).index;
}
@@ -1164,19 +1159,19 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param name name of the invoked method.
- * @param desc descriptor of the invoke method.
- * @param bsm the bootstrap method.
- * @param bsmArgs the bootstrap method constant arguments.
+ * @param name
+ * name of the invoked method.
+ * @param desc
+ * descriptor of the invoke method.
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments.
*
* @return a new or an already existing invokedynamic type reference item.
*/
- Item newInvokeDynamicItem(
- final String name,
- final String desc,
- final Handle bsm,
- final Object... bsmArgs)
- {
+ Item newInvokeDynamicItem(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
// cache for performance
ByteVector bootstrapMethods = this.bootstrapMethods;
if (bootstrapMethods == null) {
@@ -1186,9 +1181,7 @@ public class ClassWriter extends ClassVisitor {
int position = bootstrapMethods.length; // record current position
int hashCode = bsm.hashCode();
- bootstrapMethods.putShort(newHandle(bsm.tag,
- bsm.owner,
- bsm.name,
+ bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
bsm.desc));
int argsLength = bsmArgs.length;
@@ -1250,20 +1243,20 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param name name of the invoked method.
- * @param desc descriptor of the invoke method.
- * @param bsm the bootstrap method.
- * @param bsmArgs the bootstrap method constant arguments.
+ * @param name
+ * name of the invoked method.
+ * @param desc
+ * descriptor of the invoke method.
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments.
*
- * @return the index of a new or already existing invokedynamic
- * reference item.
- */
- public int newInvokeDynamic(
- final String name,
- final String desc,
- final Handle bsm,
- final Object... bsmArgs)
- {
+ * @return the index of a new or already existing invokedynamic reference
+ * item.
+ */
+ public int newInvokeDynamic(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index;
}
@@ -1271,13 +1264,15 @@ public class ClassWriter extends ClassVisitor {
* Adds a field reference to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
*
- * @param owner the internal name of the field's owner class.
- * @param name the field's name.
- * @param desc the field's descriptor.
+ * @param owner
+ * the internal name of the field's owner class.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor.
* @return a new or already existing field reference item.
*/
- Item newFieldItem(final String owner, final String name, final String desc)
- {
+ Item newFieldItem(final String owner, final String name, final String desc) {
key3.set(FIELD, owner, name, desc);
Item result = get(key3);
if (result == null) {
@@ -1294,13 +1289,15 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param owner the internal name of the field's owner class.
- * @param name the field's name.
- * @param desc the field's descriptor.
+ * @param owner
+ * the internal name of the field's owner class.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor.
* @return the index of a new or already existing field reference item.
*/
- public int newField(final String owner, final String name, final String desc)
- {
+ public int newField(final String owner, final String name, final String desc) {
return newFieldItem(owner, name, desc).index;
}
@@ -1308,18 +1305,18 @@ public class ClassWriter extends ClassVisitor {
* Adds a method reference to the constant pool of the class being build.
* Does nothing if the constant pool already contains a similar item.
*
- * @param owner the internal name of the method's owner class.
- * @param name the method's name.
- * @param desc the method's descriptor.
- * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
+ * @param owner
+ * the internal name of the method's owner class.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor.
+ * @param itf
+ * <tt>true</tt> if <tt>owner</tt> is an interface.
* @return a new or already existing method reference item.
*/
- Item newMethodItem(
- final String owner,
- final String name,
- final String desc,
- final boolean itf)
- {
+ Item newMethodItem(final String owner, final String name,
+ final String desc, final boolean itf) {
int type = itf ? IMETH : METH;
key3.set(type, owner, name, desc);
Item result = get(key3);
@@ -1337,18 +1334,18 @@ public class ClassWriter extends ClassVisitor {
* <i>This method is intended for {@link Attribute} sub classes, and is
* normally not needed by class generators or adapters.</i>
*
- * @param owner the internal name of the method's owner class.
- * @param name the method's name.
- * @param desc the method's descriptor.
- * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
+ * @param owner
+ * the internal name of the method's owner class.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor.
+ * @param itf
+ * <tt>true</tt> if <tt>owner</tt> is an interface.
* @return the index of a new or already existing method reference item.
*/
- public int newMethod(
- final String owner,
- final String name,
- final String desc,
- final boolean itf)
- {
+ public int newMethod(final String owner, final String name,
+ final String desc, final boolean itf) {
return newMethodItem(owner, name, desc, itf).index;
}
@@ -1356,7 +1353,8 @@ public class ClassWriter extends ClassVisitor {
* Adds an integer to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item.
*
- * @param value the int value.
+ * @param value
+ * the int value.
* @return a new or already existing int item.
*/
Item newInteger(final int value) {
@@ -1374,7 +1372,8 @@ public class ClassWriter extends ClassVisitor {
* Adds a float to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
- * @param value the float value.
+ * @param value
+ * the float value.
* @return a new or already existing float item.
*/
Item newFloat(final float value) {
@@ -1392,7 +1391,8 @@ public class ClassWriter extends ClassVisitor {
* Adds a long to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
- * @param value the long value.
+ * @param value
+ * the long value.
* @return a new or already existing long item.
*/
Item newLong(final long value) {
@@ -1411,7 +1411,8 @@ public class ClassWriter extends ClassVisitor {
* Adds a double to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
- * @param value the double value.
+ * @param value
+ * the double value.
* @return a new or already existing double item.
*/
Item newDouble(final double value) {
@@ -1430,7 +1431,8 @@ public class ClassWriter extends ClassVisitor {
* Adds a string to the constant pool of the class being build. Does nothing
* if the constant pool already contains a similar item.
*
- * @param value the String value.
+ * @param value
+ * the String value.
* @return a new or already existing string item.
*/
private Item newString(final String value) {
@@ -1450,8 +1452,10 @@ public class ClassWriter extends ClassVisitor {
* method is intended for {@link Attribute} sub classes, and is normally not
* needed by class generators or adapters.</i>
*
- * @param name a name.
- * @param desc a type descriptor.
+ * @param name
+ * a name.
+ * @param desc
+ * a type descriptor.
* @return the index of a new or already existing name and type item.
*/
public int newNameType(final String name, final String desc) {
@@ -1462,8 +1466,10 @@ public class ClassWriter extends ClassVisitor {
* Adds a name and type to the constant pool of the class being build. Does
* nothing if the constant pool already contains a similar item.
*
- * @param name a name.
- * @param desc a type descriptor.
+ * @param name
+ * a name.
+ * @param desc
+ * a type descriptor.
* @return a new or already existing name and type item.
*/
Item newNameTypeItem(final String name, final String desc) {
@@ -1481,7 +1487,8 @@ public class ClassWriter extends ClassVisitor {
* Adds the given internal name to {@link #typeTable} and returns its index.
* Does nothing if the type table already contains this internal name.
*
- * @param type the internal name to be added to the type table.
+ * @param type
+ * the internal name to be added to the type table.
* @return the index of this internal name in the type table.
*/
int addType(final String type) {
@@ -1498,9 +1505,11 @@ public class ClassWriter extends ClassVisitor {
* index. This method is used for UNINITIALIZED types, made of an internal
* name and a bytecode offset.
*
- * @param type the internal name to be added to the type table.
- * @param offset the bytecode offset of the NEW instruction that created
- * this UNINITIALIZED type value.
+ * @param type
+ * the internal name to be added to the type table.
+ * @param offset
+ * the bytecode offset of the NEW instruction that created this
+ * UNINITIALIZED type value.
* @return the index of this internal name in the type table.
*/
int addUninitializedType(final String type, final int offset) {
@@ -1518,7 +1527,8 @@ public class ClassWriter extends ClassVisitor {
/**
* Adds the given Item to {@link #typeTable}.
*
- * @param item the value to be added to the type table.
+ * @param item
+ * the value to be added to the type table.
* @return the added Item, which a new Item instance with the same value as
* the given Item.
*/
@@ -1544,8 +1554,10 @@ public class ClassWriter extends ClassVisitor {
* {@link #items} hash table to speedup future calls with the same
* parameters.
*
- * @param type1 index of an internal name in {@link #typeTable}.
- * @param type2 index of an internal name in {@link #typeTable}.
+ * @param type1
+ * index of an internal name in {@link #typeTable}.
+ * @param type2
+ * index of an internal name in {@link #typeTable}.
* @return the index of the common super type of the two given types.
*/
int getMergedType(final int type1, final int type2) {
@@ -1572,13 +1584,14 @@ public class ClassWriter extends ClassVisitor {
* that is currently being generated by this ClassWriter, which can of
* course not be loaded since it is under construction.
*
- * @param type1 the internal name of a class.
- * @param type2 the internal name of another class.
+ * @param type1
+ * the internal name of a class.
+ * @param type2
+ * the internal name of another class.
* @return the internal name of the common super class of the two given
* classes.
*/
- protected String getCommonSuperClass(final String type1, final String type2)
- {
+ protected String getCommonSuperClass(final String type1, final String type2) {
Class<?> c, d;
ClassLoader classLoader = getClass().getClassLoader();
try {
@@ -1607,7 +1620,8 @@ public class ClassWriter extends ClassVisitor {
* Returns the constant pool's hash table item which is equal to the given
* item.
*
- * @param key a constant pool item.
+ * @param key
+ * a constant pool item.
* @return the constant pool's hash table item which is equal to the given
* item, or <tt>null</tt> if there is no such item.
*/
@@ -1623,7 +1637,8 @@ public class ClassWriter extends ClassVisitor {
* Puts the given item in the constant pool's hash table. The hash table
* <i>must</i> not already contains this item.
*
- * @param i the item to be added to the constant pool's hash table.
+ * @param i
+ * the item to be added to the constant pool's hash table.
*/
private void put(final Item i) {
if (index + typeCount > threshold) {
@@ -1651,9 +1666,12 @@ public class ClassWriter extends ClassVisitor {
/**
* Puts one byte and two shorts into the constant pool.
*
- * @param b a byte.
- * @param s1 a short.
- * @param s2 another short.
+ * @param b
+ * a byte.
+ * @param s1
+ * a short.
+ * @param s2
+ * another short.
*/
private void put122(final int b, final int s1, final int s2) {
pool.put12(b, s1).putShort(s2);
@@ -1662,9 +1680,12 @@ public class ClassWriter extends ClassVisitor {
/**
* Puts two bytes and one short into the constant pool.
*
- * @param b1 a byte.
- * @param b2 another byte.
- * @param s a short.
+ * @param b1
+ * a byte.
+ * @param b2
+ * another byte.
+ * @param s
+ * a short.
*/
private void put112(final int b1, final int b2, final int s) {
pool.put11(b1, b2).putShort(s);
diff --git a/src/asm/scala/tools/asm/Context.java b/src/asm/scala/tools/asm/Context.java
new file mode 100644
index 0000000000..7b3a2ad9dd
--- /dev/null
+++ b/src/asm/scala/tools/asm/Context.java
@@ -0,0 +1,110 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package scala.tools.asm;
+
+/**
+ * Information about a class being parsed in a {@link ClassReader}.
+ *
+ * @author Eric Bruneton
+ */
+class Context {
+
+ /**
+ * Prototypes of the attributes that must be parsed for this class.
+ */
+ Attribute[] attrs;
+
+ /**
+ * The {@link ClassReader} option flags for the parsing of this class.
+ */
+ int flags;
+
+ /**
+ * The buffer used to read strings.
+ */
+ char[] buffer;
+
+ /**
+ * The start index of each bootstrap method.
+ */
+ int[] bootstrapMethods;
+
+ /**
+ * The access flags of the method currently being parsed.
+ */
+ int access;
+
+ /**
+ * The name of the method currently being parsed.
+ */
+ String name;
+
+ /**
+ * The descriptor of the method currently being parsed.
+ */
+ String desc;
+
+ /**
+ * The offset of the latest stack map frame that has been parsed.
+ */
+ int offset;
+
+ /**
+ * The encoding of the latest stack map frame that has been parsed.
+ */
+ int mode;
+
+ /**
+ * The number of locals in the latest stack map frame that has been parsed.
+ */
+ int localCount;
+
+ /**
+ * The number locals in the latest stack map frame that has been parsed,
+ * minus the number of locals in the previous frame.
+ */
+ int localDiff;
+
+ /**
+ * The local values of the latest stack map frame that has been parsed.
+ */
+ Object[] local;
+
+ /**
+ * The stack size of the latest stack map frame that has been parsed.
+ */
+ int stackCount;
+
+ /**
+ * The stack values of the latest stack map frame that has been parsed.
+ */
+ Object[] stack;
+}
diff --git a/src/asm/scala/tools/asm/FieldVisitor.java b/src/asm/scala/tools/asm/FieldVisitor.java
index 9ac0f6236f..9171f331e5 100644
--- a/src/asm/scala/tools/asm/FieldVisitor.java
+++ b/src/asm/scala/tools/asm/FieldVisitor.java
@@ -30,9 +30,9 @@
package scala.tools.asm;
/**
- * A visitor to visit a Java field. The methods of this class must be called
- * in the following order: ( <tt>visitAnnotation</tt> |
- * <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
+ * A visitor to visit a Java field. The methods of this class must be called in
+ * the following order: ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )*
+ * <tt>visitEnd</tt>.
*
* @author Eric Bruneton
*/
@@ -53,8 +53,9 @@ public abstract class FieldVisitor {
/**
* Constructs a new {@link FieldVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public FieldVisitor(final int api) {
this(api, null);
@@ -63,15 +64,17 @@ public abstract class FieldVisitor {
/**
* Constructs a new {@link FieldVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param fv the field visitor to which this visitor must delegate method
- * calls. May be null.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param fv
+ * the field visitor to which this visitor must delegate method
+ * calls. May be null.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
- /*if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4) {
throw new IllegalArgumentException();
- }*/
+ }
this.api = api;
this.fv = fv;
}
@@ -79,8 +82,10 @@ public abstract class FieldVisitor {
/**
* Visits an annotation of the field.
*
- * @param desc the class descriptor of the annotation class.
- * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
@@ -94,7 +99,8 @@ public abstract class FieldVisitor {
/**
* Visits a non standard attribute of the field.
*
- * @param attr an attribute.
+ * @param attr
+ * an attribute.
*/
public void visitAttribute(Attribute attr) {
if (fv != null) {
diff --git a/src/asm/scala/tools/asm/FieldWriter.java b/src/asm/scala/tools/asm/FieldWriter.java
index 45ef6d0df3..02c6059b91 100644
--- a/src/asm/scala/tools/asm/FieldWriter.java
+++ b/src/asm/scala/tools/asm/FieldWriter.java
@@ -92,21 +92,21 @@ final class FieldWriter extends FieldVisitor {
/**
* Constructs a new {@link FieldWriter}.
*
- * @param cw the class writer to which this field must be added.
- * @param access the field's access flags (see {@link Opcodes}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type}).
- * @param signature the field's signature. May be <tt>null</tt>.
- * @param value the field's constant value. May be <tt>null</tt>.
+ * @param cw
+ * the class writer to which this field must be added.
+ * @param access
+ * the field's access flags (see {@link Opcodes}).
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type}).
+ * @param signature
+ * the field's signature. May be <tt>null</tt>.
+ * @param value
+ * the field's constant value. May be <tt>null</tt>.
*/
- FieldWriter(
- final ClassWriter cw,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ FieldWriter(final ClassWriter cw, final int access, final String name,
+ final String desc, final String signature, final Object value) {
super(Opcodes.ASM4);
if (cw.firstField == null) {
cw.firstField = this;
@@ -131,10 +131,8 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -177,11 +175,12 @@ final class FieldWriter extends FieldVisitor {
cw.newUTF8("ConstantValue");
size += 8;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- cw.newUTF8("Synthetic");
- size += 6;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ cw.newUTF8("Synthetic");
+ size += 6;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
@@ -208,21 +207,23 @@ final class FieldWriter extends FieldVisitor {
/**
* Puts the content of this field into the given byte vector.
*
- * @param out where the content of this field must be put.
+ * @param out
+ * where the content of this field must be put.
*/
void put(final ByteVector out) {
- int mask = Opcodes.ACC_DEPRECATED
- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+ int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
if (value != 0) {
++attributeCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- ++attributeCount;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
@@ -244,10 +245,11 @@ final class FieldWriter extends FieldVisitor {
out.putShort(cw.newUTF8("ConstantValue"));
out.putInt(2).putShort(value);
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
diff --git a/src/asm/scala/tools/asm/Frame.java b/src/asm/scala/tools/asm/Frame.java
index 387b56796d..bcc3e8450b 100644
--- a/src/asm/scala/tools/asm/Frame.java
+++ b/src/asm/scala/tools/asm/Frame.java
@@ -80,13 +80,13 @@ final class Frame {
* table contains only internal type names (array type descriptors are
* forbidden - dimensions must be represented through the DIM field).
*
- * The LONG and DOUBLE types are always represented by using two slots (LONG +
- * TOP or DOUBLE + TOP), for local variable types as well as in the operand
- * stack. This is necessary to be able to simulate DUPx_y instructions,
- * whose effect would be dependent on the actual type values if types were
- * always represented by a single slot in the stack (and this is not
- * possible, since actual type values are not always known - cf LOCAL and
- * STACK type kinds).
+ * The LONG and DOUBLE types are always represented by using two slots (LONG
+ * + TOP or DOUBLE + TOP), for local variable types as well as in the
+ * operand stack. This is necessary to be able to simulate DUPx_y
+ * instructions, whose effect would be dependent on the actual type values
+ * if types were always represented by a single slot in the stack (and this
+ * is not possible, since actual type values are not always known - cf LOCAL
+ * and STACK type kinds).
*/
/**
@@ -117,9 +117,9 @@ final class Frame {
/**
* Flag used for LOCAL and STACK types. Indicates that if this type happens
* to be a long or double type (during the computations of input frames),
- * then it must be set to TOP because the second word of this value has
- * been reused to store other data in the basic block. Hence the first word
- * no longer stores a valid long or double value.
+ * then it must be set to TOP because the second word of this value has been
+ * reused to store other data in the basic block. Hence the first word no
+ * longer stores a valid long or double value.
*/
static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
@@ -523,7 +523,8 @@ final class Frame {
/**
* Returns the output frame local variable type at the given index.
*
- * @param local the index of the local that must be returned.
+ * @param local
+ * the index of the local that must be returned.
* @return the output frame local variable type at the given index.
*/
private int get(final int local) {
@@ -545,8 +546,10 @@ final class Frame {
/**
* Sets the output frame local variable type at the given index.
*
- * @param local the index of the local that must be set.
- * @param type the value of the local that must be set.
+ * @param local
+ * the index of the local that must be set.
+ * @param type
+ * the value of the local that must be set.
*/
private void set(final int local, final int type) {
// creates and/or resizes the output local variables array if necessary
@@ -566,7 +569,8 @@ final class Frame {
/**
* Pushes a new type onto the output frame stack.
*
- * @param type the type that must be pushed.
+ * @param type
+ * the type that must be pushed.
*/
private void push(final int type) {
// creates and/or resizes the output stack array if necessary
@@ -591,10 +595,12 @@ final class Frame {
/**
* Pushes a new type onto the output frame stack.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param desc the descriptor of the type to be pushed. Can also be a method
- * descriptor (in this case this method pushes its return type onto
- * the output frame stack).
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param desc
+ * the descriptor of the type to be pushed. Can also be a method
+ * descriptor (in this case this method pushes its return type
+ * onto the output frame stack).
*/
private void push(final ClassWriter cw, final String desc) {
int type = type(cw, desc);
@@ -609,72 +615,74 @@ final class Frame {
/**
* Returns the int encoding of the given type.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param desc a type descriptor.
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param desc
+ * a type descriptor.
* @return the int encoding of the given type.
*/
private static int type(final ClassWriter cw, final String desc) {
String t;
int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
switch (desc.charAt(index)) {
- case 'V':
- return 0;
+ case 'V':
+ return 0;
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ return INTEGER;
+ case 'F':
+ return FLOAT;
+ case 'J':
+ return LONG;
+ case 'D':
+ return DOUBLE;
+ case 'L':
+ // stores the internal name, not the descriptor!
+ t = desc.substring(index + 1, desc.length() - 1);
+ return OBJECT | cw.addType(t);
+ // case '[':
+ default:
+ // extracts the dimensions and the element type
+ int data;
+ int dims = index + 1;
+ while (desc.charAt(dims) == '[') {
+ ++dims;
+ }
+ switch (desc.charAt(dims)) {
case 'Z':
+ data = BOOLEAN;
+ break;
case 'C':
+ data = CHAR;
+ break;
case 'B':
+ data = BYTE;
+ break;
case 'S':
+ data = SHORT;
+ break;
case 'I':
- return INTEGER;
+ data = INTEGER;
+ break;
case 'F':
- return FLOAT;
+ data = FLOAT;
+ break;
case 'J':
- return LONG;
+ data = LONG;
+ break;
case 'D':
- return DOUBLE;
- case 'L':
- // stores the internal name, not the descriptor!
- t = desc.substring(index + 1, desc.length() - 1);
- return OBJECT | cw.addType(t);
- // case '[':
+ data = DOUBLE;
+ break;
+ // case 'L':
default:
- // extracts the dimensions and the element type
- int data;
- int dims = index + 1;
- while (desc.charAt(dims) == '[') {
- ++dims;
- }
- switch (desc.charAt(dims)) {
- case 'Z':
- data = BOOLEAN;
- break;
- case 'C':
- data = CHAR;
- break;
- case 'B':
- data = BYTE;
- break;
- case 'S':
- data = SHORT;
- break;
- case 'I':
- data = INTEGER;
- break;
- case 'F':
- data = FLOAT;
- break;
- case 'J':
- data = LONG;
- break;
- case 'D':
- data = DOUBLE;
- break;
- // case 'L':
- default:
- // stores the internal name, not the descriptor
- t = desc.substring(dims + 1, desc.length() - 1);
- data = OBJECT | cw.addType(t);
- }
- return (dims - index) << 28 | data;
+ // stores the internal name, not the descriptor
+ t = desc.substring(dims + 1, desc.length() - 1);
+ data = OBJECT | cw.addType(t);
+ }
+ return (dims - index) << 28 | data;
}
}
@@ -695,7 +703,8 @@ final class Frame {
/**
* Pops the given number of types from the output frame stack.
*
- * @param elements the number of types that must be popped.
+ * @param elements
+ * the number of types that must be popped.
*/
private void pop(final int elements) {
if (outputStackTop >= elements) {
@@ -712,9 +721,10 @@ final class Frame {
/**
* Pops a type from the output frame stack.
*
- * @param desc the descriptor of the type to be popped. Can also be a method
- * descriptor (in this case this method pops the types corresponding
- * to the method arguments).
+ * @param desc
+ * the descriptor of the type to be popped. Can also be a method
+ * descriptor (in this case this method pops the types
+ * corresponding to the method arguments).
*/
private void pop(final String desc) {
char c = desc.charAt(0);
@@ -731,7 +741,8 @@ final class Frame {
* Adds a new type to the list of types on which a constructor is invoked in
* the basic block.
*
- * @param var a type on a which a constructor is invoked.
+ * @param var
+ * a type on a which a constructor is invoked.
*/
private void init(final int var) {
// creates and/or resizes the initializations array if necessary
@@ -752,8 +763,10 @@ final class Frame {
* Replaces the given type with the appropriate type if it is one of the
* types on which a constructor is invoked in the basic block.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param t a type
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param t
+ * a type
* @return t or, if t is one of the types on which a constructor is invoked
* in the basic block, the type corresponding to this constructor.
*/
@@ -787,17 +800,17 @@ final class Frame {
* Initializes the input frame of the first basic block from the method
* descriptor.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param access the access flags of the method to which this label belongs.
- * @param args the formal parameter types of this method.
- * @param maxLocals the maximum number of local variables of this method.
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param access
+ * the access flags of the method to which this label belongs.
+ * @param args
+ * the formal parameter types of this method.
+ * @param maxLocals
+ * the maximum number of local variables of this method.
*/
- void initInputFrame(
- final ClassWriter cw,
- final int access,
- final Type[] args,
- final int maxLocals)
- {
+ void initInputFrame(final ClassWriter cw, final int access,
+ final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals];
inputStack = new int[0];
int i = 0;
@@ -823,435 +836,435 @@ final class Frame {
/**
* Simulates the action of the given instruction on the output stack frame.
*
- * @param opcode the opcode of the instruction.
- * @param arg the operand of the instruction, if any.
- * @param cw the class writer to which this label belongs.
- * @param item the operand of the instructions, if any.
+ * @param opcode
+ * the opcode of the instruction.
+ * @param arg
+ * the operand of the instruction, if any.
+ * @param cw
+ * the class writer to which this label belongs.
+ * @param item
+ * the operand of the instructions, if any.
*/
- void execute(
- final int opcode,
- final int arg,
- final ClassWriter cw,
- final Item item)
- {
+ void execute(final int opcode, final int arg, final ClassWriter cw,
+ final Item item) {
int t1, t2, t3, t4;
switch (opcode) {
- case Opcodes.NOP:
- case Opcodes.INEG:
- case Opcodes.LNEG:
- case Opcodes.FNEG:
- case Opcodes.DNEG:
- case Opcodes.I2B:
- case Opcodes.I2C:
- case Opcodes.I2S:
- case Opcodes.GOTO:
- case Opcodes.RETURN:
- break;
- case Opcodes.ACONST_NULL:
- push(NULL);
- break;
- case Opcodes.ICONST_M1:
- case Opcodes.ICONST_0:
- case Opcodes.ICONST_1:
- case Opcodes.ICONST_2:
- case Opcodes.ICONST_3:
- case Opcodes.ICONST_4:
- case Opcodes.ICONST_5:
- case Opcodes.BIPUSH:
- case Opcodes.SIPUSH:
- case Opcodes.ILOAD:
+ case Opcodes.NOP:
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ case Opcodes.GOTO:
+ case Opcodes.RETURN:
+ break;
+ case Opcodes.ACONST_NULL:
+ push(NULL);
+ break;
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ case Opcodes.ILOAD:
+ push(INTEGER);
+ break;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.LLOAD:
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.FLOAD:
+ push(FLOAT);
+ break;
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.DLOAD:
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LDC:
+ switch (item.type) {
+ case ClassWriter.INT:
push(INTEGER);
break;
- case Opcodes.LCONST_0:
- case Opcodes.LCONST_1:
- case Opcodes.LLOAD:
+ case ClassWriter.LONG:
push(LONG);
push(TOP);
break;
- case Opcodes.FCONST_0:
- case Opcodes.FCONST_1:
- case Opcodes.FCONST_2:
- case Opcodes.FLOAD:
+ case ClassWriter.FLOAT:
push(FLOAT);
break;
- case Opcodes.DCONST_0:
- case Opcodes.DCONST_1:
- case Opcodes.DLOAD:
+ case ClassWriter.DOUBLE:
push(DOUBLE);
push(TOP);
break;
- case Opcodes.LDC:
- switch (item.type) {
- case ClassWriter.INT:
- push(INTEGER);
- break;
- case ClassWriter.LONG:
- push(LONG);
- push(TOP);
- break;
- case ClassWriter.FLOAT:
- push(FLOAT);
- break;
- case ClassWriter.DOUBLE:
- push(DOUBLE);
- push(TOP);
- break;
- case ClassWriter.CLASS:
- push(OBJECT | cw.addType("java/lang/Class"));
- break;
- case ClassWriter.STR:
- push(OBJECT | cw.addType("java/lang/String"));
- break;
- case ClassWriter.MTYPE:
- push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
- break;
- // case ClassWriter.HANDLE_BASE + [1..9]:
- default:
- push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
- }
- break;
- case Opcodes.ALOAD:
- push(get(arg));
- break;
- case Opcodes.IALOAD:
- case Opcodes.BALOAD:
- case Opcodes.CALOAD:
- case Opcodes.SALOAD:
- pop(2);
- push(INTEGER);
- break;
- case Opcodes.LALOAD:
- case Opcodes.D2L:
- pop(2);
- push(LONG);
- push(TOP);
+ case ClassWriter.CLASS:
+ push(OBJECT | cw.addType("java/lang/Class"));
break;
- case Opcodes.FALOAD:
- pop(2);
- push(FLOAT);
+ case ClassWriter.STR:
+ push(OBJECT | cw.addType("java/lang/String"));
break;
- case Opcodes.DALOAD:
- case Opcodes.L2D:
- pop(2);
- push(DOUBLE);
- push(TOP);
+ case ClassWriter.MTYPE:
+ push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
break;
- case Opcodes.AALOAD:
- pop(1);
- t1 = pop();
- push(ELEMENT_OF + t1);
- break;
- case Opcodes.ISTORE:
- case Opcodes.FSTORE:
- case Opcodes.ASTORE:
- t1 = pop();
- set(arg, t1);
- if (arg > 0) {
- t2 = get(arg - 1);
- // if t2 is of kind STACK or LOCAL we cannot know its size!
- if (t2 == LONG || t2 == DOUBLE) {
- set(arg - 1, TOP);
- } else if ((t2 & KIND) != BASE) {
- set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
- }
+ // case ClassWriter.HANDLE_BASE + [1..9]:
+ default:
+ push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
+ }
+ break;
+ case Opcodes.ALOAD:
+ push(get(arg));
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ pop(2);
+ push(INTEGER);
+ break;
+ case Opcodes.LALOAD:
+ case Opcodes.D2L:
+ pop(2);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FALOAD:
+ pop(2);
+ push(FLOAT);
+ break;
+ case Opcodes.DALOAD:
+ case Opcodes.L2D:
+ pop(2);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.AALOAD:
+ pop(1);
+ t1 = pop();
+ push(ELEMENT_OF + t1);
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.ASTORE:
+ t1 = pop();
+ set(arg, t1);
+ if (arg > 0) {
+ t2 = get(arg - 1);
+ // if t2 is of kind STACK or LOCAL we cannot know its size!
+ if (t2 == LONG || t2 == DOUBLE) {
+ set(arg - 1, TOP);
+ } else if ((t2 & KIND) != BASE) {
+ set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
}
- break;
- case Opcodes.LSTORE:
- case Opcodes.DSTORE:
- pop(1);
- t1 = pop();
- set(arg, t1);
- set(arg + 1, TOP);
- if (arg > 0) {
- t2 = get(arg - 1);
- // if t2 is of kind STACK or LOCAL we cannot know its size!
- if (t2 == LONG || t2 == DOUBLE) {
- set(arg - 1, TOP);
- } else if ((t2 & KIND) != BASE) {
- set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
- }
+ }
+ break;
+ case Opcodes.LSTORE:
+ case Opcodes.DSTORE:
+ pop(1);
+ t1 = pop();
+ set(arg, t1);
+ set(arg + 1, TOP);
+ if (arg > 0) {
+ t2 = get(arg - 1);
+ // if t2 is of kind STACK or LOCAL we cannot know its size!
+ if (t2 == LONG || t2 == DOUBLE) {
+ set(arg - 1, TOP);
+ } else if ((t2 & KIND) != BASE) {
+ set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
}
- break;
- case Opcodes.IASTORE:
- case Opcodes.BASTORE:
- case Opcodes.CASTORE:
- case Opcodes.SASTORE:
- case Opcodes.FASTORE:
- case Opcodes.AASTORE:
- pop(3);
- break;
- case Opcodes.LASTORE:
- case Opcodes.DASTORE:
- pop(4);
- break;
- case Opcodes.POP:
- case Opcodes.IFEQ:
- case Opcodes.IFNE:
- case Opcodes.IFLT:
- case Opcodes.IFGE:
- case Opcodes.IFGT:
- case Opcodes.IFLE:
- case Opcodes.IRETURN:
- case Opcodes.FRETURN:
- case Opcodes.ARETURN:
- case Opcodes.TABLESWITCH:
- case Opcodes.LOOKUPSWITCH:
- case Opcodes.ATHROW:
- case Opcodes.MONITORENTER:
- case Opcodes.MONITOREXIT:
- case Opcodes.IFNULL:
- case Opcodes.IFNONNULL:
- pop(1);
- break;
- case Opcodes.POP2:
- case Opcodes.IF_ICMPEQ:
- case Opcodes.IF_ICMPNE:
- case Opcodes.IF_ICMPLT:
- case Opcodes.IF_ICMPGE:
- case Opcodes.IF_ICMPGT:
- case Opcodes.IF_ICMPLE:
- case Opcodes.IF_ACMPEQ:
- case Opcodes.IF_ACMPNE:
- case Opcodes.LRETURN:
- case Opcodes.DRETURN:
- pop(2);
- break;
- case Opcodes.DUP:
- t1 = pop();
- push(t1);
- push(t1);
- break;
- case Opcodes.DUP_X1:
- t1 = pop();
- t2 = pop();
- push(t1);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP_X2:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- push(t1);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2:
- t1 = pop();
- t2 = pop();
- push(t2);
- push(t1);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2_X1:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- push(t2);
- push(t1);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.DUP2_X2:
- t1 = pop();
- t2 = pop();
- t3 = pop();
- t4 = pop();
- push(t2);
- push(t1);
- push(t4);
- push(t3);
- push(t2);
- push(t1);
- break;
- case Opcodes.SWAP:
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.AASTORE:
+ pop(3);
+ break;
+ case Opcodes.LASTORE:
+ case Opcodes.DASTORE:
+ pop(4);
+ break;
+ case Opcodes.POP:
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.IRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ case Opcodes.ATHROW:
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ pop(1);
+ break;
+ case Opcodes.POP2:
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.LRETURN:
+ case Opcodes.DRETURN:
+ pop(2);
+ break;
+ case Opcodes.DUP:
+ t1 = pop();
+ push(t1);
+ push(t1);
+ break;
+ case Opcodes.DUP_X1:
+ t1 = pop();
+ t2 = pop();
+ push(t1);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP_X2:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ push(t1);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2:
+ t1 = pop();
+ t2 = pop();
+ push(t2);
+ push(t1);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2_X1:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ push(t2);
+ push(t1);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.DUP2_X2:
+ t1 = pop();
+ t2 = pop();
+ t3 = pop();
+ t4 = pop();
+ push(t2);
+ push(t1);
+ push(t4);
+ push(t3);
+ push(t2);
+ push(t1);
+ break;
+ case Opcodes.SWAP:
+ t1 = pop();
+ t2 = pop();
+ push(t1);
+ push(t2);
+ break;
+ case Opcodes.IADD:
+ case Opcodes.ISUB:
+ case Opcodes.IMUL:
+ case Opcodes.IDIV:
+ case Opcodes.IREM:
+ case Opcodes.IAND:
+ case Opcodes.IOR:
+ case Opcodes.IXOR:
+ case Opcodes.ISHL:
+ case Opcodes.ISHR:
+ case Opcodes.IUSHR:
+ case Opcodes.L2I:
+ case Opcodes.D2I:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ pop(2);
+ push(INTEGER);
+ break;
+ case Opcodes.LADD:
+ case Opcodes.LSUB:
+ case Opcodes.LMUL:
+ case Opcodes.LDIV:
+ case Opcodes.LREM:
+ case Opcodes.LAND:
+ case Opcodes.LOR:
+ case Opcodes.LXOR:
+ pop(4);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.FADD:
+ case Opcodes.FSUB:
+ case Opcodes.FMUL:
+ case Opcodes.FDIV:
+ case Opcodes.FREM:
+ case Opcodes.L2F:
+ case Opcodes.D2F:
+ pop(2);
+ push(FLOAT);
+ break;
+ case Opcodes.DADD:
+ case Opcodes.DSUB:
+ case Opcodes.DMUL:
+ case Opcodes.DDIV:
+ case Opcodes.DREM:
+ pop(4);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.LSHL:
+ case Opcodes.LSHR:
+ case Opcodes.LUSHR:
+ pop(3);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.IINC:
+ set(arg, INTEGER);
+ break;
+ case Opcodes.I2L:
+ case Opcodes.F2L:
+ pop(1);
+ push(LONG);
+ push(TOP);
+ break;
+ case Opcodes.I2F:
+ pop(1);
+ push(FLOAT);
+ break;
+ case Opcodes.I2D:
+ case Opcodes.F2D:
+ pop(1);
+ push(DOUBLE);
+ push(TOP);
+ break;
+ case Opcodes.F2I:
+ case Opcodes.ARRAYLENGTH:
+ case Opcodes.INSTANCEOF:
+ pop(1);
+ push(INTEGER);
+ break;
+ case Opcodes.LCMP:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ pop(4);
+ push(INTEGER);
+ break;
+ case Opcodes.JSR:
+ case Opcodes.RET:
+ throw new RuntimeException(
+ "JSR/RET are not supported with computeFrames option");
+ case Opcodes.GETSTATIC:
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.PUTSTATIC:
+ pop(item.strVal3);
+ break;
+ case Opcodes.GETFIELD:
+ pop(1);
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.PUTFIELD:
+ pop(item.strVal3);
+ pop();
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE:
+ pop(item.strVal3);
+ if (opcode != Opcodes.INVOKESTATIC) {
t1 = pop();
- t2 = pop();
- push(t1);
- push(t2);
- break;
- case Opcodes.IADD:
- case Opcodes.ISUB:
- case Opcodes.IMUL:
- case Opcodes.IDIV:
- case Opcodes.IREM:
- case Opcodes.IAND:
- case Opcodes.IOR:
- case Opcodes.IXOR:
- case Opcodes.ISHL:
- case Opcodes.ISHR:
- case Opcodes.IUSHR:
- case Opcodes.L2I:
- case Opcodes.D2I:
- case Opcodes.FCMPL:
- case Opcodes.FCMPG:
- pop(2);
- push(INTEGER);
- break;
- case Opcodes.LADD:
- case Opcodes.LSUB:
- case Opcodes.LMUL:
- case Opcodes.LDIV:
- case Opcodes.LREM:
- case Opcodes.LAND:
- case Opcodes.LOR:
- case Opcodes.LXOR:
- pop(4);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.FADD:
- case Opcodes.FSUB:
- case Opcodes.FMUL:
- case Opcodes.FDIV:
- case Opcodes.FREM:
- case Opcodes.L2F:
- case Opcodes.D2F:
- pop(2);
- push(FLOAT);
- break;
- case Opcodes.DADD:
- case Opcodes.DSUB:
- case Opcodes.DMUL:
- case Opcodes.DDIV:
- case Opcodes.DREM:
- pop(4);
- push(DOUBLE);
- push(TOP);
- break;
- case Opcodes.LSHL:
- case Opcodes.LSHR:
- case Opcodes.LUSHR:
- pop(3);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.IINC:
- set(arg, INTEGER);
- break;
- case Opcodes.I2L:
- case Opcodes.F2L:
- pop(1);
- push(LONG);
- push(TOP);
- break;
- case Opcodes.I2F:
- pop(1);
- push(FLOAT);
- break;
- case Opcodes.I2D:
- case Opcodes.F2D:
- pop(1);
- push(DOUBLE);
- push(TOP);
- break;
- case Opcodes.F2I:
- case Opcodes.ARRAYLENGTH:
- case Opcodes.INSTANCEOF:
- pop(1);
- push(INTEGER);
- break;
- case Opcodes.LCMP:
- case Opcodes.DCMPL:
- case Opcodes.DCMPG:
- pop(4);
- push(INTEGER);
- break;
- case Opcodes.JSR:
- case Opcodes.RET:
- throw new RuntimeException("JSR/RET are not supported with computeFrames option");
- case Opcodes.GETSTATIC:
- push(cw, item.strVal3);
- break;
- case Opcodes.PUTSTATIC:
- pop(item.strVal3);
- break;
- case Opcodes.GETFIELD:
- pop(1);
- push(cw, item.strVal3);
- break;
- case Opcodes.PUTFIELD:
- pop(item.strVal3);
- pop();
- break;
- case Opcodes.INVOKEVIRTUAL:
- case Opcodes.INVOKESPECIAL:
- case Opcodes.INVOKESTATIC:
- case Opcodes.INVOKEINTERFACE:
- pop(item.strVal3);
- if (opcode != Opcodes.INVOKESTATIC) {
- t1 = pop();
- if (opcode == Opcodes.INVOKESPECIAL
- && item.strVal2.charAt(0) == '<')
- {
- init(t1);
- }
+ if (opcode == Opcodes.INVOKESPECIAL
+ && item.strVal2.charAt(0) == '<') {
+ init(t1);
}
- push(cw, item.strVal3);
+ }
+ push(cw, item.strVal3);
+ break;
+ case Opcodes.INVOKEDYNAMIC:
+ pop(item.strVal2);
+ push(cw, item.strVal2);
+ break;
+ case Opcodes.NEW:
+ push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+ break;
+ case Opcodes.NEWARRAY:
+ pop();
+ switch (arg) {
+ case Opcodes.T_BOOLEAN:
+ push(ARRAY_OF | BOOLEAN);
break;
- case Opcodes.INVOKEDYNAMIC:
- pop(item.strVal2);
- push(cw, item.strVal2);
+ case Opcodes.T_CHAR:
+ push(ARRAY_OF | CHAR);
break;
- case Opcodes.NEW:
- push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+ case Opcodes.T_BYTE:
+ push(ARRAY_OF | BYTE);
break;
- case Opcodes.NEWARRAY:
- pop();
- switch (arg) {
- case Opcodes.T_BOOLEAN:
- push(ARRAY_OF | BOOLEAN);
- break;
- case Opcodes.T_CHAR:
- push(ARRAY_OF | CHAR);
- break;
- case Opcodes.T_BYTE:
- push(ARRAY_OF | BYTE);
- break;
- case Opcodes.T_SHORT:
- push(ARRAY_OF | SHORT);
- break;
- case Opcodes.T_INT:
- push(ARRAY_OF | INTEGER);
- break;
- case Opcodes.T_FLOAT:
- push(ARRAY_OF | FLOAT);
- break;
- case Opcodes.T_DOUBLE:
- push(ARRAY_OF | DOUBLE);
- break;
- // case Opcodes.T_LONG:
- default:
- push(ARRAY_OF | LONG);
- break;
- }
+ case Opcodes.T_SHORT:
+ push(ARRAY_OF | SHORT);
break;
- case Opcodes.ANEWARRAY:
- String s = item.strVal1;
- pop();
- if (s.charAt(0) == '[') {
- push(cw, '[' + s);
- } else {
- push(ARRAY_OF | OBJECT | cw.addType(s));
- }
+ case Opcodes.T_INT:
+ push(ARRAY_OF | INTEGER);
break;
- case Opcodes.CHECKCAST:
- s = item.strVal1;
- pop();
- if (s.charAt(0) == '[') {
- push(cw, s);
- } else {
- push(OBJECT | cw.addType(s));
- }
+ case Opcodes.T_FLOAT:
+ push(ARRAY_OF | FLOAT);
break;
- // case Opcodes.MULTIANEWARRAY:
+ case Opcodes.T_DOUBLE:
+ push(ARRAY_OF | DOUBLE);
+ break;
+ // case Opcodes.T_LONG:
default:
- pop(arg);
- push(cw, item.strVal1);
+ push(ARRAY_OF | LONG);
break;
+ }
+ break;
+ case Opcodes.ANEWARRAY:
+ String s = item.strVal1;
+ pop();
+ if (s.charAt(0) == '[') {
+ push(cw, '[' + s);
+ } else {
+ push(ARRAY_OF | OBJECT | cw.addType(s));
+ }
+ break;
+ case Opcodes.CHECKCAST:
+ s = item.strVal1;
+ pop();
+ if (s.charAt(0) == '[') {
+ push(cw, s);
+ } else {
+ push(OBJECT | cw.addType(s));
+ }
+ break;
+ // case Opcodes.MULTIANEWARRAY:
+ default:
+ pop(arg);
+ push(cw, item.strVal1);
+ break;
}
}
@@ -1260,10 +1273,13 @@ final class Frame {
* frames of this basic block. Returns <tt>true</tt> if the input frame of
* the given label has been changed by this operation.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param frame the basic block whose input frame must be updated.
- * @param edge the kind of the {@link Edge} between this label and 'label'.
- * See {@link Edge#info}.
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param frame
+ * the basic block whose input frame must be updated.
+ * @param edge
+ * the kind of the {@link Edge} between this label and 'label'.
+ * See {@link Edge#info}.
* @return <tt>true</tt> if the input frame of the given label has been
* changed by this operation.
*/
@@ -1294,7 +1310,8 @@ final class Frame {
} else {
t = dim + inputStack[nStack - (s & VALUE)];
}
- if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
+ if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+ && (t == LONG || t == DOUBLE)) {
t = TOP;
}
}
@@ -1346,7 +1363,8 @@ final class Frame {
} else {
t = dim + inputStack[nStack - (s & VALUE)];
}
- if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
+ if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+ && (t == LONG || t == DOUBLE)) {
t = TOP;
}
}
@@ -1363,19 +1381,19 @@ final class Frame {
* type. Returns <tt>true</tt> if the type array has been modified by this
* operation.
*
- * @param cw the ClassWriter to which this label belongs.
- * @param t the type with which the type array element must be merged.
- * @param types an array of types.
- * @param index the index of the type that must be merged in 'types'.
+ * @param cw
+ * the ClassWriter to which this label belongs.
+ * @param t
+ * the type with which the type array element must be merged.
+ * @param types
+ * an array of types.
+ * @param index
+ * the index of the type that must be merged in 'types'.
* @return <tt>true</tt> if the type array has been modified by this
* operation.
*/
- private static boolean merge(
- final ClassWriter cw,
- int t,
- final int[] types,
- final int index)
- {
+ private static boolean merge(final ClassWriter cw, int t,
+ final int[] types, final int index) {
int u = types[index];
if (u == t) {
// if the types are equal, merge(u,t)=u, so there is no change
diff --git a/src/asm/scala/tools/asm/Handle.java b/src/asm/scala/tools/asm/Handle.java
index be8f334192..5dd06a54b9 100644
--- a/src/asm/scala/tools/asm/Handle.java
+++ b/src/asm/scala/tools/asm/Handle.java
@@ -66,18 +66,23 @@ public final class Handle {
/**
* Constructs a new field or method handle.
*
- * @param tag the kind of field or method designated by this Handle. Must be
- * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
- * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
- * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
- * {@link Opcodes#H_INVOKESPECIAL},
- * {@link Opcodes#H_NEWINVOKESPECIAL} or
- * {@link Opcodes#H_INVOKEINTERFACE}.
- * @param owner the internal name of the field or method designed by this
- * handle.
- * @param name the name of the field or method designated by this handle.
- * @param desc the descriptor of the field or method designated by this
- * handle.
+ * @param tag
+ * the kind of field or method designated by this Handle. Must be
+ * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+ * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+ * {@link Opcodes#H_INVOKEVIRTUAL},
+ * {@link Opcodes#H_INVOKESTATIC},
+ * {@link Opcodes#H_INVOKESPECIAL},
+ * {@link Opcodes#H_NEWINVOKESPECIAL} or
+ * {@link Opcodes#H_INVOKEINTERFACE}.
+ * @param owner
+ * the internal name of the field or method designed by this
+ * handle.
+ * @param name
+ * the name of the field or method designated by this handle.
+ * @param desc
+ * the descriptor of the field or method designated by this
+ * handle.
*/
public Handle(int tag, String owner, String name, String desc) {
this.tag = tag;
@@ -101,11 +106,9 @@ public final class Handle {
}
/**
- * Returns the internal name of the field or method designed by this
- * handle.
+ * Returns the internal name of the field or method designed by this handle.
*
- * @return the internal name of the field or method designed by this
- * handle.
+ * @return the internal name of the field or method designed by this handle.
*/
public String getOwner() {
return owner;
@@ -138,8 +141,8 @@ public final class Handle {
return false;
}
Handle h = (Handle) obj;
- return tag == h.tag && owner.equals(h.owner)
- && name.equals(h.name) && desc.equals(h.desc);
+ return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
+ && desc.equals(h.desc);
}
@Override
@@ -149,8 +152,13 @@ public final class Handle {
/**
* Returns the textual representation of this handle. The textual
- * representation is: <pre>owner '.' name desc ' ' '(' tag ')'</pre>. As
- * this format is unambiguous, it can be parsed if necessary.
+ * representation is:
+ *
+ * <pre>
+ * owner '.' name desc ' ' '(' tag ')'
+ * </pre>
+ *
+ * . As this format is unambiguous, it can be parsed if necessary.
*/
@Override
public String toString() {
diff --git a/src/asm/scala/tools/asm/Handler.java b/src/asm/scala/tools/asm/Handler.java
index 9e92bb98be..a06cb8152a 100644
--- a/src/asm/scala/tools/asm/Handler.java
+++ b/src/asm/scala/tools/asm/Handler.java
@@ -72,9 +72,12 @@ class Handler {
* Removes the range between start and end from the given exception
* handlers.
*
- * @param h an exception handler list.
- * @param start the start of the range to be removed.
- * @param end the end of the range to be removed. Maybe null.
+ * @param h
+ * an exception handler list.
+ * @param start
+ * the start of the range to be removed.
+ * @param end
+ * the end of the range to be removed. Maybe null.
* @return the exception handler list with the start-end range removed.
*/
static Handler remove(Handler h, Label start, Label end) {
diff --git a/src/asm/scala/tools/asm/Item.java b/src/asm/scala/tools/asm/Item.java
index 021a0b11d3..94195a1082 100644
--- a/src/asm/scala/tools/asm/Item.java
+++ b/src/asm/scala/tools/asm/Item.java
@@ -53,8 +53,8 @@ final class Item {
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
- * MethodHandle constant 9 variations are stored using a range
- * of 9 values from {@link ClassWriter#HANDLE_BASE} + 1 to
+ * MethodHandle constant 9 variations are stored using a range of 9 values
+ * from {@link ClassWriter#HANDLE_BASE} + 1 to
* {@link ClassWriter#HANDLE_BASE} + 9.
*
* Special Item types are used for Items that are stored in the ClassWriter
@@ -115,7 +115,8 @@ final class Item {
* Constructs an uninitialized {@link Item} for constant pool element at
* given position.
*
- * @param index index of the item to be constructed.
+ * @param index
+ * index of the item to be constructed.
*/
Item(final int index) {
this.index = index;
@@ -124,8 +125,10 @@ final class Item {
/**
* Constructs a copy of the given item.
*
- * @param index index of the item to be constructed.
- * @param i the item that must be copied into the item to be constructed.
+ * @param index
+ * index of the item to be constructed.
+ * @param i
+ * the item that must be copied into the item to be constructed.
*/
Item(final int index, final Item i) {
this.index = index;
@@ -141,7 +144,8 @@ final class Item {
/**
* Sets this item to an integer item.
*
- * @param intVal the value of this item.
+ * @param intVal
+ * the value of this item.
*/
void set(final int intVal) {
this.type = ClassWriter.INT;
@@ -152,7 +156,8 @@ final class Item {
/**
* Sets this item to a long item.
*
- * @param longVal the value of this item.
+ * @param longVal
+ * the value of this item.
*/
void set(final long longVal) {
this.type = ClassWriter.LONG;
@@ -163,7 +168,8 @@ final class Item {
/**
* Sets this item to a float item.
*
- * @param floatVal the value of this item.
+ * @param floatVal
+ * the value of this item.
*/
void set(final float floatVal) {
this.type = ClassWriter.FLOAT;
@@ -174,7 +180,8 @@ final class Item {
/**
* Sets this item to a double item.
*
- * @param doubleVal the value of this item.
+ * @param doubleVal
+ * the value of this item.
*/
void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE;
@@ -185,49 +192,53 @@ final class Item {
/**
* Sets this item to an item that do not hold a primitive value.
*
- * @param type the type of this item.
- * @param strVal1 first part of the value of this item.
- * @param strVal2 second part of the value of this item.
- * @param strVal3 third part of the value of this item.
+ * @param type
+ * the type of this item.
+ * @param strVal1
+ * first part of the value of this item.
+ * @param strVal2
+ * second part of the value of this item.
+ * @param strVal3
+ * third part of the value of this item.
*/
- void set(
- final int type,
- final String strVal1,
- final String strVal2,
- final String strVal3)
- {
+ void set(final int type, final String strVal1, final String strVal2,
+ final String strVal3) {
this.type = type;
this.strVal1 = strVal1;
this.strVal2 = strVal2;
this.strVal3 = strVal3;
switch (type) {
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.MTYPE:
- case ClassWriter.TYPE_NORMAL:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
- return;
- case ClassWriter.NAME_TYPE:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
- * strVal2.hashCode());
- return;
- // ClassWriter.FIELD:
- // ClassWriter.METH:
- // ClassWriter.IMETH:
- // ClassWriter.HANDLE_BASE + 1..9
- default:
- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
- * strVal2.hashCode() * strVal3.hashCode());
+ case ClassWriter.UTF8:
+ case ClassWriter.STR:
+ case ClassWriter.CLASS:
+ case ClassWriter.MTYPE:
+ case ClassWriter.TYPE_NORMAL:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+ return;
+ case ClassWriter.NAME_TYPE: {
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode());
+ return;
+ }
+ // ClassWriter.FIELD:
+ // ClassWriter.METH:
+ // ClassWriter.IMETH:
+ // ClassWriter.HANDLE_BASE + 1..9
+ default:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode() * strVal3.hashCode());
}
}
/**
* Sets the item to an InvokeDynamic item.
*
- * @param name invokedynamic's name.
- * @param desc invokedynamic's desc.
- * @param bsmIndex zero based index into the class attribute BootrapMethods.
+ * @param name
+ * invokedynamic's name.
+ * @param desc
+ * invokedynamic's desc.
+ * @param bsmIndex
+ * zero based index into the class attribute BootrapMethods.
*/
void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY;
@@ -241,10 +252,12 @@ final class Item {
/**
* Sets the item to a BootstrapMethod item.
*
- * @param position position in byte in the class attribute BootrapMethods.
- * @param hashCode hashcode of the item. This hashcode is processed from
- * the hashcode of the bootstrap method and the hashcode of
- * all bootstrap arguments.
+ * @param position
+ * position in byte in the class attribute BootrapMethods.
+ * @param hashCode
+ * hashcode of the item. This hashcode is processed from the
+ * hashcode of the bootstrap method and the hashcode of all
+ * bootstrap arguments.
*/
void set(int position, int hashCode) {
this.type = ClassWriter.BSM;
@@ -256,41 +269,42 @@ final class Item {
* Indicates if the given item is equal to this one. <i>This method assumes
* that the two items have the same {@link #type}</i>.
*
- * @param i the item to be compared to this one. Both items must have the
- * same {@link #type}.
+ * @param i
+ * the item to be compared to this one. Both items must have the
+ * same {@link #type}.
* @return <tt>true</tt> if the given item if equal to this one,
* <tt>false</tt> otherwise.
*/
boolean isEqualTo(final Item i) {
switch (type) {
- case ClassWriter.UTF8:
- case ClassWriter.STR:
- case ClassWriter.CLASS:
- case ClassWriter.MTYPE:
- case ClassWriter.TYPE_NORMAL:
- return i.strVal1.equals(strVal1);
- case ClassWriter.TYPE_MERGED:
- case ClassWriter.LONG:
- case ClassWriter.DOUBLE:
- return i.longVal == longVal;
- case ClassWriter.INT:
- case ClassWriter.FLOAT:
- return i.intVal == intVal;
- case ClassWriter.TYPE_UNINIT:
- return i.intVal == intVal && i.strVal1.equals(strVal1);
- case ClassWriter.NAME_TYPE:
- return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
- case ClassWriter.INDY:
- return i.longVal == longVal && i.strVal1.equals(strVal1)
- && i.strVal2.equals(strVal2);
-
- // case ClassWriter.FIELD:
- // case ClassWriter.METH:
- // case ClassWriter.IMETH:
- // case ClassWriter.HANDLE_BASE + 1..9
- default:
- return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
- && i.strVal3.equals(strVal3);
+ case ClassWriter.UTF8:
+ case ClassWriter.STR:
+ case ClassWriter.CLASS:
+ case ClassWriter.MTYPE:
+ case ClassWriter.TYPE_NORMAL:
+ return i.strVal1.equals(strVal1);
+ case ClassWriter.TYPE_MERGED:
+ case ClassWriter.LONG:
+ case ClassWriter.DOUBLE:
+ return i.longVal == longVal;
+ case ClassWriter.INT:
+ case ClassWriter.FLOAT:
+ return i.intVal == intVal;
+ case ClassWriter.TYPE_UNINIT:
+ return i.intVal == intVal && i.strVal1.equals(strVal1);
+ case ClassWriter.NAME_TYPE:
+ return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
+ case ClassWriter.INDY: {
+ return i.longVal == longVal && i.strVal1.equals(strVal1)
+ && i.strVal2.equals(strVal2);
+ }
+ // case ClassWriter.FIELD:
+ // case ClassWriter.METH:
+ // case ClassWriter.IMETH:
+ // case ClassWriter.HANDLE_BASE + 1..9
+ default:
+ return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
+ && i.strVal3.equals(strVal3);
}
}
diff --git a/src/asm/scala/tools/asm/Label.java b/src/asm/scala/tools/asm/Label.java
index 712c7f251f..5d5529ce74 100644
--- a/src/asm/scala/tools/asm/Label.java
+++ b/src/asm/scala/tools/asm/Label.java
@@ -32,9 +32,9 @@ package scala.tools.asm;
/**
* A label represents a position in the bytecode of a method. Labels are used
* for jump, goto, and switch instructions, and for try catch blocks. A label
- * designates the <i>instruction</i> that is just after. Note however that
- * there can be other elements between a label and the instruction it
- * designates (such as other labels, stack map frames, line numbers, etc.).
+ * designates the <i>instruction</i> that is just after. Note however that there
+ * can be other elements between a label and the instruction it designates (such
+ * as other labels, stack map frames, line numbers, etc.).
*
* @author Eric Bruneton
*/
@@ -110,8 +110,8 @@ public class Label {
/**
* Field used to associate user information to a label. Warning: this field
* is used by the ASM tree package. In order to use it with the ASM tree
- * package you must override the {@link
- * org.objectweb.asm.tree.MethodNode#getLabelNode} method.
+ * package you must override the
+ * {@link scala.tools.asm.tree.MethodNode#getLabelNode} method.
*/
public Object info;
@@ -154,7 +154,7 @@ public class Label {
* indicates if this reference uses 2 or 4 bytes, and its absolute value
* gives the position of the bytecode instruction. This array is also used
* as a bitset to store the subroutines to which a basic block belongs. This
- * information is needed in {@linked MethodWriter#visitMaxs}, after all
+ * information is needed in {@linked MethodWriter#visitMaxs}, after all
* forward references have been resolved. Hence the same array can be used
* for both purposes without problems.
*/
@@ -177,11 +177,11 @@ public class Label {
* state of the local variables and the operand stack at the end of each
* basic block, called the "output frame", <i>relatively</i> to the frame
* state at the beginning of the basic block, which is called the "input
- * frame", and which is <i>unknown</i> during this step. The second step,
- * in {@link MethodWriter#visitMaxs}, is a fix point algorithm that
- * computes information about the input frame of each basic block, from the
- * input state of the first basic block (known from the method signature),
- * and by the using the previously computed relative output frames.
+ * frame", and which is <i>unknown</i> during this step. The second step, in
+ * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
+ * information about the input frame of each basic block, from the input
+ * state of the first basic block (known from the method signature), and by
+ * the using the previously computed relative output frames.
*
* The algorithm used to compute the maximum stack size only computes the
* relative output and absolute input stack heights, while the algorithm
@@ -266,11 +266,13 @@ public class Label {
* generators or adapters.</i>
*
* @return the offset corresponding to this label.
- * @throws IllegalStateException if this label is not resolved yet.
+ * @throws IllegalStateException
+ * if this label is not resolved yet.
*/
public int getOffset() {
if ((status & RESOLVED) == 0) {
- throw new IllegalStateException("Label offset position has not been resolved yet");
+ throw new IllegalStateException(
+ "Label offset position has not been resolved yet");
}
return position;
}
@@ -281,21 +283,21 @@ public class Label {
* directly. Otherwise, a null offset is written and a new forward reference
* is declared for this label.
*
- * @param owner the code writer that calls this method.
- * @param out the bytecode of the method.
- * @param source the position of first byte of the bytecode instruction that
- * contains this label.
- * @param wideOffset <tt>true</tt> if the reference must be stored in 4
- * bytes, or <tt>false</tt> if it must be stored with 2 bytes.
- * @throws IllegalArgumentException if this label has not been created by
- * the given code writer.
- */
- void put(
- final MethodWriter owner,
- final ByteVector out,
- final int source,
- final boolean wideOffset)
- {
+ * @param owner
+ * the code writer that calls this method.
+ * @param out
+ * the bytecode of the method.
+ * @param source
+ * the position of first byte of the bytecode instruction that
+ * contains this label.
+ * @param wideOffset
+ * <tt>true</tt> if the reference must be stored in 4 bytes, or
+ * <tt>false</tt> if it must be stored with 2 bytes.
+ * @throws IllegalArgumentException
+ * if this label has not been created by the given code writer.
+ */
+ void put(final MethodWriter owner, final ByteVector out, final int source,
+ final boolean wideOffset) {
if ((status & RESOLVED) == 0) {
if (wideOffset) {
addReference(-1 - source, out.length);
@@ -319,25 +321,21 @@ public class Label {
* yet. For backward references, the offset of the reference can be, and
* must be, computed and stored directly.
*
- * @param sourcePosition the position of the referencing instruction. This
- * position will be used to compute the offset of this forward
- * reference.
- * @param referencePosition the position where the offset for this forward
- * reference must be stored.
- */
- private void addReference(
- final int sourcePosition,
- final int referencePosition)
- {
+ * @param sourcePosition
+ * the position of the referencing instruction. This position
+ * will be used to compute the offset of this forward reference.
+ * @param referencePosition
+ * the position where the offset for this forward reference must
+ * be stored.
+ */
+ private void addReference(final int sourcePosition,
+ final int referencePosition) {
if (srcAndRefPositions == null) {
srcAndRefPositions = new int[6];
}
if (referenceCount >= srcAndRefPositions.length) {
int[] a = new int[srcAndRefPositions.length + 6];
- System.arraycopy(srcAndRefPositions,
- 0,
- a,
- 0,
+ System.arraycopy(srcAndRefPositions, 0, a, 0,
srcAndRefPositions.length);
srcAndRefPositions = a;
}
@@ -351,9 +349,12 @@ public class Label {
* position becomes known. This method fills in the blanks that where left
* in the bytecode by each forward reference previously added to this label.
*
- * @param owner the code writer that calls this method.
- * @param position the position of this label in the bytecode.
- * @param data the bytecode of the method.
+ * @param owner
+ * the code writer that calls this method.
+ * @param position
+ * the position of this label in the bytecode.
+ * @param data
+ * the bytecode of the method.
* @return <tt>true</tt> if a blank that was left for this label was to
* small to store the offset. In such a case the corresponding jump
* instruction is replaced with a pseudo instruction (using unused
@@ -361,14 +362,12 @@ public class Label {
* instructions will need to be replaced with true instructions with
* wider offsets (4 bytes instead of 2). This is done in
* {@link MethodWriter#resizeInstructions}.
- * @throws IllegalArgumentException if this label has already been resolved,
- * or if it has not been created by the given code writer.
- */
- boolean resolve(
- final MethodWriter owner,
- final int position,
- final byte[] data)
- {
+ * @throws IllegalArgumentException
+ * if this label has already been resolved, or if it has not
+ * been created by the given code writer.
+ */
+ boolean resolve(final MethodWriter owner, final int position,
+ final byte[] data) {
boolean needUpdate = false;
this.status |= RESOLVED;
this.position = position;
@@ -431,7 +430,8 @@ public class Label {
/**
* Returns true is this basic block belongs to the given subroutine.
*
- * @param id a subroutine id.
+ * @param id
+ * a subroutine id.
* @return true is this basic block belongs to the given subroutine.
*/
boolean inSubroutine(final long id) {
@@ -445,7 +445,8 @@ public class Label {
* Returns true if this basic block and the given one belong to a common
* subroutine.
*
- * @param block another basic block.
+ * @param block
+ * another basic block.
* @return true if this basic block and the given one belong to a common
* subroutine.
*/
@@ -464,8 +465,10 @@ public class Label {
/**
* Marks this basic block as belonging to the given subroutine.
*
- * @param id a subroutine id.
- * @param nbSubroutines the total number of subroutines in the method.
+ * @param id
+ * a subroutine id.
+ * @param nbSubroutines
+ * the total number of subroutines in the method.
*/
void addToSubroutine(final long id, final int nbSubroutines) {
if ((status & VISITED) == 0) {
@@ -481,14 +484,16 @@ public class Label {
* flow graph to find all the blocks that are reachable from the current
* block WITHOUT following any JSR target.
*
- * @param JSR a JSR block that jumps to this subroutine. If this JSR is not
- * null it is added to the successor of the RET blocks found in the
- * subroutine.
- * @param id the id of this subroutine.
- * @param nbSubroutines the total number of subroutines in the method.
- */
- void visitSubroutine(final Label JSR, final long id, final int nbSubroutines)
- {
+ * @param JSR
+ * a JSR block that jumps to this subroutine. If this JSR is not
+ * null it is added to the successor of the RET blocks found in
+ * the subroutine.
+ * @param id
+ * the id of this subroutine.
+ * @param nbSubroutines
+ * the total number of subroutines in the method.
+ */
+ void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
// user managed stack of labels, to avoid using a recursive method
// (recursivity can lead to stack overflow with very large methods)
Label stack = this;
diff --git a/src/asm/scala/tools/asm/MethodVisitor.java b/src/asm/scala/tools/asm/MethodVisitor.java
index a8a859a6a9..e43ca97823 100644
--- a/src/asm/scala/tools/asm/MethodVisitor.java
+++ b/src/asm/scala/tools/asm/MethodVisitor.java
@@ -30,19 +30,19 @@
package scala.tools.asm;
/**
- * A visitor to visit a Java method. The methods of this class must be
- * called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
+ * A visitor to visit a Java method. The methods of this class must be called in
+ * the following order: [ <tt>visitAnnotationDefault</tt> ] (
* <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
- * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
- * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ]
- * <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
- * and <tt>visitLabel</tt> methods must be called in the sequential order of
- * the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
- * must be called <i>before</i> the labels passed as arguments have been
- * visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
- * methods must be called <i>after</i> the labels passed as arguments have been
- * visited.
+ * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> |
+ * <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> |
+ * <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
+ * addition, the <tt>visit</tt><i>X</i>Insn</tt> and <tt>visitLabel</tt> methods
+ * must be called in the sequential order of the bytecode instructions of the
+ * visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
+ * labels passed as arguments have been visited, and the
+ * <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> methods must be
+ * called <i>after</i> the labels passed as arguments have been visited.
*
* @author Eric Bruneton
*/
@@ -63,8 +63,9 @@ public abstract class MethodVisitor {
/**
* Constructs a new {@link MethodVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public MethodVisitor(final int api) {
this(api, null);
@@ -73,15 +74,17 @@ public abstract class MethodVisitor {
/**
* Constructs a new {@link MethodVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param mv the method visitor to which this visitor must delegate method
- * calls. May be null.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param mv
+ * the method visitor to which this visitor must delegate method
+ * calls. May be null.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
- /*if (api != Opcodes.ASM4) {
+ if (api != Opcodes.ASM4) {
throw new IllegalArgumentException();
- }*/
+ }
this.api = api;
this.mv = mv;
}
@@ -94,8 +97,8 @@ public abstract class MethodVisitor {
* Visits the default value of this annotation interface method.
*
* @return a visitor to the visit the actual default value of this
- * annotation interface method, or <tt>null</tt> if this visitor
- * is not interested in visiting this default value. The 'name'
+ * annotation interface method, or <tt>null</tt> if this visitor is
+ * not interested in visiting this default value. The 'name'
* parameters passed to the methods of this annotation visitor are
* ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
@@ -110,8 +113,10 @@ public abstract class MethodVisitor {
/**
* Visits an annotation of this method.
*
- * @param desc the class descriptor of the annotation class.
- * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
@@ -125,17 +130,17 @@ public abstract class MethodVisitor {
/**
* Visits an annotation of a parameter this method.
*
- * @param parameter the parameter index.
- * @param desc the class descriptor of the annotation class.
- * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @param parameter
+ * the parameter index.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/
- public AnnotationVisitor visitParameterAnnotation(
- int parameter,
- String desc,
- boolean visible)
- {
+ public AnnotationVisitor visitParameterAnnotation(int parameter,
+ String desc, boolean visible) {
if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible);
}
@@ -145,7 +150,8 @@ public abstract class MethodVisitor {
/**
* Visits a non standard attribute of this method.
*
- * @param attr an attribute.
+ * @param attr
+ * an attribute.
*/
public void visitAttribute(Attribute attr) {
if (mv != null) {
@@ -169,57 +175,74 @@ public abstract class MethodVisitor {
* such as GOTO or THROW, that is the target of a jump instruction, or that
* starts an exception handler block. The visited types must describe the
* values of the local variables and of the operand stack elements <i>just
- * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
- * for classes whose version is greater than or equal to
- * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
- * "deltas" from the state of the previous frame (very first frame is
- * implicitly defined by the method's parameters and access flags): <ul>
+ * before</i> <b>i</b> is executed.<br>
+ * <br>
+ * (*) this is mandatory only for classes whose version is greater than or
+ * equal to {@link Opcodes#V1_6 V1_6}. <br>
+ * <br>
+ * The frames of a method must be given either in expanded form, or in
+ * compressed form (all frames must use the same format, i.e. you must not
+ * mix expanded and compressed frames within a single method):
+ * <ul>
+ * <li>In expanded form, all frames must have the F_NEW type.</li>
+ * <li>In compressed form, frames are basically "deltas" from the state of
+ * the previous frame:
+ * <ul>
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same
- * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
- * representing frame with exactly the same locals as the previous frame and
- * with single value on the stack (<code>nStack</code> is 1 and
- * <code>stack[0]</code> contains value for the type of the stack item).</li>
+ * locals as the previous frame and with the empty stack.</li>
+ * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
+ * locals as the previous frame and with single value on the stack (
+ * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
+ * type of the stack item).</li>
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are
* the same as the locals in the previous frame, except that additional
* locals are defined (<code>nLocal</code> is 1, 2 or 3 and
* <code>local</code> elements contains values representing added types).</li>
- * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
- * the same as the locals in the previous frame, except that the last 1-3
- * locals are absent and with the empty stack (<code>nLocals</code> is 1,
- * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
- * data.</li> </li> </ul>
+ * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
+ * same as the locals in the previous frame, except that the last 1-3 locals
+ * are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
+ * <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
+ * </ul>
+ * </ul> <br>
+ * In both cases the first frame, corresponding to the method's parameters
+ * and access flags, is implicit and must not be visited. Also, it is
+ * illegal to visit two or more frames for the same code location (i.e., at
+ * least one instruction must be visited between two calls to visitFrame).
*
- * @param type the type of this stack map frame. Must be
- * {@link Opcodes#F_NEW} for expanded frames, or
- * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
- * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
- * frames.
- * @param nLocal the number of local variables in the visited frame.
- * @param local the local variable types in this frame. This array must not
- * be modified. Primitive types are represented by
- * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
- * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
- * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
- * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
- * represented by a single element). Reference types are represented
- * by String objects (representing internal names), and uninitialized
- * types by Label objects (this label designates the NEW instruction
- * that created this uninitialized value).
- * @param nStack the number of operand stack elements in the visited frame.
- * @param stack the operand stack types in this frame. This array must not
- * be modified. Its content has the same format as the "local" array.
- * @throws IllegalStateException if a frame is visited just after another
- * one, without any instruction between the two (unless this frame
- * is a Opcodes#F_SAME frame, in which case it is silently ignored).
+ * @param type
+ * the type of this stack map frame. Must be
+ * {@link Opcodes#F_NEW} for expanded frames, or
+ * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+ * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+ * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
+ * compressed frames.
+ * @param nLocal
+ * the number of local variables in the visited frame.
+ * @param local
+ * the local variable types in this frame. This array must not be
+ * modified. Primitive types are represented by
+ * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+ * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+ * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+ * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+ * represented by a single element). Reference types are
+ * represented by String objects (representing internal names),
+ * and uninitialized types by Label objects (this label
+ * designates the NEW instruction that created this uninitialized
+ * value).
+ * @param nStack
+ * the number of operand stack elements in the visited frame.
+ * @param stack
+ * the operand stack types in this frame. This array must not be
+ * modified. Its content has the same format as the "local"
+ * array.
+ * @throws IllegalStateException
+ * if a frame is visited just after another one, without any
+ * instruction between the two (unless this frame is a
+ * Opcodes#F_SAME frame, in which case it is silently ignored).
*/
- public void visitFrame(
- int type,
- int nLocal,
- Object[] local,
- int nStack,
- Object[] stack)
- {
+ public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+ Object[] stack) {
if (mv != null) {
mv.visitFrame(type, nLocal, local, nStack, stack);
}
@@ -232,20 +255,22 @@ public abstract class MethodVisitor {
/**
* Visits a zero operand instruction.
*
- * @param opcode the opcode of the instruction to be visited. This opcode is
- * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
- * ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
- * FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
- * DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
- * DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
- * DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
- * DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
- * FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
- * LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
- * I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
- * I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
- * FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
- * MONITORENTER, or MONITOREXIT.
+ * @param opcode
+ * the opcode of the instruction to be visited. This opcode is
+ * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+ * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+ * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+ * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+ * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+ * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+ * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+ * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+ * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+ * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+ * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+ * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+ * or MONITOREXIT.
*/
public void visitInsn(int opcode) {
if (mv != null) {
@@ -256,17 +281,20 @@ public abstract class MethodVisitor {
/**
* Visits an instruction with a single int operand.
*
- * @param opcode the opcode of the instruction to be visited. This opcode is
- * either BIPUSH, SIPUSH or NEWARRAY.
- * @param operand the operand of the instruction to be visited.<br> When
- * opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
- * and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
- * should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
- * opcode is NEWARRAY, operand value should be one of
- * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
- * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
- * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
- * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+ * @param opcode
+ * the opcode of the instruction to be visited. This opcode is
+ * either BIPUSH, SIPUSH or NEWARRAY.
+ * @param operand
+ * the operand of the instruction to be visited.<br>
+ * When opcode is BIPUSH, operand value should be between
+ * Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
+ * When opcode is SIPUSH, operand value should be between
+ * Short.MIN_VALUE and Short.MAX_VALUE.<br>
+ * When opcode is NEWARRAY, operand value should be one of
+ * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+ * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+ * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+ * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/
public void visitIntInsn(int opcode, int operand) {
if (mv != null) {
@@ -278,11 +306,13 @@ public abstract class MethodVisitor {
* Visits a local variable instruction. A local variable instruction is an
* instruction that loads or stores the value of a local variable.
*
- * @param opcode the opcode of the local variable instruction to be visited.
- * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
- * LSTORE, FSTORE, DSTORE, ASTORE or RET.
- * @param var the operand of the instruction to be visited. This operand is
- * the index of a local variable.
+ * @param opcode
+ * the opcode of the local variable instruction to be visited.
+ * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
+ * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param var
+ * the operand of the instruction to be visited. This operand is
+ * the index of a local variable.
*/
public void visitVarInsn(int opcode, int var) {
if (mv != null) {
@@ -294,11 +324,13 @@ public abstract class MethodVisitor {
* Visits a type instruction. A type instruction is an instruction that
* takes the internal name of a class as parameter.
*
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
- * @param type the operand of the instruction to be visited. This operand
- * must be the internal name of an object or array class (see {@link
- * Type#getInternalName() getInternalName}).
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param type
+ * the operand of the instruction to be visited. This operand
+ * must be the internal name of an object or array class (see
+ * {@link Type#getInternalName() getInternalName}).
*/
public void visitTypeInsn(int opcode, String type) {
if (mv != null) {
@@ -310,14 +342,19 @@ public abstract class MethodVisitor {
* Visits a field instruction. A field instruction is an instruction that
* loads or stores the value of a field of an object.
*
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
- * @param owner the internal name of the field's owner class (see {@link
- * Type#getInternalName() getInternalName}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link Type Type}).
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner
+ * the internal name of the field's owner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link Type Type}).
*/
- public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+ public void visitFieldInsn(int opcode, String owner, String name,
+ String desc) {
if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc);
}
@@ -327,15 +364,20 @@ public abstract class MethodVisitor {
* Visits a method instruction. A method instruction is an instruction that
* invokes a method.
*
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC
- * or INVOKEINTERFACE.
- * @param owner the internal name of the method's owner class (see {@link
- * Type#getInternalName() getInternalName}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+ * INVOKEINTERFACE.
+ * @param owner
+ * the internal name of the method's owner class (see
+ * {@link Type#getInternalName() getInternalName}).
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
*/
- public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ public void visitMethodInsn(int opcode, String owner, String name,
+ String desc) {
if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc);
}
@@ -344,16 +386,21 @@ public abstract class MethodVisitor {
/**
* Visits an invokedynamic instruction.
*
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- * @param bsm the bootstrap method.
- * @param bsmArgs the bootstrap method constant arguments. Each argument
- * must be an {@link Integer}, {@link Float}, {@link Long},
- * {@link Double}, {@link String}, {@link Type} or {@link Handle}
- * value. This method is allowed to modify the content of the array
- * so a caller should expect that this array may change.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the bootstrap method constant arguments. Each argument must be
+ * an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double}, {@link String}, {@link Type} or {@link Handle}
+ * value. This method is allowed to modify the content of the
+ * array so a caller should expect that this array may change.
*/
- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
}
@@ -363,13 +410,15 @@ public abstract class MethodVisitor {
* Visits a jump instruction. A jump instruction is an instruction that may
* jump to another instruction.
*
- * @param opcode the opcode of the type instruction to be visited. This
- * opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
- * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
- * @param label the operand of the instruction to be visited. This operand
- * is a label that designates the instruction to which the jump
- * instruction may jump.
+ * @param opcode
+ * the opcode of the type instruction to be visited. This opcode
+ * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+ * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+ * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label
+ * the operand of the instruction to be visited. This operand is
+ * a label that designates the instruction to which the jump
+ * instruction may jump.
*/
public void visitJumpInsn(int opcode, Label label) {
if (mv != null) {
@@ -381,7 +430,8 @@ public abstract class MethodVisitor {
* Visits a label. A label designates the instruction that will be visited
* just after it.
*
- * @param label a {@link Label Label} object.
+ * @param label
+ * a {@link Label Label} object.
*/
public void visitLabel(Label label) {
if (mv != null) {
@@ -398,41 +448,44 @@ public abstract class MethodVisitor {
* future versions of the Java Virtual Machine. To easily detect new
* constant types, implementations of this method should check for
* unexpected constant types, like this:
+ *
* <pre>
* if (cst instanceof Integer) {
- * // ...
+ * // ...
* } else if (cst instanceof Float) {
- * // ...
+ * // ...
* } else if (cst instanceof Long) {
- * // ...
- * } else if (cst instanceof Double) {
- * // ...
- * } else if (cst instanceof String) {
- * // ...
- * } else if (cst instanceof Type) {
- * int sort = ((Type) cst).getSort();
- * if (sort == Type.OBJECT) {
* // ...
- * } else if (sort == Type.ARRAY) {
+ * } else if (cst instanceof Double) {
* // ...
- * } else if (sort == Type.METHOD) {
+ * } else if (cst instanceof String) {
* // ...
- * } else {
- * // throw an exception
- * }
+ * } else if (cst instanceof Type) {
+ * int sort = ((Type) cst).getSort();
+ * if (sort == Type.OBJECT) {
+ * // ...
+ * } else if (sort == Type.ARRAY) {
+ * // ...
+ * } else if (sort == Type.METHOD) {
+ * // ...
+ * } else {
+ * // throw an exception
+ * }
* } else if (cst instanceof Handle) {
- * // ...
+ * // ...
* } else {
- * // throw an exception
- * }</pre>
+ * // throw an exception
+ * }
+ * </pre>
*
- * @param cst the constant to be loaded on the stack. This parameter must be
- * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY
- * sort for <tt>.class</tt> constants, for classes whose version is
- * 49.0, a {@link Type} of METHOD sort or a {@link Handle} for
- * MethodType and MethodHandle constants, for classes whose version
- * is 51.0.
+ * @param cst
+ * the constant to be loaded on the stack. This parameter must be
+ * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
+ * ARRAY sort for <tt>.class</tt> constants, for classes whose
+ * version is 49.0, a {@link Type} of METHOD sort or a
+ * {@link Handle} for MethodType and MethodHandle constants, for
+ * classes whose version is 51.0.
*/
public void visitLdcInsn(Object cst) {
if (mv != null) {
@@ -443,8 +496,10 @@ public abstract class MethodVisitor {
/**
* Visits an IINC instruction.
*
- * @param var index of the local variable to be incremented.
- * @param increment amount to increment the local variable by.
+ * @param var
+ * index of the local variable to be incremented.
+ * @param increment
+ * amount to increment the local variable by.
*/
public void visitIincInsn(int var, int increment) {
if (mv != null) {
@@ -455,13 +510,18 @@ public abstract class MethodVisitor {
/**
* Visits a TABLESWITCH instruction.
*
- * @param min the minimum key value.
- * @param max the maximum key value.
- * @param dflt beginning of the default handler block.
- * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
- * the beginning of the handler block for the <tt>min + i</tt> key.
+ * @param min
+ * the minimum key value.
+ * @param max
+ * the maximum key value.
+ * @param dflt
+ * beginning of the default handler block.
+ * @param labels
+ * beginnings of the handler blocks. <tt>labels[i]</tt> is the
+ * beginning of the handler block for the <tt>min + i</tt> key.
*/
- public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
+ public void visitTableSwitchInsn(int min, int max, Label dflt,
+ Label... labels) {
if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels);
}
@@ -470,10 +530,13 @@ public abstract class MethodVisitor {
/**
* Visits a LOOKUPSWITCH instruction.
*
- * @param dflt beginning of the default handler block.
- * @param keys the values of the keys.
- * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
- * the beginning of the handler block for the <tt>keys[i]</tt> key.
+ * @param dflt
+ * beginning of the default handler block.
+ * @param keys
+ * the values of the keys.
+ * @param labels
+ * beginnings of the handler blocks. <tt>labels[i]</tt> is the
+ * beginning of the handler block for the <tt>keys[i]</tt> key.
*/
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mv != null) {
@@ -484,8 +547,10 @@ public abstract class MethodVisitor {
/**
* Visits a MULTIANEWARRAY instruction.
*
- * @param desc an array type descriptor (see {@link Type Type}).
- * @param dims number of dimensions of the array to allocate.
+ * @param desc
+ * an array type descriptor (see {@link Type Type}).
+ * @param dims
+ * number of dimensions of the array to allocate.
*/
public void visitMultiANewArrayInsn(String desc, int dims) {
if (mv != null) {
@@ -500,17 +565,22 @@ public abstract class MethodVisitor {
/**
* Visits a try catch block.
*
- * @param start beginning of the exception handler's scope (inclusive).
- * @param end end of the exception handler's scope (exclusive).
- * @param handler beginning of the exception handler's code.
- * @param type internal name of the type of exceptions handled by the
- * handler, or <tt>null</tt> to catch any exceptions (for "finally"
- * blocks).
- * @throws IllegalArgumentException if one of the labels has already been
- * visited by this visitor (by the {@link #visitLabel visitLabel}
- * method).
+ * @param start
+ * beginning of the exception handler's scope (inclusive).
+ * @param end
+ * end of the exception handler's scope (exclusive).
+ * @param handler
+ * beginning of the exception handler's code.
+ * @param type
+ * internal name of the type of exceptions handled by the
+ * handler, or <tt>null</tt> to catch any exceptions (for
+ * "finally" blocks).
+ * @throws IllegalArgumentException
+ * if one of the labels has already been visited by this visitor
+ * (by the {@link #visitLabel visitLabel} method).
*/
- public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+ public void visitTryCatchBlock(Label start, Label end, Label handler,
+ String type) {
if (mv != null) {
mv.visitTryCatchBlock(start, end, handler, type);
}
@@ -519,28 +589,28 @@ public abstract class MethodVisitor {
/**
* Visits a local variable declaration.
*
- * @param name the name of a local variable.
- * @param desc the type descriptor of this local variable.
- * @param signature the type signature of this local variable. May be
- * <tt>null</tt> if the local variable type does not use generic
- * types.
- * @param start the first instruction corresponding to the scope of this
- * local variable (inclusive).
- * @param end the last instruction corresponding to the scope of this local
- * variable (exclusive).
- * @param index the local variable's index.
- * @throws IllegalArgumentException if one of the labels has not already
- * been visited by this visitor (by the
- * {@link #visitLabel visitLabel} method).
+ * @param name
+ * the name of a local variable.
+ * @param desc
+ * the type descriptor of this local variable.
+ * @param signature
+ * the type signature of this local variable. May be
+ * <tt>null</tt> if the local variable type does not use generic
+ * types.
+ * @param start
+ * the first instruction corresponding to the scope of this local
+ * variable (inclusive).
+ * @param end
+ * the last instruction corresponding to the scope of this local
+ * variable (exclusive).
+ * @param index
+ * the local variable's index.
+ * @throws IllegalArgumentException
+ * if one of the labels has not already been visited by this
+ * visitor (by the {@link #visitLabel visitLabel} method).
*/
- public void visitLocalVariable(
- String name,
- String desc,
- String signature,
- Label start,
- Label end,
- int index)
- {
+ public void visitLocalVariable(String name, String desc, String signature,
+ Label start, Label end, int index) {
if (mv != null) {
mv.visitLocalVariable(name, desc, signature, start, end, index);
}
@@ -549,12 +619,14 @@ public abstract class MethodVisitor {
/**
* Visits a line number declaration.
*
- * @param line a line number. This number refers to the source file from
- * which the class was compiled.
- * @param start the first instruction corresponding to this line number.
- * @throws IllegalArgumentException if <tt>start</tt> has not already been
- * visited by this visitor (by the {@link #visitLabel visitLabel}
- * method).
+ * @param line
+ * a line number. This number refers to the source file from
+ * which the class was compiled.
+ * @param start
+ * the first instruction corresponding to this line number.
+ * @throws IllegalArgumentException
+ * if <tt>start</tt> has not already been visited by this
+ * visitor (by the {@link #visitLabel visitLabel} method).
*/
public void visitLineNumber(int line, Label start) {
if (mv != null) {
@@ -566,8 +638,10 @@ public abstract class MethodVisitor {
* Visits the maximum stack size and the maximum number of local variables
* of the method.
*
- * @param maxStack maximum stack size of the method.
- * @param maxLocals maximum number of local variables for the method.
+ * @param maxStack
+ * maximum stack size of the method.
+ * @param maxLocals
+ * maximum number of local variables for the method.
*/
public void visitMaxs(int maxStack, int maxLocals) {
if (mv != null) {
diff --git a/src/asm/scala/tools/asm/MethodWriter.java b/src/asm/scala/tools/asm/MethodWriter.java
index 321bacb6fc..f5fbd1e74f 100644
--- a/src/asm/scala/tools/asm/MethodWriter.java
+++ b/src/asm/scala/tools/asm/MethodWriter.java
@@ -42,7 +42,7 @@ class MethodWriter extends MethodVisitor {
/**
* Pseudo access flag used to denote constructors.
*/
- static final int ACC_CONSTRUCTOR = 262144;
+ static final int ACC_CONSTRUCTOR = 0x80000;
/**
* Frame has exactly the same locals as the previous stack map frame and
@@ -229,7 +229,7 @@ class MethodWriter extends MethodVisitor {
private int maxLocals;
/**
- * Number of local variables in the current stack map frame.
+ * Number of local variables in the current stack map frame.
*/
private int currentLocals;
@@ -257,11 +257,6 @@ class MethodWriter extends MethodVisitor {
private int[] previousFrame;
/**
- * Index of the next element to be added in {@link #frame}.
- */
- private int frameIndex;
-
- /**
* The current stack map frame. The first element contains the offset of the
* instruction to which the frame corresponds, the second element is the
* number of locals and the third one is the number of stack elements. The
@@ -357,7 +352,8 @@ class MethodWriter extends MethodVisitor {
* A list of labels. This list is the list of basic blocks in the method,
* i.e. a list of Label objects linked to each other by their
* {@link Label#successor} field, in the order they are visited by
- * {@link MethodVisitor#visitLabel}, and starting with the first basic block.
+ * {@link MethodVisitor#visitLabel}, and starting with the first basic
+ * block.
*/
private Label labels;
@@ -396,28 +392,30 @@ class MethodWriter extends MethodVisitor {
/**
* Constructs a new {@link MethodWriter}.
*
- * @param cw the class writer in which the method must be added.
- * @param access the method's access flags (see {@link Opcodes}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be <tt>null</tt>.
- * @param exceptions the internal names of the method's exceptions. May be
- * <tt>null</tt>.
- * @param computeMaxs <tt>true</tt> if the maximum stack size and number
- * of local variables must be automatically computed.
- * @param computeFrames <tt>true</tt> if the stack map tables must be
- * recomputed from scratch.
- */
- MethodWriter(
- final ClassWriter cw,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions,
- final boolean computeMaxs,
- final boolean computeFrames)
- {
+ * @param cw
+ * the class writer in which the method must be added.
+ * @param access
+ * the method's access flags (see {@link Opcodes}).
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type}).
+ * @param signature
+ * the method's signature. May be <tt>null</tt>.
+ * @param exceptions
+ * the internal names of the method's exceptions. May be
+ * <tt>null</tt>.
+ * @param computeMaxs
+ * <tt>true</tt> if the maximum stack size and number of local
+ * variables must be automatically computed.
+ * @param computeFrames
+ * <tt>true</tt> if the stack map tables must be recomputed from
+ * scratch.
+ */
+ MethodWriter(final ClassWriter cw, final int access, final String name,
+ final String desc, final String signature,
+ final String[] exceptions, final boolean computeMaxs,
+ final boolean computeFrames) {
super(Opcodes.ASM4);
if (cw.firstMethod == null) {
cw.firstMethod = this;
@@ -427,6 +425,9 @@ class MethodWriter extends MethodVisitor {
cw.lastMethod = this;
this.cw = cw;
this.access = access;
+ if ("<init>".equals(name)) {
+ this.access |= ACC_CONSTRUCTOR;
+ }
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
this.descriptor = desc;
@@ -442,9 +443,6 @@ class MethodWriter extends MethodVisitor {
}
this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
if (computeMaxs || computeFrames) {
- if (computeFrames && "<init>".equals(name)) {
- this.access |= ACC_CONSTRUCTOR;
- }
// updates maxLocals
int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -473,10 +471,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -495,11 +491,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
if (!ClassReader.ANNOTATIONS) {
return null;
}
@@ -545,20 +538,18 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
if (!ClassReader.FRAMES || compute == FRAMES) {
return;
}
if (type == Opcodes.F_NEW) {
+ if (previousFrame == null) {
+ visitImplicitFirstFrame();
+ }
currentLocals = nLocal;
- startFrame(code.length, nLocal, nStack);
+ int frameIndex = startFrame(code.length, nLocal, nStack);
for (int i = 0; i < nLocal; ++i) {
if (local[i] instanceof String) {
frame[frameIndex++] = Frame.OBJECT
@@ -601,48 +592,44 @@ class MethodWriter extends MethodVisitor {
}
switch (type) {
- case Opcodes.F_FULL:
- currentLocals = nLocal;
- stackMap.putByte(FULL_FRAME)
- .putShort(delta)
- .putShort(nLocal);
- for (int i = 0; i < nLocal; ++i) {
- writeFrameType(local[i]);
- }
- stackMap.putShort(nStack);
- for (int i = 0; i < nStack; ++i) {
- writeFrameType(stack[i]);
- }
- break;
- case Opcodes.F_APPEND:
- currentLocals += nLocal;
- stackMap.putByte(SAME_FRAME_EXTENDED + nLocal)
- .putShort(delta);
- for (int i = 0; i < nLocal; ++i) {
- writeFrameType(local[i]);
- }
- break;
- case Opcodes.F_CHOP:
- currentLocals -= nLocal;
- stackMap.putByte(SAME_FRAME_EXTENDED - nLocal)
+ case Opcodes.F_FULL:
+ currentLocals = nLocal;
+ stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal);
+ for (int i = 0; i < nLocal; ++i) {
+ writeFrameType(local[i]);
+ }
+ stackMap.putShort(nStack);
+ for (int i = 0; i < nStack; ++i) {
+ writeFrameType(stack[i]);
+ }
+ break;
+ case Opcodes.F_APPEND:
+ currentLocals += nLocal;
+ stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta);
+ for (int i = 0; i < nLocal; ++i) {
+ writeFrameType(local[i]);
+ }
+ break;
+ case Opcodes.F_CHOP:
+ currentLocals -= nLocal;
+ stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta);
+ break;
+ case Opcodes.F_SAME:
+ if (delta < 64) {
+ stackMap.putByte(delta);
+ } else {
+ stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+ }
+ break;
+ case Opcodes.F_SAME1:
+ if (delta < 64) {
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+ } else {
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
.putShort(delta);
- break;
- case Opcodes.F_SAME:
- if (delta < 64) {
- stackMap.putByte(delta);
- } else {
- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
- }
- break;
- case Opcodes.F_SAME1:
- if (delta < 64) {
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
- } else {
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- .putShort(delta);
- }
- writeFrameType(stack[0]);
- break;
+ }
+ writeFrameType(stack[0]);
+ break;
}
previousFrameOffset = code.length;
@@ -672,8 +659,7 @@ class MethodWriter extends MethodVisitor {
}
// if opcode == ATHROW or xRETURN, ends current block (no successor)
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
- || opcode == Opcodes.ATHROW)
- {
+ || opcode == Opcodes.ATHROW) {
noSuccessor();
}
}
@@ -731,8 +717,7 @@ class MethodWriter extends MethodVisitor {
// updates max locals
int n;
if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD
- || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE)
- {
+ || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) {
n = var + 2;
} else {
n = var + 1;
@@ -784,12 +769,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
Item i = cw.newFieldItem(owner, name, desc);
// Label currentBlock = this.currentBlock;
if (currentBlock != null) {
@@ -800,19 +781,19 @@ class MethodWriter extends MethodVisitor {
// computes the stack size variation
char c = desc.charAt(0);
switch (opcode) {
- case Opcodes.GETSTATIC:
- size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
- break;
- case Opcodes.PUTSTATIC:
- size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
- break;
- case Opcodes.GETFIELD:
- size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
- break;
- // case Constants.PUTFIELD:
- default:
- size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
- break;
+ case Opcodes.GETSTATIC:
+ size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
+ break;
+ case Opcodes.PUTSTATIC:
+ size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
+ break;
+ case Opcodes.GETFIELD:
+ size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
+ break;
+ // case Constants.PUTFIELD:
+ default:
+ size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
+ break;
}
// updates current and max stack sizes
if (size > maxStackSize) {
@@ -826,12 +807,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
boolean itf = opcode == Opcodes.INVOKEINTERFACE;
Item i = cw.newMethodItem(owner, name, desc, itf);
int argSize = i.intVal;
@@ -882,12 +859,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitInvokeDynamicInsn(
- final String name,
- final String desc,
- final Handle bsm,
- final Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
int argSize = i.intVal;
// Label currentBlock = this.currentBlock;
@@ -967,8 +940,7 @@ class MethodWriter extends MethodVisitor {
}
// adds the instruction to the bytecode of the method
if ((label.status & Label.RESOLVED) != 0
- && label.position - code.length < Short.MIN_VALUE)
- {
+ && label.position - code.length < Short.MIN_VALUE) {
/*
* case of a backward jump with an offset < -32768. In this case we
* automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
@@ -986,8 +958,7 @@ class MethodWriter extends MethodVisitor {
if (nextInsn != null) {
nextInsn.status |= Label.TARGET;
}
- code.putByte(opcode <= 166
- ? ((opcode + 1) ^ 1) - 1
+ code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
: opcode ^ 1);
code.putShort(8); // jump offset
code.putByte(200); // GOTO_W
@@ -1082,8 +1053,7 @@ class MethodWriter extends MethodVisitor {
} else {
int size;
// computes the stack size variation
- if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE)
- {
+ if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
size = stackSize + 2;
} else {
size = stackSize + 1;
@@ -1122,8 +1092,7 @@ class MethodWriter extends MethodVisitor {
}
// adds the instruction to the bytecode of the method
if ((var > 255) || (increment > 127) || (increment < -128)) {
- code.putByte(196 /* WIDE */)
- .put12(Opcodes.IINC, var)
+ code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var)
.putShort(increment);
} else {
code.putByte(Opcodes.IINC).put11(var, increment);
@@ -1131,12 +1100,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.TABLESWITCH);
@@ -1151,11 +1116,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
// adds the instruction to the bytecode of the method
int source = code.length;
code.putByte(Opcodes.LOOKUPSWITCH);
@@ -1214,12 +1176,8 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
++handlerCount;
Handler h = new Handler();
h.start = start;
@@ -1236,14 +1194,9 @@ class MethodWriter extends MethodVisitor {
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
if (signature != null) {
if (localVarType == null) {
localVarType = new ByteVector();
@@ -1251,8 +1204,7 @@ class MethodWriter extends MethodVisitor {
++localVarTypeCount;
localVarType.putShort(start.position)
.putShort(end.position - start.position)
- .putShort(cw.newUTF8(name))
- .putShort(cw.newUTF8(signature))
+ .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature))
.putShort(index);
}
if (localVar == null) {
@@ -1261,8 +1213,7 @@ class MethodWriter extends MethodVisitor {
++localVarCount;
localVar.putShort(start.position)
.putShort(end.position - start.position)
- .putShort(cw.newUTF8(name))
- .putShort(cw.newUTF8(desc))
+ .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc))
.putShort(index);
if (compute != NOTHING) {
// updates max locals
@@ -1294,8 +1245,7 @@ class MethodWriter extends MethodVisitor {
Label h = handler.handler.getFirst();
Label e = handler.end.getFirst();
// computes the kind of the edges to 'h'
- String t = handler.desc == null
- ? "java/lang/Throwable"
+ String t = handler.desc == null ? "java/lang/Throwable"
: handler.desc;
int kind = Frame.OBJECT | cw.addType(t);
// h is an exception handler
@@ -1382,11 +1332,12 @@ class MethodWriter extends MethodVisitor {
}
code.data[end] = (byte) Opcodes.ATHROW;
// emits a frame for this unreachable block
- startFrame(start, 0, 1);
- frame[frameIndex++] = Frame.OBJECT
+ int frameIndex = startFrame(start, 0, 1);
+ frame[frameIndex] = Frame.OBJECT
| cw.addType("java/lang/Throwable");
endFrame();
- // removes the start-end range from the exception handlers
+ // removes the start-end range from the exception
+ // handlers
firstHandler = Handler.remove(firstHandler, l, k);
}
}
@@ -1535,8 +1486,10 @@ class MethodWriter extends MethodVisitor {
/**
* Adds a successor to the {@link #currentBlock currentBlock} block.
*
- * @param info information about the control flow edge to be added.
- * @param successor the successor block to be added to the current block.
+ * @param info
+ * information about the control flow edge to be added.
+ * @param successor
+ * the successor block to be added to the current block.
*/
private void addSuccessor(final int info, final Label successor) {
// creates and initializes an Edge object...
@@ -1573,7 +1526,8 @@ class MethodWriter extends MethodVisitor {
/**
* Visits a frame that has been computed from scratch.
*
- * @param f the frame that must be visited.
+ * @param f
+ * the frame that must be visited.
*/
private void visitFrame(final Frame f) {
int i, t;
@@ -1606,7 +1560,7 @@ class MethodWriter extends MethodVisitor {
}
}
// visits the frame and its content
- startFrame(f.owner.position, nLocal, nStack);
+ int frameIndex = startFrame(f.owner.position, nLocal, nStack);
for (i = 0; nLocal > 0; ++i, --nLocal) {
t = locals[i];
frame[frameIndex++] = t;
@@ -1625,15 +1579,78 @@ class MethodWriter extends MethodVisitor {
}
/**
+ * Visit the implicit first frame of this method.
+ */
+ private void visitImplicitFirstFrame() {
+ // There can be at most descriptor.length() + 1 locals
+ int frameIndex = startFrame(0, descriptor.length() + 1, 0);
+ if ((access & Opcodes.ACC_STATIC) == 0) {
+ if ((access & ACC_CONSTRUCTOR) == 0) {
+ frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
+ } else {
+ frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+ }
+ }
+ int i = 1;
+ loop: while (true) {
+ int j = i;
+ switch (descriptor.charAt(i++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ frame[frameIndex++] = 1; // Opcodes.INTEGER;
+ break;
+ case 'F':
+ frame[frameIndex++] = 2; // Opcodes.FLOAT;
+ break;
+ case 'J':
+ frame[frameIndex++] = 4; // Opcodes.LONG;
+ break;
+ case 'D':
+ frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+ break;
+ case '[':
+ while (descriptor.charAt(i) == '[') {
+ ++i;
+ }
+ if (descriptor.charAt(i) == 'L') {
+ ++i;
+ while (descriptor.charAt(i) != ';') {
+ ++i;
+ }
+ }
+ frame[frameIndex++] = Frame.OBJECT
+ | cw.addType(descriptor.substring(j, ++i));
+ break;
+ case 'L':
+ while (descriptor.charAt(i) != ';') {
+ ++i;
+ }
+ frame[frameIndex++] = Frame.OBJECT
+ | cw.addType(descriptor.substring(j + 1, i++));
+ break;
+ default:
+ break loop;
+ }
+ }
+ frame[1] = frameIndex - 3;
+ endFrame();
+ }
+
+ /**
* Starts the visit of a stack map frame.
*
- * @param offset the offset of the instruction to which the frame
- * corresponds.
- * @param nLocal the number of local variables in the frame.
- * @param nStack the number of stack elements in the frame.
- */
- private void startFrame(final int offset, final int nLocal, final int nStack)
- {
+ * @param offset
+ * the offset of the instruction to which the frame corresponds.
+ * @param nLocal
+ * the number of local variables in the frame.
+ * @param nStack
+ * the number of stack elements in the frame.
+ * @return the index of the next element to be written in this frame.
+ */
+ private int startFrame(final int offset, final int nLocal, final int nStack) {
int n = 3 + nLocal + nStack;
if (frame == null || frame.length < n) {
frame = new int[n];
@@ -1641,7 +1658,7 @@ class MethodWriter extends MethodVisitor {
frame[0] = offset;
frame[1] = nLocal;
frame[2] = nStack;
- frameIndex = 3;
+ return 3;
}
/**
@@ -1686,24 +1703,23 @@ class MethodWriter extends MethodVisitor {
if (cstackSize == 0) {
k = clocalsSize - localsSize;
switch (k) {
- case -3:
- case -2:
- case -1:
- type = CHOP_FRAME;
- localsSize = clocalsSize;
- break;
- case 0:
- type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
- break;
- case 1:
- case 2:
- case 3:
- type = APPEND_FRAME;
- break;
+ case -3:
+ case -2:
+ case -1:
+ type = CHOP_FRAME;
+ localsSize = clocalsSize;
+ break;
+ case 0:
+ type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ type = APPEND_FRAME;
+ break;
}
} else if (clocalsSize == localsSize && cstackSize == 1) {
- type = delta < 63
- ? SAME_LOCALS_1_STACK_ITEM_FRAME
+ type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME
: SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
}
if (type != FULL_FRAME) {
@@ -1718,36 +1734,34 @@ class MethodWriter extends MethodVisitor {
}
}
switch (type) {
- case SAME_FRAME:
- stackMap.putByte(delta);
- break;
- case SAME_LOCALS_1_STACK_ITEM_FRAME:
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
- break;
- case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- .putShort(delta);
- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
- break;
- case SAME_FRAME_EXTENDED:
- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
- break;
- case CHOP_FRAME:
- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
- break;
- case APPEND_FRAME:
- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
- writeFrameTypes(3 + localsSize, 3 + clocalsSize);
- break;
- // case FULL_FRAME:
- default:
- stackMap.putByte(FULL_FRAME)
- .putShort(delta)
- .putShort(clocalsSize);
- writeFrameTypes(3, 3 + clocalsSize);
- stackMap.putShort(cstackSize);
- writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+ case SAME_FRAME:
+ stackMap.putByte(delta);
+ break;
+ case SAME_LOCALS_1_STACK_ITEM_FRAME:
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+ writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+ break;
+ case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+ stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(
+ delta);
+ writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+ break;
+ case SAME_FRAME_EXTENDED:
+ stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+ break;
+ case CHOP_FRAME:
+ stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+ break;
+ case APPEND_FRAME:
+ stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+ writeFrameTypes(3 + localsSize, 3 + clocalsSize);
+ break;
+ // case FULL_FRAME:
+ default:
+ stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize);
+ writeFrameTypes(3, 3 + clocalsSize);
+ stackMap.putShort(cstackSize);
+ writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
}
}
@@ -1757,8 +1771,10 @@ class MethodWriter extends MethodVisitor {
* in {@link Label} to the format used in StackMapTable attributes. In
* particular, it converts type table indexes to constant pool indexes.
*
- * @param start index of the first type in {@link #frame} to write.
- * @param end index of last type in {@link #frame} to write (exclusive).
+ * @param start
+ * index of the first type in {@link #frame} to write.
+ * @param end
+ * index of last type in {@link #frame} to write (exclusive).
*/
private void writeFrameTypes(final int start, final int end) {
for (int i = start; i < end; ++i) {
@@ -1767,15 +1783,15 @@ class MethodWriter extends MethodVisitor {
if (d == 0) {
int v = t & Frame.BASE_VALUE;
switch (t & Frame.BASE_KIND) {
- case Frame.OBJECT:
- stackMap.putByte(7)
- .putShort(cw.newClass(cw.typeTable[v].strVal1));
- break;
- case Frame.UNINITIALIZED:
- stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
- break;
- default:
- stackMap.putByte(v);
+ case Frame.OBJECT:
+ stackMap.putByte(7).putShort(
+ cw.newClass(cw.typeTable[v].strVal1));
+ break;
+ case Frame.UNINITIALIZED:
+ stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
+ break;
+ default:
+ stackMap.putByte(v);
}
} else {
StringBuffer buf = new StringBuffer();
@@ -1789,29 +1805,29 @@ class MethodWriter extends MethodVisitor {
buf.append(';');
} else {
switch (t & 0xF) {
- case 1:
- buf.append('I');
- break;
- case 2:
- buf.append('F');
- break;
- case 3:
- buf.append('D');
- break;
- case 9:
- buf.append('Z');
- break;
- case 10:
- buf.append('B');
- break;
- case 11:
- buf.append('C');
- break;
- case 12:
- buf.append('S');
- break;
- default:
- buf.append('J');
+ case 1:
+ buf.append('I');
+ break;
+ case 2:
+ buf.append('F');
+ break;
+ case 3:
+ buf.append('D');
+ break;
+ case 9:
+ buf.append('Z');
+ break;
+ case 10:
+ buf.append('B');
+ break;
+ case 11:
+ buf.append('C');
+ break;
+ case 12:
+ buf.append('S');
+ break;
+ default:
+ buf.append('J');
}
}
stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
@@ -1875,10 +1891,7 @@ class MethodWriter extends MethodVisitor {
size += 8 + stackMap.length;
}
if (cattrs != null) {
- size += cattrs.getSize(cw,
- code.data,
- code.length,
- maxStack,
+ size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
}
}
@@ -1886,11 +1899,12 @@ class MethodWriter extends MethodVisitor {
cw.newUTF8("Exceptions");
size += 8 + 2 * exceptionCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- cw.newUTF8("Synthetic");
- size += 6;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ cw.newUTF8("Synthetic");
+ size += 6;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
@@ -1936,13 +1950,15 @@ class MethodWriter extends MethodVisitor {
/**
* Puts the bytecode of this method in the given byte vector.
*
- * @param out the byte vector into which the bytecode of this method must be
- * copied.
+ * @param out
+ * the byte vector into which the bytecode of this method must be
+ * copied.
*/
final void put(final ByteVector out) {
- int mask = Opcodes.ACC_DEPRECATED
+ final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+ int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / (ClassWriter.ACC_SYNTHETIC_ATTRIBUTE / Opcodes.ACC_SYNTHETIC));
+ | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc);
if (classReaderOffset != 0) {
out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength);
@@ -1955,10 +1971,11 @@ class MethodWriter extends MethodVisitor {
if (exceptionCount > 0) {
++attributeCount;
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- ++attributeCount;
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ ++attributeCount;
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
@@ -2000,10 +2017,7 @@ class MethodWriter extends MethodVisitor {
size += 8 + stackMap.length;
}
if (cattrs != null) {
- size += cattrs.getSize(cw,
- code.data,
- code.length,
- maxStack,
+ size += cattrs.getSize(cw, code.data, code.length, maxStack,
maxLocals);
}
out.putShort(cw.newUTF8("Code")).putInt(size);
@@ -2013,10 +2027,8 @@ class MethodWriter extends MethodVisitor {
if (handlerCount > 0) {
Handler h = firstHandler;
while (h != null) {
- out.putShort(h.start.position)
- .putShort(h.end.position)
- .putShort(h.handler.position)
- .putShort(h.type);
+ out.putShort(h.start.position).putShort(h.end.position)
+ .putShort(h.handler.position).putShort(h.type);
h = h.next;
}
}
@@ -2063,24 +2075,24 @@ class MethodWriter extends MethodVisitor {
}
}
if (exceptionCount > 0) {
- out.putShort(cw.newUTF8("Exceptions"))
- .putInt(2 * exceptionCount + 2);
+ out.putShort(cw.newUTF8("Exceptions")).putInt(
+ 2 * exceptionCount + 2);
out.putShort(exceptionCount);
for (int i = 0; i < exceptionCount; ++i) {
out.putShort(exceptions[i]);
}
}
- if ((access & Opcodes.ACC_SYNTHETIC) != 0
- && ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0))
- {
- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if ((cw.version & 0xFFFF) < Opcodes.V1_5
+ || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+ out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+ }
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
if (ClassReader.SIGNATURES && signature != null) {
- out.putShort(cw.newUTF8("Signature"))
- .putInt(2)
+ out.putShort(cw.newUTF8("Signature")).putInt(2)
.putShort(cw.newUTF8(signature));
}
if (ClassReader.ANNOTATIONS && annd != null) {
@@ -2123,10 +2135,12 @@ class MethodWriter extends MethodVisitor {
* 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
* 32765. This, in turn, may require to increase the size of another jump
* instruction, and so on... All these operations are handled automatically
- * by this method. <p> <i>This method must be called after all the method
- * that is being built has been visited</i>. In particular, the
- * {@link Label Label} objects used to construct the method are no longer
- * valid after this method has been called.
+ * by this method.
+ * <p>
+ * <i>This method must be called after all the method that is being built
+ * has been visited</i>. In particular, the {@link Label Label} objects used
+ * to construct the method are no longer valid after this method has been
+ * called.
*/
private void resizeInstructions() {
byte[] b = code.data; // bytecode of the method
@@ -2176,158 +2190,14 @@ class MethodWriter extends MethodVisitor {
int insert = 0; // bytes to be added after this instruction
switch (ClassWriter.TYPE[opcode]) {
- case ClassWriter.NOARG_INSN:
- case ClassWriter.IMPLVAR_INSN:
- u += 1;
- break;
- case ClassWriter.LABEL_INSN:
- if (opcode > 201) {
- // converts temporary opcodes 202 to 217, 218 and
- // 219 to IFEQ ... JSR (inclusive), IFNULL and
- // IFNONNULL
- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
- label = u + readUnsignedShort(b, u + 1);
- } else {
- label = u + readShort(b, u + 1);
- }
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (newOffset < Short.MIN_VALUE
- || newOffset > Short.MAX_VALUE)
- {
- if (!resize[u]) {
- if (opcode == Opcodes.GOTO
- || opcode == Opcodes.JSR)
- {
- // two additional bytes will be required to
- // replace this GOTO or JSR instruction with
- // a GOTO_W or a JSR_W
- insert = 2;
- } else {
- // five additional bytes will be required to
- // replace this IFxxx <l> instruction with
- // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
- // is the "opposite" opcode of IFxxx (i.e.,
- // IFNE for IFEQ) and where <l'> designates
- // the instruction just after the GOTO_W.
- insert = 5;
- }
- resize[u] = true;
- }
- }
- u += 3;
- break;
- case ClassWriter.LABELW_INSN:
- u += 5;
- break;
- case ClassWriter.TABL_INSN:
- if (state == 1) {
- // true number of bytes to be added (or removed)
- // from this instruction = (future number of padding
- // bytes - current number of padding byte) -
- // previously over estimated variation =
- // = ((3 - newOffset%4) - (3 - u%4)) - u%4
- // = (-newOffset%4 + u%4) - u%4
- // = -(newOffset & 3)
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // over estimation of the number of bytes to be
- // added to this instruction = 3 - current number
- // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
- break;
- case ClassWriter.LOOK_INSN:
- if (state == 1) {
- // like TABL_INSN
- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
- insert = -(newOffset & 3);
- } else if (!resize[u]) {
- // like TABL_INSN
- insert = u & 3;
- resize[u] = true;
- }
- // skips instruction
- u = u + 4 - (u & 3);
- u += 8 * readInt(b, u + 4) + 8;
- break;
- case ClassWriter.WIDE_INSN:
- opcode = b[u + 1] & 0xFF;
- if (opcode == Opcodes.IINC) {
- u += 6;
- } else {
- u += 4;
- }
- break;
- case ClassWriter.VAR_INSN:
- case ClassWriter.SBYTE_INSN:
- case ClassWriter.LDC_INSN:
- u += 2;
- break;
- case ClassWriter.SHORT_INSN:
- case ClassWriter.LDCW_INSN:
- case ClassWriter.FIELDORMETH_INSN:
- case ClassWriter.TYPE_INSN:
- case ClassWriter.IINC_INSN:
- u += 3;
- break;
- case ClassWriter.ITFMETH_INSN:
- case ClassWriter.INDYMETH_INSN:
- u += 5;
- break;
- // case ClassWriter.MANA_INSN:
- default:
- u += 4;
- break;
- }
- if (insert != 0) {
- // adds a new (u, insert) entry in the allIndexes and
- // allSizes arrays
- int[] newIndexes = new int[allIndexes.length + 1];
- int[] newSizes = new int[allSizes.length + 1];
- System.arraycopy(allIndexes,
- 0,
- newIndexes,
- 0,
- allIndexes.length);
- System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
- newIndexes[allIndexes.length] = u;
- newSizes[allSizes.length] = insert;
- allIndexes = newIndexes;
- allSizes = newSizes;
- if (insert > 0) {
- state = 3;
- }
- }
- }
- if (state < 3) {
- --state;
- }
- } while (state != 0);
-
- // 2nd step:
- // copies the bytecode of the method into a new bytevector, updates the
- // offsets, and inserts (or removes) bytes as requested.
-
- ByteVector newCode = new ByteVector(code.length);
-
- u = 0;
- while (u < code.length) {
- int opcode = b[u] & 0xFF;
- switch (ClassWriter.TYPE[opcode]) {
case ClassWriter.NOARG_INSN:
case ClassWriter.IMPLVAR_INSN:
- newCode.putByte(opcode);
u += 1;
break;
case ClassWriter.LABEL_INSN:
if (opcode > 201) {
- // changes temporary opcodes 202 to 217 (inclusive), 218
- // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // converts temporary opcodes 202 to 217, 218 and
+ // 219 to IFEQ ... JSR (inclusive), IFNULL and
// IFNONNULL
opcode = opcode < 218 ? opcode - 49 : opcode - 20;
label = u + readUnsignedShort(b, u + 1);
@@ -2335,100 +2205,78 @@ class MethodWriter extends MethodVisitor {
label = u + readShort(b, u + 1);
}
newOffset = getNewOffset(allIndexes, allSizes, u, label);
- if (resize[u]) {
- // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
- // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
- // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
- // and where <l'> designates the instruction just after
- // the GOTO_W.
- if (opcode == Opcodes.GOTO) {
- newCode.putByte(200); // GOTO_W
- } else if (opcode == Opcodes.JSR) {
- newCode.putByte(201); // JSR_W
- } else {
- newCode.putByte(opcode <= 166
- ? ((opcode + 1) ^ 1) - 1
- : opcode ^ 1);
- newCode.putShort(8); // jump offset
- newCode.putByte(200); // GOTO_W
- // newOffset now computed from start of GOTO_W
- newOffset -= 3;
+ if (newOffset < Short.MIN_VALUE
+ || newOffset > Short.MAX_VALUE) {
+ if (!resize[u]) {
+ if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+ // two additional bytes will be required to
+ // replace this GOTO or JSR instruction with
+ // a GOTO_W or a JSR_W
+ insert = 2;
+ } else {
+ // five additional bytes will be required to
+ // replace this IFxxx <l> instruction with
+ // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
+ // is the "opposite" opcode of IFxxx (i.e.,
+ // IFNE for IFEQ) and where <l'> designates
+ // the instruction just after the GOTO_W.
+ insert = 5;
+ }
+ resize[u] = true;
}
- newCode.putInt(newOffset);
- } else {
- newCode.putByte(opcode);
- newCode.putShort(newOffset);
}
u += 3;
break;
case ClassWriter.LABELW_INSN:
- label = u + readInt(b, u + 1);
- newOffset = getNewOffset(allIndexes, allSizes, u, label);
- newCode.putByte(opcode);
- newCode.putInt(newOffset);
u += 5;
break;
case ClassWriter.TABL_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.TABLESWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- j = readInt(b, u) - j + 1;
- u += 4;
- newCode.putInt(readInt(b, u - 4));
- for (; j > 0; --j) {
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
+ if (state == 1) {
+ // true number of bytes to be added (or removed)
+ // from this instruction = (future number of padding
+ // bytes - current number of padding byte) -
+ // previously over estimated variation =
+ // = ((3 - newOffset%4) - (3 - u%4)) - u%4
+ // = (-newOffset%4 + u%4) - u%4
+ // = -(newOffset & 3)
+ newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+ insert = -(newOffset & 3);
+ } else if (!resize[u]) {
+ // over estimation of the number of bytes to be
+ // added to this instruction = 3 - current number
+ // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
+ insert = u & 3;
+ resize[u] = true;
}
+ // skips instruction
+ u = u + 4 - (u & 3);
+ u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
break;
case ClassWriter.LOOK_INSN:
- // skips 0 to 3 padding bytes
- v = u;
- u = u + 4 - (v & 3);
- // reads and copies instruction
- newCode.putByte(Opcodes.LOOKUPSWITCH);
- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
- j = readInt(b, u);
- u += 4;
- newCode.putInt(j);
- for (; j > 0; --j) {
- newCode.putInt(readInt(b, u));
- u += 4;
- label = v + readInt(b, u);
- u += 4;
- newOffset = getNewOffset(allIndexes, allSizes, v, label);
- newCode.putInt(newOffset);
+ if (state == 1) {
+ // like TABL_INSN
+ newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+ insert = -(newOffset & 3);
+ } else if (!resize[u]) {
+ // like TABL_INSN
+ insert = u & 3;
+ resize[u] = true;
}
+ // skips instruction
+ u = u + 4 - (u & 3);
+ u += 8 * readInt(b, u + 4) + 8;
break;
case ClassWriter.WIDE_INSN:
opcode = b[u + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
- newCode.putByteArray(b, u, 6);
u += 6;
} else {
- newCode.putByteArray(b, u, 4);
u += 4;
}
break;
case ClassWriter.VAR_INSN:
case ClassWriter.SBYTE_INSN:
case ClassWriter.LDC_INSN:
- newCode.putByteArray(b, u, 2);
u += 2;
break;
case ClassWriter.SHORT_INSN:
@@ -2436,19 +2284,178 @@ class MethodWriter extends MethodVisitor {
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.TYPE_INSN:
case ClassWriter.IINC_INSN:
- newCode.putByteArray(b, u, 3);
u += 3;
break;
case ClassWriter.ITFMETH_INSN:
case ClassWriter.INDYMETH_INSN:
- newCode.putByteArray(b, u, 5);
u += 5;
break;
- // case MANA_INSN:
+ // case ClassWriter.MANA_INSN:
default:
- newCode.putByteArray(b, u, 4);
u += 4;
break;
+ }
+ if (insert != 0) {
+ // adds a new (u, insert) entry in the allIndexes and
+ // allSizes arrays
+ int[] newIndexes = new int[allIndexes.length + 1];
+ int[] newSizes = new int[allSizes.length + 1];
+ System.arraycopy(allIndexes, 0, newIndexes, 0,
+ allIndexes.length);
+ System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
+ newIndexes[allIndexes.length] = u;
+ newSizes[allSizes.length] = insert;
+ allIndexes = newIndexes;
+ allSizes = newSizes;
+ if (insert > 0) {
+ state = 3;
+ }
+ }
+ }
+ if (state < 3) {
+ --state;
+ }
+ } while (state != 0);
+
+ // 2nd step:
+ // copies the bytecode of the method into a new bytevector, updates the
+ // offsets, and inserts (or removes) bytes as requested.
+
+ ByteVector newCode = new ByteVector(code.length);
+
+ u = 0;
+ while (u < code.length) {
+ int opcode = b[u] & 0xFF;
+ switch (ClassWriter.TYPE[opcode]) {
+ case ClassWriter.NOARG_INSN:
+ case ClassWriter.IMPLVAR_INSN:
+ newCode.putByte(opcode);
+ u += 1;
+ break;
+ case ClassWriter.LABEL_INSN:
+ if (opcode > 201) {
+ // changes temporary opcodes 202 to 217 (inclusive), 218
+ // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+ // IFNONNULL
+ opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+ label = u + readUnsignedShort(b, u + 1);
+ } else {
+ label = u + readShort(b, u + 1);
+ }
+ newOffset = getNewOffset(allIndexes, allSizes, u, label);
+ if (resize[u]) {
+ // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+ // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
+ // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+ // and where <l'> designates the instruction just after
+ // the GOTO_W.
+ if (opcode == Opcodes.GOTO) {
+ newCode.putByte(200); // GOTO_W
+ } else if (opcode == Opcodes.JSR) {
+ newCode.putByte(201); // JSR_W
+ } else {
+ newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+ : opcode ^ 1);
+ newCode.putShort(8); // jump offset
+ newCode.putByte(200); // GOTO_W
+ // newOffset now computed from start of GOTO_W
+ newOffset -= 3;
+ }
+ newCode.putInt(newOffset);
+ } else {
+ newCode.putByte(opcode);
+ newCode.putShort(newOffset);
+ }
+ u += 3;
+ break;
+ case ClassWriter.LABELW_INSN:
+ label = u + readInt(b, u + 1);
+ newOffset = getNewOffset(allIndexes, allSizes, u, label);
+ newCode.putByte(opcode);
+ newCode.putInt(newOffset);
+ u += 5;
+ break;
+ case ClassWriter.TABL_INSN:
+ // skips 0 to 3 padding bytes
+ v = u;
+ u = u + 4 - (v & 3);
+ // reads and copies instruction
+ newCode.putByte(Opcodes.TABLESWITCH);
+ newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ j = readInt(b, u);
+ u += 4;
+ newCode.putInt(j);
+ j = readInt(b, u) - j + 1;
+ u += 4;
+ newCode.putInt(readInt(b, u - 4));
+ for (; j > 0; --j) {
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ }
+ break;
+ case ClassWriter.LOOK_INSN:
+ // skips 0 to 3 padding bytes
+ v = u;
+ u = u + 4 - (v & 3);
+ // reads and copies instruction
+ newCode.putByte(Opcodes.LOOKUPSWITCH);
+ newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ j = readInt(b, u);
+ u += 4;
+ newCode.putInt(j);
+ for (; j > 0; --j) {
+ newCode.putInt(readInt(b, u));
+ u += 4;
+ label = v + readInt(b, u);
+ u += 4;
+ newOffset = getNewOffset(allIndexes, allSizes, v, label);
+ newCode.putInt(newOffset);
+ }
+ break;
+ case ClassWriter.WIDE_INSN:
+ opcode = b[u + 1] & 0xFF;
+ if (opcode == Opcodes.IINC) {
+ newCode.putByteArray(b, u, 6);
+ u += 6;
+ } else {
+ newCode.putByteArray(b, u, 4);
+ u += 4;
+ }
+ break;
+ case ClassWriter.VAR_INSN:
+ case ClassWriter.SBYTE_INSN:
+ case ClassWriter.LDC_INSN:
+ newCode.putByteArray(b, u, 2);
+ u += 2;
+ break;
+ case ClassWriter.SHORT_INSN:
+ case ClassWriter.LDCW_INSN:
+ case ClassWriter.FIELDORMETH_INSN:
+ case ClassWriter.TYPE_INSN:
+ case ClassWriter.IINC_INSN:
+ newCode.putByteArray(b, u, 3);
+ u += 3;
+ break;
+ case ClassWriter.ITFMETH_INSN:
+ case ClassWriter.INDYMETH_INSN:
+ newCode.putByteArray(b, u, 5);
+ u += 5;
+ break;
+ // case MANA_INSN:
+ default:
+ newCode.putByteArray(b, u, 4);
+ u += 4;
+ break;
}
}
@@ -2471,8 +2478,7 @@ class MethodWriter extends MethodVisitor {
* must therefore never have been called for this label.
*/
u = l.position - 3;
- if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u]))
- {
+ if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
getNewOffset(allIndexes, allSizes, l);
// TODO update offsets in UNINITIALIZED values
visitFrame(l.frame);
@@ -2528,10 +2534,11 @@ class MethodWriter extends MethodVisitor {
b = lineNumber.data;
u = 0;
while (u < lineNumber.length) {
- writeShort(b, u, getNewOffset(allIndexes,
- allSizes,
- 0,
- readUnsignedShort(b, u)));
+ writeShort(
+ b,
+ u,
+ getNewOffset(allIndexes, allSizes, 0,
+ readUnsignedShort(b, u)));
u += 4;
}
}
@@ -2554,8 +2561,10 @@ class MethodWriter extends MethodVisitor {
/**
* Reads an unsigned short value in the given byte array.
*
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static int readUnsignedShort(final byte[] b, final int index) {
@@ -2565,8 +2574,10 @@ class MethodWriter extends MethodVisitor {
/**
* Reads a signed short value in the given byte array.
*
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static short readShort(final byte[] b, final int index) {
@@ -2576,8 +2587,10 @@ class MethodWriter extends MethodVisitor {
/**
* Reads a signed int value in the given byte array.
*
- * @param b a byte array.
- * @param index the start index of the value to be read.
+ * @param b
+ * a byte array.
+ * @param index
+ * the start index of the value to be read.
* @return the read value.
*/
static int readInt(final byte[] b, final int index) {
@@ -2588,9 +2601,12 @@ class MethodWriter extends MethodVisitor {
/**
* Writes a short value in the given byte array.
*
- * @param b a byte array.
- * @param index where the first byte of the short value must be written.
- * @param s the value to be written in the given byte array.
+ * @param b
+ * a byte array.
+ * @param index
+ * where the first byte of the short value must be written.
+ * @param s
+ * the value to be written in the given byte array.
*/
static void writeShort(final byte[] b, final int index, final int s) {
b[index] = (byte) (s >>> 8);
@@ -2598,32 +2614,34 @@ class MethodWriter extends MethodVisitor {
}
/**
- * Computes the future value of a bytecode offset. <p> Note: it is possible
- * to have several entries for the same instruction in the <tt>indexes</tt>
- * and <tt>sizes</tt>: two entries (index=a,size=b) and (index=a,size=b')
- * are equivalent to a single entry (index=a,size=b+b').
+ * Computes the future value of a bytecode offset.
+ * <p>
+ * Note: it is possible to have several entries for the same instruction in
+ * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
+ * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
*
- * @param indexes current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the <i>first</i>
- * byte of the <i>next</i> instruction).
- * @param sizes the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
- * bytes of the instruction will be removed (the instruction size
- * <i>must not</i> become negative or null).
- * @param begin index of the first byte of the source instruction.
- * @param end index of the first byte of the target instruction.
+ * @param indexes
+ * current positions of the instructions to be resized. Each
+ * instruction must be designated by the index of its <i>last</i>
+ * byte, plus one (or, in other words, by the index of the
+ * <i>first</i> byte of the <i>next</i> instruction).
+ * @param sizes
+ * the number of bytes to be <i>added</i> to the above
+ * instructions. More precisely, for each i < <tt>len</tt>,
+ * <tt>sizes</tt>[i] bytes will be added at the end of the
+ * instruction designated by <tt>indexes</tt>[i] or, if
+ * <tt>sizes</tt>[i] is negative, the <i>last</i> |
+ * <tt>sizes[i]</tt>| bytes of the instruction will be removed
+ * (the instruction size <i>must not</i> become negative or
+ * null).
+ * @param begin
+ * index of the first byte of the source instruction.
+ * @param end
+ * index of the first byte of the target instruction.
* @return the future value of the given bytecode offset.
*/
- static int getNewOffset(
- final int[] indexes,
- final int[] sizes,
- final int begin,
- final int end)
- {
+ static int getNewOffset(final int[] indexes, final int[] sizes,
+ final int begin, final int end) {
int offset = end - begin;
for (int i = 0; i < indexes.length; ++i) {
if (begin < indexes[i] && indexes[i] <= end) {
@@ -2640,24 +2658,25 @@ class MethodWriter extends MethodVisitor {
/**
* Updates the offset of the given label.
*
- * @param indexes current positions of the instructions to be resized. Each
- * instruction must be designated by the index of its <i>last</i>
- * byte, plus one (or, in other words, by the index of the <i>first</i>
- * byte of the <i>next</i> instruction).
- * @param sizes the number of bytes to be <i>added</i> to the above
- * instructions. More precisely, for each i < <tt>len</tt>,
- * <tt>sizes</tt>[i] bytes will be added at the end of the
- * instruction designated by <tt>indexes</tt>[i] or, if
- * <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
- * bytes of the instruction will be removed (the instruction size
- * <i>must not</i> become negative or null).
- * @param label the label whose offset must be updated.
- */
- static void getNewOffset(
- final int[] indexes,
- final int[] sizes,
- final Label label)
- {
+ * @param indexes
+ * current positions of the instructions to be resized. Each
+ * instruction must be designated by the index of its <i>last</i>
+ * byte, plus one (or, in other words, by the index of the
+ * <i>first</i> byte of the <i>next</i> instruction).
+ * @param sizes
+ * the number of bytes to be <i>added</i> to the above
+ * instructions. More precisely, for each i < <tt>len</tt>,
+ * <tt>sizes</tt>[i] bytes will be added at the end of the
+ * instruction designated by <tt>indexes</tt>[i] or, if
+ * <tt>sizes</tt>[i] is negative, the <i>last</i> |
+ * <tt>sizes[i]</tt>| bytes of the instruction will be removed
+ * (the instruction size <i>must not</i> become negative or
+ * null).
+ * @param label
+ * the label whose offset must be updated.
+ */
+ static void getNewOffset(final int[] indexes, final int[] sizes,
+ final Label label) {
if ((label.status & Label.RESIZED) == 0) {
label.position = getNewOffset(indexes, sizes, 0, label.position);
label.status |= Label.RESIZED;
diff --git a/src/asm/scala/tools/asm/Type.java b/src/asm/scala/tools/asm/Type.java
index bf1107182a..7821a492e6 100644
--- a/src/asm/scala/tools/asm/Type.java
+++ b/src/asm/scala/tools/asm/Type.java
@@ -190,13 +190,16 @@ public class Type {
/**
* Constructs a reference type.
*
- * @param sort the sort of the reference type to be constructed.
- * @param buf a buffer containing the descriptor of the previous type.
- * @param off the offset of this descriptor in the previous buffer.
- * @param len the length of this descriptor.
- */
- private Type(final int sort, final char[] buf, final int off, final int len)
- {
+ * @param sort
+ * the sort of the reference type to be constructed.
+ * @param buf
+ * a buffer containing the descriptor of the previous type.
+ * @param off
+ * the offset of this descriptor in the previous buffer.
+ * @param len
+ * the length of this descriptor.
+ */
+ private Type(final int sort, final char[] buf, final int off, final int len) {
this.sort = sort;
this.buf = buf;
this.off = off;
@@ -206,7 +209,8 @@ public class Type {
/**
* Returns the Java type corresponding to the given type descriptor.
*
- * @param typeDescriptor a field or method type descriptor.
+ * @param typeDescriptor
+ * a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor.
*/
public static Type getType(final String typeDescriptor) {
@@ -216,7 +220,8 @@ public class Type {
/**
* Returns the Java type corresponding to the given internal name.
*
- * @param internalName an internal name.
+ * @param internalName
+ * an internal name.
* @return the Java type corresponding to the given internal name.
*/
public static Type getObjectType(final String internalName) {
@@ -228,7 +233,8 @@ public class Type {
* Returns the Java type corresponding to the given method descriptor.
* Equivalent to <code>Type.getType(methodDescriptor)</code>.
*
- * @param methodDescriptor a method descriptor.
+ * @param methodDescriptor
+ * a method descriptor.
* @return the Java type corresponding to the given method descriptor.
*/
public static Type getMethodType(final String methodDescriptor) {
@@ -239,18 +245,23 @@ public class Type {
* Returns the Java method type corresponding to the given argument and
* return types.
*
- * @param returnType the return type of the method.
- * @param argumentTypes the argument types of the method.
- * @return the Java type corresponding to the given argument and return types.
+ * @param returnType
+ * the return type of the method.
+ * @param argumentTypes
+ * the argument types of the method.
+ * @return the Java type corresponding to the given argument and return
+ * types.
*/
- public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
+ public static Type getMethodType(final Type returnType,
+ final Type... argumentTypes) {
return getType(getMethodDescriptor(returnType, argumentTypes));
}
/**
* Returns the Java type corresponding to the given class.
*
- * @param c a class.
+ * @param c
+ * a class.
* @return the Java type corresponding to the given class.
*/
public static Type getType(final Class<?> c) {
@@ -282,7 +293,8 @@ public class Type {
/**
* Returns the Java method type corresponding to the given constructor.
*
- * @param c a {@link Constructor Constructor} object.
+ * @param c
+ * a {@link Constructor Constructor} object.
* @return the Java method type corresponding to the given constructor.
*/
public static Type getType(final Constructor<?> c) {
@@ -292,7 +304,8 @@ public class Type {
/**
* Returns the Java method type corresponding to the given method.
*
- * @param m a {@link Method Method} object.
+ * @param m
+ * a {@link Method Method} object.
* @return the Java method type corresponding to the given method.
*/
public static Type getType(final Method m) {
@@ -303,7 +316,8 @@ public class Type {
* Returns the Java types corresponding to the argument types of the given
* method descriptor.
*
- * @param methodDescriptor a method descriptor.
+ * @param methodDescriptor
+ * a method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
*/
@@ -338,7 +352,8 @@ public class Type {
* Returns the Java types corresponding to the argument types of the given
* method.
*
- * @param method a method.
+ * @param method
+ * a method.
* @return the Java types corresponding to the argument types of the given
* method.
*/
@@ -355,7 +370,8 @@ public class Type {
* Returns the Java type corresponding to the return type of the given
* method descriptor.
*
- * @param methodDescriptor a method descriptor.
+ * @param methodDescriptor
+ * a method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
*/
@@ -368,7 +384,8 @@ public class Type {
* Returns the Java type corresponding to the return type of the given
* method.
*
- * @param method a method.
+ * @param method
+ * a method.
* @return the Java type corresponding to the return type of the given
* method.
*/
@@ -379,12 +396,13 @@ public class Type {
/**
* Computes the size of the arguments and of the return value of a method.
*
- * @param desc the descriptor of a method.
+ * @param desc
+ * the descriptor of a method.
* @return the size of the arguments of the method (plus one for the
* implicit this argument), argSize, and the size of its return
* value, retSize, packed into a single int i =
- * <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal
- * to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
+ * <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
+ * <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
*/
public static int getArgumentsAndReturnSizes(final String desc) {
int n = 1;
@@ -419,52 +437,54 @@ public class Type {
* method descriptors, buf is supposed to contain nothing more than the
* descriptor itself.
*
- * @param buf a buffer containing a type descriptor.
- * @param off the offset of this descriptor in the previous buffer.
+ * @param buf
+ * a buffer containing a type descriptor.
+ * @param off
+ * the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor.
*/
private static Type getType(final char[] buf, final int off) {
int len;
switch (buf[off]) {
- case 'V':
- return VOID_TYPE;
- case 'Z':
- return BOOLEAN_TYPE;
- case 'C':
- return CHAR_TYPE;
- case 'B':
- return BYTE_TYPE;
- case 'S':
- return SHORT_TYPE;
- case 'I':
- return INT_TYPE;
- case 'F':
- return FLOAT_TYPE;
- case 'J':
- return LONG_TYPE;
- case 'D':
- return DOUBLE_TYPE;
- case '[':
- len = 1;
- while (buf[off + len] == '[') {
- ++len;
- }
- if (buf[off + len] == 'L') {
- ++len;
- while (buf[off + len] != ';') {
- ++len;
- }
- }
- return new Type(ARRAY, buf, off, len + 1);
- case 'L':
- len = 1;
+ case 'V':
+ return VOID_TYPE;
+ case 'Z':
+ return BOOLEAN_TYPE;
+ case 'C':
+ return CHAR_TYPE;
+ case 'B':
+ return BYTE_TYPE;
+ case 'S':
+ return SHORT_TYPE;
+ case 'I':
+ return INT_TYPE;
+ case 'F':
+ return FLOAT_TYPE;
+ case 'J':
+ return LONG_TYPE;
+ case 'D':
+ return DOUBLE_TYPE;
+ case '[':
+ len = 1;
+ while (buf[off + len] == '[') {
+ ++len;
+ }
+ if (buf[off + len] == 'L') {
+ ++len;
while (buf[off + len] != ';') {
++len;
}
- return new Type(OBJECT, buf, off + 1, len - 1);
+ }
+ return new Type(ARRAY, buf, off, len + 1);
+ case 'L':
+ len = 1;
+ while (buf[off + len] != ';') {
+ ++len;
+ }
+ return new Type(OBJECT, buf, off + 1, len - 1);
// case '(':
- default:
- return new Type(METHOD, buf, 0, buf.length);
+ default:
+ return new Type(METHOD, buf, off, buf.length - off);
}
}
@@ -475,11 +495,11 @@ public class Type {
/**
* Returns the sort of this Java type.
*
- * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
- * {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
- * {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
- * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY},
- * {@link #OBJECT OBJECT} or {@link #METHOD METHOD}.
+ * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
+ * {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
+ * {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
+ * {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
+ * METHOD}.
*/
public int getSort() {
return sort;
@@ -517,34 +537,34 @@ public class Type {
*/
public String getClassName() {
switch (sort) {
- case VOID:
- return "void";
- case BOOLEAN:
- return "boolean";
- case CHAR:
- return "char";
- case BYTE:
- return "byte";
- case SHORT:
- return "short";
- case INT:
- return "int";
- case FLOAT:
- return "float";
- case LONG:
- return "long";
- case DOUBLE:
- return "double";
- case ARRAY:
- StringBuffer b = new StringBuffer(getElementType().getClassName());
- for (int i = getDimensions(); i > 0; --i) {
- b.append("[]");
- }
- return b.toString();
- case OBJECT:
- return new String(buf, off, len).replace('/', '.');
- default:
- return null;
+ case VOID:
+ return "void";
+ case BOOLEAN:
+ return "boolean";
+ case CHAR:
+ return "char";
+ case BYTE:
+ return "byte";
+ case SHORT:
+ return "short";
+ case INT:
+ return "int";
+ case FLOAT:
+ return "float";
+ case LONG:
+ return "long";
+ case DOUBLE:
+ return "double";
+ case ARRAY:
+ StringBuffer b = new StringBuffer(getElementType().getClassName());
+ for (int i = getDimensions(); i > 0; --i) {
+ b.append("[]");
+ }
+ return b.toString();
+ case OBJECT:
+ return new String(buf, off, len).replace('/', '.');
+ default:
+ return null;
}
}
@@ -613,15 +633,15 @@ public class Type {
* Returns the descriptor corresponding to the given argument and return
* types.
*
- * @param returnType the return type of the method.
- * @param argumentTypes the argument types of the method.
+ * @param returnType
+ * the return type of the method.
+ * @param argumentTypes
+ * the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/
- public static String getMethodDescriptor(
- final Type returnType,
- final Type... argumentTypes)
- {
+ public static String getMethodDescriptor(final Type returnType,
+ final Type... argumentTypes) {
StringBuffer buf = new StringBuffer();
buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) {
@@ -636,11 +656,13 @@ public class Type {
* Appends the descriptor corresponding to this Java type to the given
* string buffer.
*
- * @param buf the string buffer to which the descriptor must be appended.
+ * @param buf
+ * the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuffer buf) {
if (this.buf == null) {
- // descriptor is in byte 3 of 'off' for primitive types (buf == null)
+ // descriptor is in byte 3 of 'off' for primitive types (buf ==
+ // null)
buf.append((char) ((off & 0xFF000000) >>> 24));
} else if (sort == OBJECT) {
buf.append('L');
@@ -661,7 +683,8 @@ public class Type {
* class is its fully qualified name, as returned by Class.getName(), where
* '.' are replaced by '/'.
*
- * @param c an object or array class.
+ * @param c
+ * an object or array class.
* @return the internal name of the given class.
*/
public static String getInternalName(final Class<?> c) {
@@ -671,7 +694,8 @@ public class Type {
/**
* Returns the descriptor corresponding to the given Java type.
*
- * @param c an object class, a primitive class or an array class.
+ * @param c
+ * an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class.
*/
public static String getDescriptor(final Class<?> c) {
@@ -683,7 +707,8 @@ public class Type {
/**
* Returns the descriptor corresponding to the given constructor.
*
- * @param c a {@link Constructor Constructor} object.
+ * @param c
+ * a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor.
*/
public static String getConstructorDescriptor(final Constructor<?> c) {
@@ -699,7 +724,8 @@ public class Type {
/**
* Returns the descriptor corresponding to the given method.
*
- * @param m a {@link Method Method} object.
+ * @param m
+ * a {@link Method Method} object.
* @return the descriptor of the given method.
*/
public static String getMethodDescriptor(final Method m) {
@@ -717,8 +743,10 @@ public class Type {
/**
* Appends the descriptor of the given class to the given string buffer.
*
- * @param buf the string buffer to which the descriptor must be appended.
- * @param c the class whose descriptor must be computed.
+ * @param buf
+ * the string buffer to which the descriptor must be appended.
+ * @param c
+ * the class whose descriptor must be computed.
*/
private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
Class<?> d = c;
@@ -783,9 +811,10 @@ public class Type {
* Returns a JVM instruction opcode adapted to this Java type. This method
* must not be used for method types.
*
- * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
- * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
- * ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
+ * @param opcode
+ * a JVM instruction opcode. This opcode must be one of ILOAD,
+ * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
+ * ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to
* this Java type. For example, if this type is <tt>float</tt> and
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
@@ -809,7 +838,8 @@ public class Type {
/**
* Tests if the given object is equal to this type.
*
- * @param o the object to be compared to this type.
+ * @param o
+ * the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type.
*/
@Override
diff --git a/src/asm/scala/tools/asm/signature/SignatureReader.java b/src/asm/scala/tools/asm/signature/SignatureReader.java
index 22e6427e63..9c7c3880d9 100644
--- a/src/asm/scala/tools/asm/signature/SignatureReader.java
+++ b/src/asm/scala/tools/asm/signature/SignatureReader.java
@@ -46,8 +46,9 @@ public class SignatureReader {
/**
* Constructs a {@link SignatureReader} for the given signature.
*
- * @param signature A <i>ClassSignature</i>, <i>MethodTypeSignature</i>,
- * or <i>FieldTypeSignature</i>.
+ * @param signature
+ * A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
+ * <i>FieldTypeSignature</i>.
*/
public SignatureReader(final String signature) {
this.signature = signature;
@@ -58,15 +59,15 @@ public class SignatureReader {
* {@link SignatureReader}. This signature is the one specified in the
* constructor (see {@link #SignatureReader(String) SignatureReader}). This
* method is intended to be called on a {@link SignatureReader} that was
- * created using a <i>ClassSignature</i> (such as the
+ * created using a <i>ClassSignature</i> (such as the <code>signature</code>
+ * parameter of the {@link scala.tools.asm.ClassVisitor#visit
+ * ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the
* <code>signature</code> parameter of the
- * {@link org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method)
- * or a <i>MethodTypeSignature</i> (such as the <code>signature</code>
- * parameter of the
- * {@link org.objectweb.asm.ClassVisitor#visitMethod ClassVisitor.visitMethod}
- * method).
+ * {@link scala.tools.asm.ClassVisitor#visitMethod
+ * ClassVisitor.visitMethod} method).
*
- * @param v the visitor that must visit this signature.
+ * @param v
+ * the visitor that must visit this signature.
*/
public void accept(final SignatureVisitor v) {
String signature = this.signature;
@@ -118,12 +119,12 @@ public class SignatureReader {
* method is intended to be called on a {@link SignatureReader} that was
* created using a <i>FieldTypeSignature</i>, such as the
* <code>signature</code> parameter of the
- * {@link org.objectweb.asm.ClassVisitor#visitField
- * ClassVisitor.visitField} or {@link
- * org.objectweb.asm.MethodVisitor#visitLocalVariable
+ * {@link scala.tools.asm.ClassVisitor#visitField ClassVisitor.visitField}
+ * or {@link scala.tools.asm.MethodVisitor#visitLocalVariable
* MethodVisitor.visitLocalVariable} methods.
*
- * @param v the visitor that must visit this signature.
+ * @param v
+ * the visitor that must visit this signature.
*/
public void acceptType(final SignatureVisitor v) {
parseType(this.signature, 0, v);
@@ -132,98 +133,96 @@ public class SignatureReader {
/**
* Parses a field type signature and makes the given visitor visit it.
*
- * @param signature a string containing the signature that must be parsed.
- * @param pos index of the first character of the signature to parsed.
- * @param v the visitor that must visit this signature.
+ * @param signature
+ * a string containing the signature that must be parsed.
+ * @param pos
+ * index of the first character of the signature to parsed.
+ * @param v
+ * the visitor that must visit this signature.
* @return the index of the first character after the parsed signature.
*/
- private static int parseType(
- final String signature,
- int pos,
- final SignatureVisitor v)
- {
+ private static int parseType(final String signature, int pos,
+ final SignatureVisitor v) {
char c;
int start, end;
boolean visited, inner;
String name;
switch (c = signature.charAt(pos++)) {
- case 'Z':
- case 'C':
- case 'B':
- case 'S':
- case 'I':
- case 'F':
- case 'J':
- case 'D':
- case 'V':
- v.visitBaseType(c);
- return pos;
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ case 'V':
+ v.visitBaseType(c);
+ return pos;
- case '[':
- return parseType(signature, pos, v.visitArrayType());
+ case '[':
+ return parseType(signature, pos, v.visitArrayType());
- case 'T':
- end = signature.indexOf(';', pos);
- v.visitTypeVariable(signature.substring(pos, end));
- return end + 1;
+ case 'T':
+ end = signature.indexOf(';', pos);
+ v.visitTypeVariable(signature.substring(pos, end));
+ return end + 1;
- default: // case 'L':
- start = pos;
- visited = false;
- inner = false;
- for (;;) {
- switch (c = signature.charAt(pos++)) {
- case '.':
- case ';':
- if (!visited) {
- name = signature.substring(start, pos - 1);
- if (inner) {
- v.visitInnerClassType(name);
- } else {
- v.visitClassType(name);
- }
- }
- if (c == ';') {
- v.visitEnd();
- return pos;
- }
- start = pos;
- visited = false;
- inner = true;
- break;
+ default: // case 'L':
+ start = pos;
+ visited = false;
+ inner = false;
+ for (;;) {
+ switch (c = signature.charAt(pos++)) {
+ case '.':
+ case ';':
+ if (!visited) {
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ }
+ if (c == ';') {
+ v.visitEnd();
+ return pos;
+ }
+ start = pos;
+ visited = false;
+ inner = true;
+ break;
- case '<':
- name = signature.substring(start, pos - 1);
- if (inner) {
- v.visitInnerClassType(name);
- } else {
- v.visitClassType(name);
- }
- visited = true;
- top: for (;;) {
- switch (c = signature.charAt(pos)) {
- case '>':
- break top;
- case '*':
- ++pos;
- v.visitTypeArgument();
- break;
- case '+':
- case '-':
- pos = parseType(signature,
- pos + 1,
- v.visitTypeArgument(c));
- break;
- default:
- pos = parseType(signature,
- pos,
- v.visitTypeArgument('='));
- break;
- }
- }
+ case '<':
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ visited = true;
+ top: for (;;) {
+ switch (c = signature.charAt(pos)) {
+ case '>':
+ break top;
+ case '*':
+ ++pos;
+ v.visitTypeArgument();
+ break;
+ case '+':
+ case '-':
+ pos = parseType(signature, pos + 1,
+ v.visitTypeArgument(c));
+ break;
+ default:
+ pos = parseType(signature, pos,
+ v.visitTypeArgument('='));
+ break;
+ }
}
}
+ }
}
}
}
diff --git a/src/asm/scala/tools/asm/signature/SignatureVisitor.java b/src/asm/scala/tools/asm/signature/SignatureVisitor.java
index 2fc364e374..f38f81f53b 100644
--- a/src/asm/scala/tools/asm/signature/SignatureVisitor.java
+++ b/src/asm/scala/tools/asm/signature/SignatureVisitor.java
@@ -35,21 +35,21 @@ import scala.tools.asm.Opcodes;
* A visitor to visit a generic signature. The methods of this interface must be
* called in one of the three following orders (the last one is the only valid
* order for a {@link SignatureVisitor} that is returned by a method of this
- * interface): <ul> <li><i>ClassSignature</i> = (
- * <tt>visitFormalTypeParameter</tt>
- * <tt>visitClassBound</tt>?
- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt>
- * <tt>visitInterface</tt>* )</li>
+ * interface):
+ * <ul>
+ * <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
+ * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
+ * <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
- * <tt>visitClassBound</tt>?
- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>*
- * <tt>visitReturnType</tt>
- * <tt>visitExceptionType</tt>* )</li> <li><i>TypeSignature</i> =
- * <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> |
- * <tt>visitArrayType</tt> | (
+ * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
+ * <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
+ * <tt>visitExceptionType</tt>* )</li>
+ * <li><i>TypeSignature</i> = <tt>visitBaseType</tt> |
+ * <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | (
* <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
- * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )*
- * <tt>visitEnd</tt> ) )</li> </ul>
+ * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt>
+ * ) )</li>
+ * </ul>
*
* @author Thomas Hallgren
* @author Eric Bruneton
@@ -80,8 +80,9 @@ public abstract class SignatureVisitor {
/**
* Constructs a new {@link SignatureVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public SignatureVisitor(final int api) {
this.api = api;
@@ -90,7 +91,8 @@ public abstract class SignatureVisitor {
/**
* Visits a formal type parameter.
*
- * @param name the name of the formal parameter.
+ * @param name
+ * the name of the formal parameter.
*/
public void visitFormalTypeParameter(String name) {
}
@@ -162,8 +164,9 @@ public abstract class SignatureVisitor {
/**
* Visits a signature corresponding to a primitive type.
*
- * @param descriptor the descriptor of the primitive type, or 'V' for
- * <tt>void</tt>.
+ * @param descriptor
+ * the descriptor of the primitive type, or 'V' for <tt>void</tt>
+ * .
*/
public void visitBaseType(char descriptor) {
}
@@ -171,7 +174,8 @@ public abstract class SignatureVisitor {
/**
* Visits a signature corresponding to a type variable.
*
- * @param name the name of the type variable.
+ * @param name
+ * the name of the type variable.
*/
public void visitTypeVariable(String name) {
}
@@ -190,7 +194,8 @@ public abstract class SignatureVisitor {
* Starts the visit of a signature corresponding to a class or interface
* type.
*
- * @param name the internal name of the class or interface.
+ * @param name
+ * the internal name of the class or interface.
*/
public void visitClassType(String name) {
}
@@ -198,7 +203,8 @@ public abstract class SignatureVisitor {
/**
* Visits an inner class.
*
- * @param name the local name of the inner class in its enclosing class.
+ * @param name
+ * the local name of the inner class in its enclosing class.
*/
public void visitInnerClassType(String name) {
}
@@ -213,7 +219,8 @@ public abstract class SignatureVisitor {
/**
* Visits a type argument of the last visited class or inner class type.
*
- * @param wildcard '+', '-' or '='.
+ * @param wildcard
+ * '+', '-' or '='.
* @return a non null visitor to visit the signature of the type argument.
*/
public SignatureVisitor visitTypeArgument(char wildcard) {
diff --git a/src/asm/scala/tools/asm/signature/SignatureWriter.java b/src/asm/scala/tools/asm/signature/SignatureWriter.java
index a59fdfde2b..ebf4fe07b4 100644
--- a/src/asm/scala/tools/asm/signature/SignatureWriter.java
+++ b/src/asm/scala/tools/asm/signature/SignatureWriter.java
@@ -224,4 +224,4 @@ public class SignatureWriter extends SignatureVisitor {
}
argumentStack /= 2;
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/AbstractInsnNode.java b/src/asm/scala/tools/asm/tree/AbstractInsnNode.java
index 471f842ffc..411eead3c7 100644
--- a/src/asm/scala/tools/asm/tree/AbstractInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/AbstractInsnNode.java
@@ -148,7 +148,8 @@ public abstract class AbstractInsnNode {
/**
* Constructs a new {@link AbstractInsnNode}.
*
- * @param opcode the opcode of the instruction to be constructed.
+ * @param opcode
+ * the opcode of the instruction to be constructed.
*/
protected AbstractInsnNode(final int opcode) {
this.opcode = opcode;
@@ -197,38 +198,47 @@ public abstract class AbstractInsnNode {
/**
* Makes the given code visitor visit this instruction.
*
- * @param cv a code visitor.
+ * @param cv
+ * a code visitor.
*/
public abstract void accept(final MethodVisitor cv);
/**
* Returns a copy of this instruction.
*
- * @param labels a map from LabelNodes to cloned LabelNodes.
+ * @param labels
+ * a map from LabelNodes to cloned LabelNodes.
* @return a copy of this instruction. The returned instruction does not
* belong to any {@link InsnList}.
*/
- public abstract AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels);
+ public abstract AbstractInsnNode clone(
+ final Map<LabelNode, LabelNode> labels);
/**
* Returns the clone of the given label.
*
- * @param label a label.
- * @param map a map from LabelNodes to cloned LabelNodes.
+ * @param label
+ * a label.
+ * @param map
+ * a map from LabelNodes to cloned LabelNodes.
* @return the clone of the given label.
*/
- static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> map) {
+ static LabelNode clone(final LabelNode label,
+ final Map<LabelNode, LabelNode> map) {
return map.get(label);
}
/**
* Returns the clones of the given labels.
*
- * @param labels a list of labels.
- * @param map a map from LabelNodes to cloned LabelNodes.
+ * @param labels
+ * a list of labels.
+ * @param map
+ * a map from LabelNodes to cloned LabelNodes.
* @return the clones of the given labels.
*/
- static LabelNode[] clone(final List<LabelNode> labels, final Map<LabelNode, LabelNode> map) {
+ static LabelNode[] clone(final List<LabelNode> labels,
+ final Map<LabelNode, LabelNode> map) {
LabelNode[] clones = new LabelNode[labels.size()];
for (int i = 0; i < clones.length; ++i) {
clones[i] = map.get(labels.get(i));
diff --git a/src/asm/scala/tools/asm/tree/AnnotationNode.java b/src/asm/scala/tools/asm/tree/AnnotationNode.java
index 9f132550e6..1f4beef9f7 100644
--- a/src/asm/scala/tools/asm/tree/AnnotationNode.java
+++ b/src/asm/scala/tools/asm/tree/AnnotationNode.java
@@ -52,11 +52,11 @@ public class AnnotationNode extends AnnotationVisitor {
* as two consecutive elements in the list. The name is a {@link String},
* and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
* {@link Short}, {@link Integer}, {@link Long}, {@link Float},
- * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
+ * {@link Double}, {@link String} or {@link scala.tools.asm.Type}, or an
* two elements String array (for enumeration values), a
* {@link AnnotationNode}, or a {@link List} of values of one of the
- * preceding types. The list may be <tt>null</tt> if there is no name
- * value pair.
+ * preceding types. The list may be <tt>null</tt> if there is no name value
+ * pair.
*/
public List<Object> values;
@@ -65,7 +65,8 @@ public class AnnotationNode extends AnnotationVisitor {
* constructor</i>. Instead, they must use the
* {@link #AnnotationNode(int, String)} version.
*
- * @param desc the class descriptor of the annotation class.
+ * @param desc
+ * the class descriptor of the annotation class.
*/
public AnnotationNode(final String desc) {
this(Opcodes.ASM4, desc);
@@ -74,9 +75,11 @@ public class AnnotationNode extends AnnotationVisitor {
/**
* Constructs a new {@link AnnotationNode}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param desc the class descriptor of the annotation class.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param desc
+ * the class descriptor of the annotation class.
*/
public AnnotationNode(final int api, final String desc) {
super(api);
@@ -86,7 +89,8 @@ public class AnnotationNode extends AnnotationVisitor {
/**
* Constructs a new {@link AnnotationNode} to visit an array value.
*
- * @param values where the visited values must be stored.
+ * @param values
+ * where the visited values must be stored.
*/
AnnotationNode(final List<Object> values) {
super(Opcodes.ASM4);
@@ -109,11 +113,8 @@ public class AnnotationNode extends AnnotationVisitor {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
@@ -124,10 +125,8 @@ public class AnnotationNode extends AnnotationVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String name,
- final String desc)
- {
+ public AnnotationVisitor visitAnnotation(final String name,
+ final String desc) {
if (values == null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1);
}
@@ -166,7 +165,8 @@ public class AnnotationNode extends AnnotationVisitor {
* recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
*
- * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+ * @param api
+ * an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/
public void check(final int api) {
// nothing to do
@@ -175,7 +175,8 @@ public class AnnotationNode extends AnnotationVisitor {
/**
* Makes the given visitor visit this annotation.
*
- * @param av an annotation visitor. Maybe <tt>null</tt>.
+ * @param av
+ * an annotation visitor. Maybe <tt>null</tt>.
*/
public void accept(final AnnotationVisitor av) {
if (av != null) {
@@ -193,15 +194,15 @@ public class AnnotationNode extends AnnotationVisitor {
/**
* Makes the given visitor visit a given annotation value.
*
- * @param av an annotation visitor. Maybe <tt>null</tt>.
- * @param name the value name.
- * @param value the actual value.
+ * @param av
+ * an annotation visitor. Maybe <tt>null</tt>.
+ * @param name
+ * the value name.
+ * @param value
+ * the actual value.
*/
- static void accept(
- final AnnotationVisitor av,
- final String name,
- final Object value)
- {
+ static void accept(final AnnotationVisitor av, final String name,
+ final Object value) {
if (av != null) {
if (value instanceof String[]) {
String[] typeconst = (String[]) value;
diff --git a/src/asm/scala/tools/asm/tree/ClassNode.java b/src/asm/scala/tools/asm/tree/ClassNode.java
index 64effae698..c3d999985a 100644
--- a/src/asm/scala/tools/asm/tree/ClassNode.java
+++ b/src/asm/scala/tools/asm/tree/ClassNode.java
@@ -53,33 +53,33 @@ public class ClassNode extends ClassVisitor {
public int version;
/**
- * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This
+ * The class's access flags (see {@link scala.tools.asm.Opcodes}). This
* field also indicates if the class is deprecated.
*/
public int access;
/**
* The internal name of the class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}).
*/
public String name;
/**
- * The signature of the class. Mayt be <tt>null</tt>.
+ * The signature of the class. May be <tt>null</tt>.
*/
public String signature;
/**
* The internal of name of the super class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For
- * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
- * but only for the {@link Object} class.
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}). For
+ * interfaces, the super class is {@link Object}. May be <tt>null</tt>, but
+ * only for the {@link Object} class.
*/
public String superName;
/**
* The internal names of the class's interfaces (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}). This
* list is a list of {@link String} objects.
*/
public List<String> interfaces;
@@ -91,7 +91,7 @@ public class ClassNode extends ClassVisitor {
public String sourceFile;
/**
- * Debug information to compute the correspondance between source and
+ * Debug information to compute the correspondence between source and
* compiled elements of the class. May be <tt>null</tt>.
*/
public String sourceDebug;
@@ -109,8 +109,8 @@ public class ClassNode extends ClassVisitor {
public String outerMethod;
/**
- * The descriptor of the method that contains the class, or <tt>null</tt>
- * if the class is not enclosed in a method.
+ * The descriptor of the method that contains the class, or <tt>null</tt> if
+ * the class is not enclosed in a method.
*/
public String outerMethodDesc;
@@ -118,7 +118,7 @@ public class ClassNode extends ClassVisitor {
* The runtime visible annotations of this class. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
@@ -127,7 +127,7 @@ public class ClassNode extends ClassVisitor {
* The runtime invisible annotations of this class. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
@@ -136,7 +136,7 @@ public class ClassNode extends ClassVisitor {
* The non standard attributes of this class. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.Attribute
+ * @associates scala.tools.asm.Attribute
*/
public List<Attribute> attrs;
@@ -144,7 +144,7 @@ public class ClassNode extends ClassVisitor {
* Informations about the inner classes of this class. This list is a list
* of {@link InnerClassNode} objects.
*
- * @associates org.objectweb.asm.tree.InnerClassNode
+ * @associates scala.tools.asm.tree.InnerClassNode
*/
public List<InnerClassNode> innerClasses;
@@ -152,7 +152,7 @@ public class ClassNode extends ClassVisitor {
* The fields of this class. This list is a list of {@link FieldNode}
* objects.
*
- * @associates org.objectweb.asm.tree.FieldNode
+ * @associates scala.tools.asm.tree.FieldNode
*/
public List<FieldNode> fields;
@@ -160,7 +160,7 @@ public class ClassNode extends ClassVisitor {
* The methods of this class. This list is a list of {@link MethodNode}
* objects.
*
- * @associates org.objectweb.asm.tree.MethodNode
+ * @associates scala.tools.asm.tree.MethodNode
*/
public List<MethodNode> methods;
@@ -176,8 +176,9 @@ public class ClassNode extends ClassVisitor {
/**
* Constructs a new {@link ClassNode}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public ClassNode(final int api) {
super(api);
@@ -192,14 +193,9 @@ public class ClassNode extends ClassVisitor {
// ------------------------------------------------------------------------
@Override
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
this.version = version;
this.access = access;
this.name = name;
@@ -217,21 +213,16 @@ public class ClassNode extends ClassVisitor {
}
@Override
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
outerClass = owner;
outerMethod = name;
outerMethodDesc = desc;
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
@@ -256,44 +247,25 @@ public class ClassNode extends ClassVisitor {
}
@Override
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
- InnerClassNode icn = new InnerClassNode(name,
- outerName,
- innerName,
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
+ InnerClassNode icn = new InnerClassNode(name, outerName, innerName,
access);
innerClasses.add(icn);
}
@Override
- public FieldVisitor visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
FieldNode fn = new FieldNode(access, name, desc, signature, value);
fields.add(fn);
return fn;
}
@Override
- public MethodVisitor visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
- MethodNode mn = new MethodNode(access,
- name,
- desc,
- signature,
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ MethodNode mn = new MethodNode(access, name, desc, signature,
exceptions);
methods.add(mn);
return mn;
@@ -313,7 +285,8 @@ public class ClassNode extends ClassVisitor {
* contain elements that were introduced in more recent versions of the ASM
* API than the given version.
*
- * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+ * @param api
+ * an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/
public void check(final int api) {
// nothing to do
@@ -322,7 +295,8 @@ public class ClassNode extends ClassVisitor {
/**
* Makes the given class visitor visit this class.
*
- * @param cv a class visitor.
+ * @param cv
+ * a class visitor.
*/
public void accept(final ClassVisitor cv) {
// visits header
diff --git a/src/asm/scala/tools/asm/tree/FieldInsnNode.java b/src/asm/scala/tools/asm/tree/FieldInsnNode.java
index 6b7a6a142a..0c94f18adf 100644
--- a/src/asm/scala/tools/asm/tree/FieldInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/FieldInsnNode.java
@@ -43,7 +43,7 @@ public class FieldInsnNode extends AbstractInsnNode {
/**
* The internal name of the field's owner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}).
*/
public String owner;
@@ -53,26 +53,27 @@ public class FieldInsnNode extends AbstractInsnNode {
public String name;
/**
- * The field's descriptor (see {@link org.objectweb.asm.Type}).
+ * The field's descriptor (see {@link scala.tools.asm.Type}).
*/
public String desc;
/**
* Constructs a new {@link FieldInsnNode}.
*
- * @param opcode the opcode of the type instruction to be constructed. This
- * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
- * @param owner the internal name of the field's owner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param opcode
+ * the opcode of the type instruction to be constructed. This
+ * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner
+ * the internal name of the field's owner class (see
+ * {@link scala.tools.asm.Type#getInternalName()
+ * getInternalName}).
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link scala.tools.asm.Type}).
*/
- public FieldInsnNode(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public FieldInsnNode(final int opcode, final String owner,
+ final String name, final String desc) {
super(opcode);
this.owner = owner;
this.name = name;
@@ -82,8 +83,9 @@ public class FieldInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be GETSTATIC,
- * PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param opcode
+ * the new instruction opcode. This opcode must be GETSTATIC,
+ * PUTSTATIC, GETFIELD or PUTFIELD.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
diff --git a/src/asm/scala/tools/asm/tree/FieldNode.java b/src/asm/scala/tools/asm/tree/FieldNode.java
index 9a1e17033c..61b614ec59 100644
--- a/src/asm/scala/tools/asm/tree/FieldNode.java
+++ b/src/asm/scala/tools/asm/tree/FieldNode.java
@@ -46,7 +46,7 @@ import scala.tools.asm.Opcodes;
public class FieldNode extends FieldVisitor {
/**
- * The field's access flags (see {@link org.objectweb.asm.Opcodes}). This
+ * The field's access flags (see {@link scala.tools.asm.Opcodes}). This
* field also indicates if the field is synthetic and/or deprecated.
*/
public int access;
@@ -57,7 +57,7 @@ public class FieldNode extends FieldVisitor {
public String name;
/**
- * The field's descriptor (see {@link org.objectweb.asm.Type}).
+ * The field's descriptor (see {@link scala.tools.asm.Type}).
*/
public String desc;
@@ -67,8 +67,8 @@ public class FieldNode extends FieldVisitor {
public String signature;
/**
- * The field's initial value. This field, which may be <tt>null</tt> if
- * the field does not have an initial value, must be an {@link Integer}, a
+ * The field's initial value. This field, which may be <tt>null</tt> if the
+ * field does not have an initial value, must be an {@link Integer}, a
* {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
*/
public Object value;
@@ -77,7 +77,7 @@ public class FieldNode extends FieldVisitor {
* The runtime visible annotations of this field. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
@@ -86,7 +86,7 @@ public class FieldNode extends FieldVisitor {
* The runtime invisible annotations of this field. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
@@ -95,7 +95,7 @@ public class FieldNode extends FieldVisitor {
* The non standard attributes of this field. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.Attribute
+ * @associates scala.tools.asm.Attribute
*/
public List<Attribute> attrs;
@@ -104,25 +104,25 @@ public class FieldNode extends FieldVisitor {
* constructor</i>. Instead, they must use the
* {@link #FieldNode(int, int, String, String, String, Object)} version.
*
- * @param access the field's access flags (see
- * {@link org.objectweb.asm.Opcodes}). This parameter also indicates
- * if the field is synthetic and/or deprecated.
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link org.objectweb.asm.Type
- * Type}).
- * @param signature the field's signature.
- * @param value the field's initial value. This parameter, which may be
- * <tt>null</tt> if the field does not have an initial value, must be
- * an {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} or a {@link String}.
+ * @param access
+ * the field's access flags (see
+ * {@link scala.tools.asm.Opcodes}). This parameter also
+ * indicates if the field is synthetic and/or deprecated.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link scala.tools.asm.Type
+ * Type}).
+ * @param signature
+ * the field's signature.
+ * @param value
+ * the field's initial value. This parameter, which may be
+ * <tt>null</tt> if the field does not have an initial value,
+ * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String}.
*/
- public FieldNode(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public FieldNode(final int access, final String name, final String desc,
+ final String signature, final Object value) {
this(Opcodes.ASM4, access, name, desc, signature, value);
}
@@ -131,28 +131,28 @@ public class FieldNode extends FieldVisitor {
* constructor</i>. Instead, they must use the
* {@link #FieldNode(int, int, String, String, String, Object)} version.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param access the field's access flags (see
- * {@link org.objectweb.asm.Opcodes}). This parameter also indicates
- * if the field is synthetic and/or deprecated.
- * @param name the field's name.
- * @param desc the field's descriptor (see {@link org.objectweb.asm.Type
- * Type}).
- * @param signature the field's signature.
- * @param value the field's initial value. This parameter, which may be
- * <tt>null</tt> if the field does not have an initial value, must be
- * an {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} or a {@link String}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param access
+ * the field's access flags (see
+ * {@link scala.tools.asm.Opcodes}). This parameter also
+ * indicates if the field is synthetic and/or deprecated.
+ * @param name
+ * the field's name.
+ * @param desc
+ * the field's descriptor (see {@link scala.tools.asm.Type
+ * Type}).
+ * @param signature
+ * the field's signature.
+ * @param value
+ * the field's initial value. This parameter, which may be
+ * <tt>null</tt> if the field does not have an initial value,
+ * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String}.
*/
- public FieldNode(
- final int api,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public FieldNode(final int api, final int access, final String name,
+ final String desc, final String signature, final Object value) {
super(api);
this.access = access;
this.name = name;
@@ -166,10 +166,8 @@ public class FieldNode extends FieldVisitor {
// ------------------------------------------------------------------------
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
@@ -207,7 +205,8 @@ public class FieldNode extends FieldVisitor {
* contain elements that were introduced in more recent versions of the ASM
* API than the given version.
*
- * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+ * @param api
+ * an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/
public void check(final int api) {
// nothing to do
@@ -216,7 +215,8 @@ public class FieldNode extends FieldVisitor {
/**
* Makes the given class visitor visit this field.
*
- * @param cv a class visitor.
+ * @param cv
+ * a class visitor.
*/
public void accept(final ClassVisitor cv) {
FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
diff --git a/src/asm/scala/tools/asm/tree/FrameNode.java b/src/asm/scala/tools/asm/tree/FrameNode.java
index 66825de0ac..f13fc66749 100644
--- a/src/asm/scala/tools/asm/tree/FrameNode.java
+++ b/src/asm/scala/tools/asm/tree/FrameNode.java
@@ -45,8 +45,9 @@ import scala.tools.asm.Opcodes;
* the target of a jump instruction, or that starts an exception handler block.
* The stack map frame types must describe the values of the local variables and
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
- * <br> (*) this is mandatory only for classes whose version is greater than or
- * equal to {@link Opcodes#V1_6 V1_6}.
+ * <br>
+ * (*) this is mandatory only for classes whose version is greater than or equal
+ * to {@link Opcodes#V1_6 V1_6}.
*
* @author Eric Bruneton
*/
@@ -83,48 +84,48 @@ public class FrameNode extends AbstractInsnNode {
/**
* Constructs a new {@link FrameNode}.
*
- * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for
- * expanded frames, or {@link Opcodes#F_FULL},
- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
- * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
- * {@link Opcodes#F_SAME1} for compressed frames.
- * @param nLocal number of local variables of this stack map frame.
- * @param local the types of the local variables of this stack map frame.
- * Elements of this list can be Integer, String or LabelNode objects
- * (for primitive, reference and uninitialized types respectively -
- * see {@link MethodVisitor}).
- * @param nStack number of operand stack elements of this stack map frame.
- * @param stack the types of the operand stack elements of this stack map
- * frame. Elements of this list can be Integer, String or LabelNode
- * objects (for primitive, reference and uninitialized types
- * respectively - see {@link MethodVisitor}).
+ * @param type
+ * the type of this frame. Must be {@link Opcodes#F_NEW} for
+ * expanded frames, or {@link Opcodes#F_FULL},
+ * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
+ * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
+ * {@link Opcodes#F_SAME1} for compressed frames.
+ * @param nLocal
+ * number of local variables of this stack map frame.
+ * @param local
+ * the types of the local variables of this stack map frame.
+ * Elements of this list can be Integer, String or LabelNode
+ * objects (for primitive, reference and uninitialized types
+ * respectively - see {@link MethodVisitor}).
+ * @param nStack
+ * number of operand stack elements of this stack map frame.
+ * @param stack
+ * the types of the operand stack elements of this stack map
+ * frame. Elements of this list can be Integer, String or
+ * LabelNode objects (for primitive, reference and uninitialized
+ * types respectively - see {@link MethodVisitor}).
*/
- public FrameNode(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public FrameNode(final int type, final int nLocal, final Object[] local,
+ final int nStack, final Object[] stack) {
super(-1);
this.type = type;
switch (type) {
- case Opcodes.F_NEW:
- case Opcodes.F_FULL:
- this.local = asList(nLocal, local);
- this.stack = asList(nStack, stack);
- break;
- case Opcodes.F_APPEND:
- this.local = asList(nLocal, local);
- break;
- case Opcodes.F_CHOP:
- this.local = Arrays.asList(new Object[nLocal]);
- break;
- case Opcodes.F_SAME:
- break;
- case Opcodes.F_SAME1:
- this.stack = asList(1, stack);
- break;
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ this.local = asList(nLocal, local);
+ this.stack = asList(nStack, stack);
+ break;
+ case Opcodes.F_APPEND:
+ this.local = asList(nLocal, local);
+ break;
+ case Opcodes.F_CHOP:
+ this.local = Arrays.asList(new Object[nLocal]);
+ break;
+ case Opcodes.F_SAME:
+ break;
+ case Opcodes.F_SAME1:
+ this.stack = asList(1, stack);
+ break;
}
}
@@ -136,31 +137,29 @@ public class FrameNode extends AbstractInsnNode {
/**
* Makes the given visitor visit this stack map frame.
*
- * @param mv a method visitor.
+ * @param mv
+ * a method visitor.
*/
@Override
public void accept(final MethodVisitor mv) {
switch (type) {
- case Opcodes.F_NEW:
- case Opcodes.F_FULL:
- mv.visitFrame(type,
- local.size(),
- asArray(local),
- stack.size(),
- asArray(stack));
- break;
- case Opcodes.F_APPEND:
- mv.visitFrame(type, local.size(), asArray(local), 0, null);
- break;
- case Opcodes.F_CHOP:
- mv.visitFrame(type, local.size(), null, 0, null);
- break;
- case Opcodes.F_SAME:
- mv.visitFrame(type, 0, null, 0, null);
- break;
- case Opcodes.F_SAME1:
- mv.visitFrame(type, 0, null, 1, asArray(stack));
- break;
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ mv.visitFrame(type, local.size(), asArray(local), stack.size(),
+ asArray(stack));
+ break;
+ case Opcodes.F_APPEND:
+ mv.visitFrame(type, local.size(), asArray(local), 0, null);
+ break;
+ case Opcodes.F_CHOP:
+ mv.visitFrame(type, local.size(), null, 0, null);
+ break;
+ case Opcodes.F_SAME:
+ mv.visitFrame(type, 0, null, 0, null);
+ break;
+ case Opcodes.F_SAME1:
+ mv.visitFrame(type, 0, null, 1, asArray(stack));
+ break;
}
}
diff --git a/src/asm/scala/tools/asm/tree/IincInsnNode.java b/src/asm/scala/tools/asm/tree/IincInsnNode.java
index 75ac40884d..f9adf2e38c 100644
--- a/src/asm/scala/tools/asm/tree/IincInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/IincInsnNode.java
@@ -54,8 +54,10 @@ public class IincInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link IincInsnNode}.
*
- * @param var index of the local variable to be incremented.
- * @param incr increment amount to increment the local variable by.
+ * @param var
+ * index of the local variable to be incremented.
+ * @param incr
+ * increment amount to increment the local variable by.
*/
public IincInsnNode(final int var, final int incr) {
super(Opcodes.IINC);
@@ -77,4 +79,4 @@ public class IincInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new IincInsnNode(var, incr);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/InnerClassNode.java b/src/asm/scala/tools/asm/tree/InnerClassNode.java
index 4579488921..aa3810c759 100644
--- a/src/asm/scala/tools/asm/tree/InnerClassNode.java
+++ b/src/asm/scala/tools/asm/tree/InnerClassNode.java
@@ -40,14 +40,14 @@ public class InnerClassNode {
/**
* The internal name of an inner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}).
*/
public String name;
/**
* The internal name of the class to which the inner class belongs (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May
- * be <tt>null</tt>.
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}). May be
+ * <tt>null</tt>.
*/
public String outerName;
@@ -66,24 +66,23 @@ public class InnerClassNode {
/**
* Constructs a new {@link InnerClassNode}.
*
- * @param name the internal name of an inner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
- * @param outerName the internal name of the class to which the inner class
- * belongs (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
- * May be <tt>null</tt>.
- * @param innerName the (simple) name of the inner class inside its
- * enclosing class. May be <tt>null</tt> for anonymous inner
- * classes.
- * @param access the access flags of the inner class as originally declared
- * in the enclosing class.
+ * @param name
+ * the internal name of an inner class (see
+ * {@link scala.tools.asm.Type#getInternalName()
+ * getInternalName}).
+ * @param outerName
+ * the internal name of the class to which the inner class
+ * belongs (see {@link scala.tools.asm.Type#getInternalName()
+ * getInternalName}). May be <tt>null</tt>.
+ * @param innerName
+ * the (simple) name of the inner class inside its enclosing
+ * class. May be <tt>null</tt> for anonymous inner classes.
+ * @param access
+ * the access flags of the inner class as originally declared in
+ * the enclosing class.
*/
- public InnerClassNode(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public InnerClassNode(final String name, final String outerName,
+ final String innerName, final int access) {
this.name = name;
this.outerName = outerName;
this.innerName = innerName;
@@ -93,7 +92,8 @@ public class InnerClassNode {
/**
* Makes the given class visitor visit this inner class.
*
- * @param cv a class visitor.
+ * @param cv
+ * a class visitor.
*/
public void accept(final ClassVisitor cv) {
cv.visitInnerClass(name, outerName, innerName, access);
diff --git a/src/asm/scala/tools/asm/tree/InsnList.java b/src/asm/scala/tools/asm/tree/InsnList.java
index dedd3bba73..55d83c2e8b 100644
--- a/src/asm/scala/tools/asm/tree/InsnList.java
+++ b/src/asm/scala/tools/asm/tree/InsnList.java
@@ -73,8 +73,8 @@ public class InsnList {
/**
* Returns the first instruction in this list.
*
- * @return the first instruction in this list, or <tt>null</tt> if the
- * list is empty.
+ * @return the first instruction in this list, or <tt>null</tt> if the list
+ * is empty.
*/
public AbstractInsnNode getFirst() {
return first;
@@ -96,9 +96,11 @@ public class InsnList {
* time it is called. Once the cache is built, this method run in constant
* time. This cache is invalidated by all the methods that modify the list.
*
- * @param index the index of the instruction that must be returned.
+ * @param index
+ * the index of the instruction that must be returned.
* @return the instruction whose index is given.
- * @throws IndexOutOfBoundsException if (index < 0 || index >= size()).
+ * @throws IndexOutOfBoundsException
+ * if (index < 0 || index >= size()).
*/
public AbstractInsnNode get(final int index) {
if (index < 0 || index >= size) {
@@ -111,11 +113,12 @@ public class InsnList {
}
/**
- * Returns <tt>true</tt> if the given instruction belongs to this list.
- * This method always scans the instructions of this list until it finds the
+ * Returns <tt>true</tt> if the given instruction belongs to this list. This
+ * method always scans the instructions of this list until it finds the
* given instruction or reaches the end of the list.
*
- * @param insn an instruction.
+ * @param insn
+ * an instruction.
* @return <tt>true</tt> if the given instruction belongs to this list.
*/
public boolean contains(final AbstractInsnNode insn) {
@@ -133,7 +136,8 @@ public class InsnList {
* constant time. The cache is invalidated by all the methods that modify
* the list.
*
- * @param insn an instruction <i>of this list</i>.
+ * @param insn
+ * an instruction <i>of this list</i>.
* @return the index of the given instruction in this list. <i>The result of
* this method is undefined if the given instruction does not belong
* to this list</i>. Use {@link #contains contains} to test if an
@@ -149,7 +153,8 @@ public class InsnList {
/**
* Makes the given visitor visit all of the instructions in this list.
*
- * @param mv the method visitor that must visit the instructions.
+ * @param mv
+ * the method visitor that must visit the instructions.
*/
public void accept(final MethodVisitor mv) {
AbstractInsnNode insn = first;
@@ -198,9 +203,11 @@ public class InsnList {
/**
* Replaces an instruction of this list with another instruction.
*
- * @param location an instruction <i>of this list</i>.
- * @param insn another instruction, <i>which must not belong to any
- * {@link InsnList}</i>.
+ * @param location
+ * an instruction <i>of this list</i>.
+ * @param insn
+ * another instruction, <i>which must not belong to any
+ * {@link InsnList}</i>.
*/
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
AbstractInsnNode next = location.next;
@@ -232,8 +239,9 @@ public class InsnList {
/**
* Adds the given instruction to the end of this list.
*
- * @param insn an instruction, <i>which must not belong to any
- * {@link InsnList}</i>.
+ * @param insn
+ * an instruction, <i>which must not belong to any
+ * {@link InsnList}</i>.
*/
public void add(final AbstractInsnNode insn) {
++size;
@@ -252,8 +260,9 @@ public class InsnList {
/**
* Adds the given instructions to the end of this list.
*
- * @param insns an instruction list, which is cleared during the process.
- * This list must be different from 'this'.
+ * @param insns
+ * an instruction list, which is cleared during the process. This
+ * list must be different from 'this'.
*/
public void add(final InsnList insns) {
if (insns.size == 0) {
@@ -276,8 +285,9 @@ public class InsnList {
/**
* Inserts the given instruction at the begining of this list.
*
- * @param insn an instruction, <i>which must not belong to any
- * {@link InsnList}</i>.
+ * @param insn
+ * an instruction, <i>which must not belong to any
+ * {@link InsnList}</i>.
*/
public void insert(final AbstractInsnNode insn) {
++size;
@@ -296,8 +306,9 @@ public class InsnList {
/**
* Inserts the given instructions at the begining of this list.
*
- * @param insns an instruction list, which is cleared during the process.
- * This list must be different from 'this'.
+ * @param insns
+ * an instruction list, which is cleared during the process. This
+ * list must be different from 'this'.
*/
public void insert(final InsnList insns) {
if (insns.size == 0) {
@@ -320,12 +331,15 @@ public class InsnList {
/**
* Inserts the given instruction after the specified instruction.
*
- * @param location an instruction <i>of this list</i> after which insn must be
- * inserted.
- * @param insn the instruction to be inserted, <i>which must not belong to
- * any {@link InsnList}</i>.
+ * @param location
+ * an instruction <i>of this list</i> after which insn must be
+ * inserted.
+ * @param insn
+ * the instruction to be inserted, <i>which must not belong to
+ * any {@link InsnList}</i>.
*/
- public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) {
+ public void insert(final AbstractInsnNode location,
+ final AbstractInsnNode insn) {
++size;
AbstractInsnNode next = location.next;
if (next == null) {
@@ -343,10 +357,12 @@ public class InsnList {
/**
* Inserts the given instructions after the specified instruction.
*
- * @param location an instruction <i>of this list</i> after which the
- * instructions must be inserted.
- * @param insns the instruction list to be inserted, which is cleared during
- * the process. This list must be different from 'this'.
+ * @param location
+ * an instruction <i>of this list</i> after which the
+ * instructions must be inserted.
+ * @param insns
+ * the instruction list to be inserted, which is cleared during
+ * the process. This list must be different from 'this'.
*/
public void insert(final AbstractInsnNode location, final InsnList insns) {
if (insns.size == 0) {
@@ -371,12 +387,15 @@ public class InsnList {
/**
* Inserts the given instruction before the specified instruction.
*
- * @param location an instruction <i>of this list</i> before which insn must be
- * inserted.
- * @param insn the instruction to be inserted, <i>which must not belong to
- * any {@link InsnList}</i>.
+ * @param location
+ * an instruction <i>of this list</i> before which insn must be
+ * inserted.
+ * @param insn
+ * the instruction to be inserted, <i>which must not belong to
+ * any {@link InsnList}</i>.
*/
- public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) {
+ public void insertBefore(final AbstractInsnNode location,
+ final AbstractInsnNode insn) {
++size;
AbstractInsnNode prev = location.prev;
if (prev == null) {
@@ -394,37 +413,39 @@ public class InsnList {
/**
* Inserts the given instructions before the specified instruction.
*
- * @param location an instruction <i>of this list</i> before which the instructions
- * must be inserted.
- * @param insns the instruction list to be inserted, which is cleared during
- * the process. This list must be different from 'this'.
+ * @param location
+ * an instruction <i>of this list</i> before which the
+ * instructions must be inserted.
+ * @param insns
+ * the instruction list to be inserted, which is cleared during
+ * the process. This list must be different from 'this'.
*/
- public void insertBefore(final AbstractInsnNode location, final InsnList insns) {
+ public void insertBefore(final AbstractInsnNode location,
+ final InsnList insns) {
if (insns.size == 0) {
return;
}
size += insns.size;
AbstractInsnNode ifirst = insns.first;
AbstractInsnNode ilast = insns.last;
- AbstractInsnNode prev = location .prev;
+ AbstractInsnNode prev = location.prev;
if (prev == null) {
first = ifirst;
} else {
prev.next = ifirst;
}
- location .prev = ilast;
- ilast.next = location ;
+ location.prev = ilast;
+ ilast.next = location;
ifirst.prev = prev;
cache = null;
insns.removeAll(false);
}
-
-
/**
* Removes the given instruction from this list.
*
- * @param insn the instruction <i>of this list</i> that must be removed.
+ * @param insn
+ * the instruction <i>of this list</i> that must be removed.
*/
public void remove(final AbstractInsnNode insn) {
--size;
@@ -456,8 +477,9 @@ public class InsnList {
/**
* Removes all of the instructions of this list.
*
- * @param mark if the instructions must be marked as no longer belonging to
- * any {@link InsnList}.
+ * @param mark
+ * if the instructions must be marked as no longer belonging to
+ * any {@link InsnList}.
*/
void removeAll(final boolean mark) {
if (mark) {
@@ -499,14 +521,14 @@ public class InsnList {
}
// this class is not generified because it will create bridges
- private final class InsnListIterator implements ListIterator/*<AbstractInsnNode>*/ {
+ private final class InsnListIterator implements ListIterator {
AbstractInsnNode next;
AbstractInsnNode prev;
InsnListIterator(int index) {
- if(index==size()) {
+ if (index == size()) {
next = null;
prev = getLast();
} else {
diff --git a/src/asm/scala/tools/asm/tree/InsnNode.java b/src/asm/scala/tools/asm/tree/InsnNode.java
index d4664d23c2..4d5288cafa 100644
--- a/src/asm/scala/tools/asm/tree/InsnNode.java
+++ b/src/asm/scala/tools/asm/tree/InsnNode.java
@@ -43,20 +43,22 @@ public class InsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link InsnNode}.
*
- * @param opcode the opcode of the instruction to be constructed. This
- * opcode must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
- * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
- * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
- * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
- * FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2,
- * DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD,
- * FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
- * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG,
- * ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR,
- * LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F,
- * I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
- * FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
- * MONITORENTER, or MONITOREXIT.
+ * @param opcode
+ * the opcode of the instruction to be constructed. This opcode
+ * must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+ * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+ * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+ * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+ * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+ * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+ * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+ * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+ * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+ * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+ * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+ * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+ * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+ * or MONITOREXIT.
*/
public InsnNode(final int opcode) {
super(opcode);
@@ -70,7 +72,8 @@ public class InsnNode extends AbstractInsnNode {
/**
* Makes the given visitor visit this instruction.
*
- * @param mv a method visitor.
+ * @param mv
+ * a method visitor.
*/
@Override
public void accept(final MethodVisitor mv) {
diff --git a/src/asm/scala/tools/asm/tree/IntInsnNode.java b/src/asm/scala/tools/asm/tree/IntInsnNode.java
index b61270c786..e0aeed4bc8 100644
--- a/src/asm/scala/tools/asm/tree/IntInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/IntInsnNode.java
@@ -48,9 +48,11 @@ public class IntInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link IntInsnNode}.
*
- * @param opcode the opcode of the instruction to be constructed. This
- * opcode must be BIPUSH, SIPUSH or NEWARRAY.
- * @param operand the operand of the instruction to be constructed.
+ * @param opcode
+ * the opcode of the instruction to be constructed. This opcode
+ * must be BIPUSH, SIPUSH or NEWARRAY.
+ * @param operand
+ * the operand of the instruction to be constructed.
*/
public IntInsnNode(final int opcode, final int operand) {
super(opcode);
@@ -60,8 +62,9 @@ public class IntInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be BIPUSH,
- * SIPUSH or NEWARRAY.
+ * @param opcode
+ * the new instruction opcode. This opcode must be BIPUSH, SIPUSH
+ * or NEWARRAY.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
diff --git a/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java b/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java
index d993b5a054..7ee84b875b 100644
--- a/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java
@@ -65,17 +65,17 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link InvokeDynamicInsnNode}.
*
- * @param name invokedynamic name.
- * @param desc invokedynamic descriptor (see {@link org.objectweb.asm.Type}).
- * @param bsm the bootstrap method.
- * @param bsmArgs the boostrap constant arguments.
+ * @param name
+ * invokedynamic name.
+ * @param desc
+ * invokedynamic descriptor (see {@link scala.tools.asm.Type}).
+ * @param bsm
+ * the bootstrap method.
+ * @param bsmArgs
+ * the boostrap constant arguments.
*/
- public InvokeDynamicInsnNode(
- final String name,
- final String desc,
- final Handle bsm,
- final Object... bsmArgs)
- {
+ public InvokeDynamicInsnNode(final String name, final String desc,
+ final Handle bsm, final Object... bsmArgs) {
super(Opcodes.INVOKEDYNAMIC);
this.name = name;
this.desc = desc;
@@ -97,4 +97,4 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/JumpInsnNode.java b/src/asm/scala/tools/asm/tree/JumpInsnNode.java
index 339ebbd2d0..81e1e09deb 100644
--- a/src/asm/scala/tools/asm/tree/JumpInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/JumpInsnNode.java
@@ -50,13 +50,15 @@ public class JumpInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link JumpInsnNode}.
*
- * @param opcode the opcode of the type instruction to be constructed. This
- * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
- * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
- * @param label the operand of the instruction to be constructed. This
- * operand is a label that designates the instruction to which the
- * jump instruction may jump.
+ * @param opcode
+ * the opcode of the type instruction to be constructed. This
+ * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+ * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+ * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label
+ * the operand of the instruction to be constructed. This operand
+ * is a label that designates the instruction to which the jump
+ * instruction may jump.
*/
public JumpInsnNode(final int opcode, final LabelNode label) {
super(opcode);
@@ -66,10 +68,11 @@ public class JumpInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE,
- * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
- * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR,
- * IFNULL or IFNONNULL.
+ * @param opcode
+ * the new instruction opcode. This opcode must be IFEQ, IFNE,
+ * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
+ * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
+ * JSR, IFNULL or IFNONNULL.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
diff --git a/src/asm/scala/tools/asm/tree/LabelNode.java b/src/asm/scala/tools/asm/tree/LabelNode.java
index 523a8d6442..44c48c1160 100644
--- a/src/asm/scala/tools/asm/tree/LabelNode.java
+++ b/src/asm/scala/tools/asm/tree/LabelNode.java
@@ -75,4 +75,4 @@ public class LabelNode extends AbstractInsnNode {
public void resetLabel() {
label = null;
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/LdcInsnNode.java b/src/asm/scala/tools/asm/tree/LdcInsnNode.java
index f8d115acd5..4e328f9b39 100644
--- a/src/asm/scala/tools/asm/tree/LdcInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/LdcInsnNode.java
@@ -44,16 +44,17 @@ public class LdcInsnNode extends AbstractInsnNode {
/**
* The constant to be loaded on the stack. This parameter must be a non null
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
- * {@link String} or a {@link org.objectweb.asm.Type}.
+ * {@link String} or a {@link scala.tools.asm.Type}.
*/
public Object cst;
/**
* Constructs a new {@link LdcInsnNode}.
*
- * @param cst the constant to be loaded on the stack. This parameter must be
- * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
- * {@link Double} or a {@link String}.
+ * @param cst
+ * the constant to be loaded on the stack. This parameter must be
+ * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String}.
*/
public LdcInsnNode(final Object cst) {
super(Opcodes.LDC);
@@ -74,4 +75,4 @@ public class LdcInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new LdcInsnNode(cst);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/LineNumberNode.java b/src/asm/scala/tools/asm/tree/LineNumberNode.java
index acc83c8d30..9947aa70a9 100644
--- a/src/asm/scala/tools/asm/tree/LineNumberNode.java
+++ b/src/asm/scala/tools/asm/tree/LineNumberNode.java
@@ -55,9 +55,11 @@ public class LineNumberNode extends AbstractInsnNode {
/**
* Constructs a new {@link LineNumberNode}.
*
- * @param line a line number. This number refers to the source file from
- * which the class was compiled.
- * @param start the first instruction corresponding to this line number.
+ * @param line
+ * a line number. This number refers to the source file from
+ * which the class was compiled.
+ * @param start
+ * the first instruction corresponding to this line number.
*/
public LineNumberNode(final int line, final LabelNode start) {
super(-1);
diff --git a/src/asm/scala/tools/asm/tree/LocalVariableNode.java b/src/asm/scala/tools/asm/tree/LocalVariableNode.java
index 51cbd3ca00..0d8e27356f 100644
--- a/src/asm/scala/tools/asm/tree/LocalVariableNode.java
+++ b/src/asm/scala/tools/asm/tree/LocalVariableNode.java
@@ -73,24 +73,24 @@ public class LocalVariableNode {
/**
* Constructs a new {@link LocalVariableNode}.
*
- * @param name the name of a local variable.
- * @param desc the type descriptor of this local variable.
- * @param signature the signature of this local variable. May be
- * <tt>null</tt>.
- * @param start the first instruction corresponding to the scope of this
- * local variable (inclusive).
- * @param end the last instruction corresponding to the scope of this local
- * variable (exclusive).
- * @param index the local variable's index.
+ * @param name
+ * the name of a local variable.
+ * @param desc
+ * the type descriptor of this local variable.
+ * @param signature
+ * the signature of this local variable. May be <tt>null</tt>.
+ * @param start
+ * the first instruction corresponding to the scope of this local
+ * variable (inclusive).
+ * @param end
+ * the last instruction corresponding to the scope of this local
+ * variable (exclusive).
+ * @param index
+ * the local variable's index.
*/
- public LocalVariableNode(
- final String name,
- final String desc,
- final String signature,
- final LabelNode start,
- final LabelNode end,
- final int index)
- {
+ public LocalVariableNode(final String name, final String desc,
+ final String signature, final LabelNode start, final LabelNode end,
+ final int index) {
this.name = name;
this.desc = desc;
this.signature = signature;
@@ -102,14 +102,11 @@ public class LocalVariableNode {
/**
* Makes the given visitor visit this local variable declaration.
*
- * @param mv a method visitor.
+ * @param mv
+ * a method visitor.
*/
public void accept(final MethodVisitor mv) {
- mv.visitLocalVariable(name,
- desc,
- signature,
- start.getLabel(),
- end.getLabel(),
- index);
+ mv.visitLocalVariable(name, desc, signature, start.getLabel(),
+ end.getLabel(), index);
}
}
diff --git a/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java b/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java
index 6d0f971c29..d2479b4814 100644
--- a/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java
@@ -64,20 +64,21 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link LookupSwitchInsnNode}.
*
- * @param dflt beginning of the default handler block.
- * @param keys the values of the keys.
- * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
- * the beginning of the handler block for the <tt>keys[i]</tt> key.
+ * @param dflt
+ * beginning of the default handler block.
+ * @param keys
+ * the values of the keys.
+ * @param labels
+ * beginnings of the handler blocks. <tt>labels[i]</tt> is the
+ * beginning of the handler block for the <tt>keys[i]</tt> key.
*/
- public LookupSwitchInsnNode(
- final LabelNode dflt,
- final int[] keys,
- final LabelNode[] labels)
- {
+ public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys,
+ final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt;
this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
- this.labels = new ArrayList<LabelNode>(labels == null ? 0 : labels.length);
+ this.labels = new ArrayList<LabelNode>(labels == null ? 0
+ : labels.length);
if (keys != null) {
for (int i = 0; i < keys.length; ++i) {
this.keys.add(new Integer(keys[i]));
diff --git a/src/asm/scala/tools/asm/tree/MethodInsnNode.java b/src/asm/scala/tools/asm/tree/MethodInsnNode.java
index c3036bc6b4..bf09f556d8 100644
--- a/src/asm/scala/tools/asm/tree/MethodInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/MethodInsnNode.java
@@ -43,7 +43,7 @@ public class MethodInsnNode extends AbstractInsnNode {
/**
* The internal name of the method's owner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * {@link scala.tools.asm.Type#getInternalName() getInternalName}).
*/
public String owner;
@@ -53,27 +53,28 @@ public class MethodInsnNode extends AbstractInsnNode {
public String name;
/**
- * The method's descriptor (see {@link org.objectweb.asm.Type}).
+ * The method's descriptor (see {@link scala.tools.asm.Type}).
*/
public String desc;
/**
* Constructs a new {@link MethodInsnNode}.
*
- * @param opcode the opcode of the type instruction to be constructed. This
- * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
- * INVOKEINTERFACE.
- * @param owner the internal name of the method's owner class (see
- * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param opcode
+ * the opcode of the type instruction to be constructed. This
+ * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+ * INVOKEINTERFACE.
+ * @param owner
+ * the internal name of the method's owner class (see
+ * {@link scala.tools.asm.Type#getInternalName()
+ * getInternalName}).
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link scala.tools.asm.Type}).
*/
- public MethodInsnNode(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public MethodInsnNode(final int opcode, final String owner,
+ final String name, final String desc) {
super(opcode);
this.owner = owner;
this.name = name;
@@ -83,8 +84,9 @@ public class MethodInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be
- * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+ * @param opcode
+ * the new instruction opcode. This opcode must be INVOKEVIRTUAL,
+ * INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
@@ -104,4 +106,4 @@ public class MethodInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new MethodInsnNode(opcode, owner, name, desc);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/MethodNode.java b/src/asm/scala/tools/asm/tree/MethodNode.java
index 70ec39e058..5f9c778e0c 100644
--- a/src/asm/scala/tools/asm/tree/MethodNode.java
+++ b/src/asm/scala/tools/asm/tree/MethodNode.java
@@ -81,7 +81,7 @@ public class MethodNode extends MethodVisitor {
* The runtime visible annotations of this method. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label visible
*/
public List<AnnotationNode> visibleAnnotations;
@@ -90,7 +90,7 @@ public class MethodNode extends MethodVisitor {
* The runtime invisible annotations of this method. This list is a list of
* {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label invisible
*/
public List<AnnotationNode> invisibleAnnotations;
@@ -99,7 +99,7 @@ public class MethodNode extends MethodVisitor {
* The non standard attributes of this method. This list is a list of
* {@link Attribute} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.Attribute
+ * @associates scala.tools.asm.Attribute
*/
public List<Attribute> attrs;
@@ -117,7 +117,7 @@ public class MethodNode extends MethodVisitor {
* The runtime visible parameter annotations of this method. These lists are
* lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label invisible parameters
*/
public List<AnnotationNode>[] visibleParameterAnnotations;
@@ -126,7 +126,7 @@ public class MethodNode extends MethodVisitor {
* The runtime invisible parameter annotations of this method. These lists
* are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
*
- * @associates org.objectweb.asm.tree.AnnotationNode
+ * @associates scala.tools.asm.tree.AnnotationNode
* @label visible parameters
*/
public List<AnnotationNode>[] invisibleParameterAnnotations;
@@ -135,7 +135,7 @@ public class MethodNode extends MethodVisitor {
* The instructions of this method. This list is a list of
* {@link AbstractInsnNode} objects.
*
- * @associates org.objectweb.asm.tree.AbstractInsnNode
+ * @associates scala.tools.asm.tree.AbstractInsnNode
* @label instructions
*/
public InsnList instructions;
@@ -144,7 +144,7 @@ public class MethodNode extends MethodVisitor {
* The try catch blocks of this method. This list is a list of
* {@link TryCatchBlockNode} objects.
*
- * @associates org.objectweb.asm.tree.TryCatchBlockNode
+ * @associates scala.tools.asm.tree.TryCatchBlockNode
*/
public List<TryCatchBlockNode> tryCatchBlocks;
@@ -162,7 +162,7 @@ public class MethodNode extends MethodVisitor {
* The local variables of this method. This list is a list of
* {@link LocalVariableNode} objects. May be <tt>null</tt>
*
- * @associates org.objectweb.asm.tree.LocalVariableNode
+ * @associates scala.tools.asm.tree.LocalVariableNode
*/
public List<LocalVariableNode> localVariables;
@@ -170,7 +170,7 @@ public class MethodNode extends MethodVisitor {
* If the accept method has been called on this object.
*/
private boolean visited;
-
+
/**
* Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not
* use this constructor</i>. Instead, they must use the
@@ -183,8 +183,9 @@ public class MethodNode extends MethodVisitor {
/**
* Constructs an uninitialized {@link MethodNode}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
public MethodNode(final int api) {
super(api);
@@ -196,56 +197,55 @@ public class MethodNode extends MethodVisitor {
* constructor</i>. Instead, they must use the
* {@link #MethodNode(int, int, String, String, String, String[])} version.
*
- * @param access the method's access flags (see {@link Opcodes}). This
- * parameter also indicates if the method is synthetic and/or
- * deprecated.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be <tt>null</tt>.
- * @param exceptions the internal names of the method's exception classes
- * (see {@link Type#getInternalName() getInternalName}). May be
- * <tt>null</tt>.
+ * @param access
+ * the method's access flags (see {@link Opcodes}). This
+ * parameter also indicates if the method is synthetic and/or
+ * deprecated.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type}).
+ * @param signature
+ * the method's signature. May be <tt>null</tt>.
+ * @param exceptions
+ * the internal names of the method's exception classes (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * <tt>null</tt>.
*/
- public MethodNode(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
+ public MethodNode(final int access, final String name, final String desc,
+ final String signature, final String[] exceptions) {
this(Opcodes.ASM4, access, name, desc, signature, exceptions);
}
/**
* Constructs a new {@link MethodNode}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param access the method's access flags (see {@link Opcodes}). This
- * parameter also indicates if the method is synthetic and/or
- * deprecated.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be <tt>null</tt>.
- * @param exceptions the internal names of the method's exception classes
- * (see {@link Type#getInternalName() getInternalName}). May be
- * <tt>null</tt>.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param access
+ * the method's access flags (see {@link Opcodes}). This
+ * parameter also indicates if the method is synthetic and/or
+ * deprecated.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type}).
+ * @param signature
+ * the method's signature. May be <tt>null</tt>.
+ * @param exceptions
+ * the internal names of the method's exception classes (see
+ * {@link Type#getInternalName() getInternalName}). May be
+ * <tt>null</tt>.
*/
- public MethodNode(
- final int api,
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
+ public MethodNode(final int api, final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
super(api);
this.access = access;
this.name = name;
this.desc = desc;
this.signature = signature;
- this.exceptions = new ArrayList<String>(exceptions == null
- ? 0
+ this.exceptions = new ArrayList<String>(exceptions == null ? 0
: exceptions.length);
boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
if (!isAbstract) {
@@ -274,10 +274,8 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleAnnotations == null) {
@@ -294,28 +292,27 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
AnnotationNode an = new AnnotationNode(desc);
if (visible) {
if (visibleParameterAnnotations == null) {
int params = Type.getArgumentTypes(this.desc).length;
- visibleParameterAnnotations = (List<AnnotationNode>[])new List<?>[params];
+ visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
if (visibleParameterAnnotations[parameter] == null) {
- visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+ visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
+ 1);
}
visibleParameterAnnotations[parameter].add(an);
} else {
if (invisibleParameterAnnotations == null) {
int params = Type.getArgumentTypes(this.desc).length;
- invisibleParameterAnnotations = (List<AnnotationNode>[])new List<?>[params];
+ invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
}
if (invisibleParameterAnnotations[parameter] == null) {
- invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+ invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
+ 1);
}
invisibleParameterAnnotations[parameter].add(an);
}
@@ -335,17 +332,10 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
- instructions.add(new FrameNode(type, nLocal, local == null
- ? null
- : getLabelNodes(local), nStack, stack == null
- ? null
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
+ instructions.add(new FrameNode(type, nLocal, local == null ? null
+ : getLabelNodes(local), nStack, stack == null ? null
: getLabelNodes(stack)));
}
@@ -370,32 +360,20 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
instructions.add(new FieldInsnNode(opcode, owner, name, desc));
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
instructions.add(new MethodInsnNode(opcode, owner, name, desc));
}
@Override
- public void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
}
@@ -420,26 +398,16 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
- instructions.add(new TableSwitchInsnNode(min,
- max,
- getLabelNode(dflt),
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
+ instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt),
getLabelNodes(labels)));
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
- instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt),
- keys,
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
+ instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
getLabelNodes(labels)));
}
@@ -449,33 +417,18 @@ public class MethodNode extends MethodVisitor {
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
- getLabelNode(end),
- getLabelNode(handler),
- type));
+ getLabelNode(end), getLabelNode(handler), type));
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
- localVariables.add(new LocalVariableNode(name,
- desc,
- signature,
- getLabelNode(start),
- getLabelNode(end),
- index));
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
+ localVariables.add(new LocalVariableNode(name, desc, signature,
+ getLabelNode(start), getLabelNode(end), index));
}
@Override
@@ -499,12 +452,13 @@ public class MethodNode extends MethodVisitor {
* the {@link Label#info} field to store associations between labels and
* label nodes.
*
- * @param l a Label.
+ * @param l
+ * a Label.
* @return the LabelNode corresponding to l.
*/
protected LabelNode getLabelNode(final Label l) {
if (!(l.info instanceof LabelNode)) {
- l.info = new LabelNode(l);
+ l.info = new LabelNode();
}
return (LabelNode) l.info;
}
@@ -539,7 +493,8 @@ public class MethodNode extends MethodVisitor {
* recursively, do not contain elements that were introduced in more recent
* versions of the ASM API than the given version.
*
- * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
+ * @param api
+ * an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/
public void check(final int api) {
// nothing to do
@@ -548,15 +503,13 @@ public class MethodNode extends MethodVisitor {
/**
* Makes the given class visitor visit this method.
*
- * @param cv a class visitor.
+ * @param cv
+ * a class visitor.
*/
public void accept(final ClassVisitor cv) {
String[] exceptions = new String[this.exceptions.size()];
this.exceptions.toArray(exceptions);
- MethodVisitor mv = cv.visitMethod(access,
- name,
- desc,
- signature,
+ MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
exceptions);
if (mv != null) {
accept(mv);
@@ -566,7 +519,8 @@ public class MethodNode extends MethodVisitor {
/**
* Makes the given method visitor visit this method.
*
- * @param mv a method visitor.
+ * @param mv
+ * a method visitor.
*/
public void accept(final MethodVisitor mv) {
// visits the method attributes
@@ -588,8 +542,7 @@ public class MethodNode extends MethodVisitor {
AnnotationNode an = invisibleAnnotations.get(i);
an.accept(mv.visitAnnotation(an.desc, false));
}
- n = visibleParameterAnnotations == null
- ? 0
+ n = visibleParameterAnnotations == null ? 0
: visibleParameterAnnotations.length;
for (i = 0; i < n; ++i) {
List<?> l = visibleParameterAnnotations[i];
@@ -601,8 +554,7 @@ public class MethodNode extends MethodVisitor {
an.accept(mv.visitParameterAnnotation(i, an.desc, true));
}
}
- n = invisibleParameterAnnotations == null
- ? 0
+ n = invisibleParameterAnnotations == null ? 0
: invisibleParameterAnnotations.length;
for (i = 0; i < n; ++i) {
List<?> l = invisibleParameterAnnotations[i];
diff --git a/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java b/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java
index 9dfba77335..fe5e8832b3 100644
--- a/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java
@@ -42,7 +42,7 @@ import scala.tools.asm.Opcodes;
public class MultiANewArrayInsnNode extends AbstractInsnNode {
/**
- * An array type descriptor (see {@link org.objectweb.asm.Type}).
+ * An array type descriptor (see {@link scala.tools.asm.Type}).
*/
public String desc;
@@ -54,8 +54,10 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link MultiANewArrayInsnNode}.
*
- * @param desc an array type descriptor (see {@link org.objectweb.asm.Type}).
- * @param dims number of dimensions of the array to allocate.
+ * @param desc
+ * an array type descriptor (see {@link scala.tools.asm.Type}).
+ * @param dims
+ * number of dimensions of the array to allocate.
*/
public MultiANewArrayInsnNode(final String desc, final int dims) {
super(Opcodes.MULTIANEWARRAY);
@@ -78,4 +80,4 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
return new MultiANewArrayInsnNode(desc, dims);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java b/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java
index 929ad9b32b..9b3c2a3437 100644
--- a/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java
@@ -69,18 +69,18 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link TableSwitchInsnNode}.
*
- * @param min the minimum key value.
- * @param max the maximum key value.
- * @param dflt beginning of the default handler block.
- * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
- * the beginning of the handler block for the <tt>min + i</tt> key.
+ * @param min
+ * the minimum key value.
+ * @param max
+ * the maximum key value.
+ * @param dflt
+ * beginning of the default handler block.
+ * @param labels
+ * beginnings of the handler blocks. <tt>labels[i]</tt> is the
+ * beginning of the handler block for the <tt>min + i</tt> key.
*/
- public TableSwitchInsnNode(
- final int min,
- final int max,
- final LabelNode dflt,
- final LabelNode... labels)
- {
+ public TableSwitchInsnNode(final int min, final int max,
+ final LabelNode dflt, final LabelNode... labels) {
super(Opcodes.TABLESWITCH);
this.min = min;
this.max = max;
@@ -107,9 +107,7 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
@Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
- return new TableSwitchInsnNode(min,
- max,
- clone(dflt, labels),
- clone(this.labels, labels));
+ return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(
+ this.labels, labels));
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java b/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java
index 375b4cfcb9..ab4fa97c34 100644
--- a/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java
+++ b/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java
@@ -62,19 +62,19 @@ public class TryCatchBlockNode {
/**
* Constructs a new {@link TryCatchBlockNode}.
*
- * @param start beginning of the exception handler's scope (inclusive).
- * @param end end of the exception handler's scope (exclusive).
- * @param handler beginning of the exception handler's code.
- * @param type internal name of the type of exceptions handled by the
- * handler, or <tt>null</tt> to catch any exceptions (for "finally"
- * blocks).
+ * @param start
+ * beginning of the exception handler's scope (inclusive).
+ * @param end
+ * end of the exception handler's scope (exclusive).
+ * @param handler
+ * beginning of the exception handler's code.
+ * @param type
+ * internal name of the type of exceptions handled by the
+ * handler, or <tt>null</tt> to catch any exceptions (for
+ * "finally" blocks).
*/
- public TryCatchBlockNode(
- final LabelNode start,
- final LabelNode end,
- final LabelNode handler,
- final String type)
- {
+ public TryCatchBlockNode(final LabelNode start, final LabelNode end,
+ final LabelNode handler, final String type) {
this.start = start;
this.end = end;
this.handler = handler;
@@ -84,11 +84,11 @@ public class TryCatchBlockNode {
/**
* Makes the given visitor visit this try catch block.
*
- * @param mv a method visitor.
+ * @param mv
+ * a method visitor.
*/
public void accept(final MethodVisitor mv) {
- mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), handler == null
- ? null
- : handler.getLabel(), type);
+ mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),
+ handler == null ? null : handler.getLabel(), type);
}
}
diff --git a/src/asm/scala/tools/asm/tree/TypeInsnNode.java b/src/asm/scala/tools/asm/tree/TypeInsnNode.java
index 0b2666c498..3210dd60e6 100644
--- a/src/asm/scala/tools/asm/tree/TypeInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/TypeInsnNode.java
@@ -43,17 +43,19 @@ public class TypeInsnNode extends AbstractInsnNode {
/**
* The operand of this instruction. This operand is an internal name (see
- * {@link org.objectweb.asm.Type}).
+ * {@link scala.tools.asm.Type}).
*/
public String desc;
/**
* Constructs a new {@link TypeInsnNode}.
*
- * @param opcode the opcode of the type instruction to be constructed. This
- * opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
- * @param desc the operand of the instruction to be constructed. This
- * operand is an internal name (see {@link org.objectweb.asm.Type}).
+ * @param opcode
+ * the opcode of the type instruction to be constructed. This
+ * opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param desc
+ * the operand of the instruction to be constructed. This operand
+ * is an internal name (see {@link scala.tools.asm.Type}).
*/
public TypeInsnNode(final int opcode, final String desc) {
super(opcode);
@@ -63,8 +65,9 @@ public class TypeInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be NEW,
- * ANEWARRAY, CHECKCAST or INSTANCEOF.
+ * @param opcode
+ * the new instruction opcode. This opcode must be NEW,
+ * ANEWARRAY, CHECKCAST or INSTANCEOF.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
@@ -84,4 +87,4 @@ public class TypeInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TypeInsnNode(opcode, desc);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/VarInsnNode.java b/src/asm/scala/tools/asm/tree/VarInsnNode.java
index 89f572db59..5dd9ef6726 100644
--- a/src/asm/scala/tools/asm/tree/VarInsnNode.java
+++ b/src/asm/scala/tools/asm/tree/VarInsnNode.java
@@ -51,11 +51,13 @@ public class VarInsnNode extends AbstractInsnNode {
/**
* Constructs a new {@link VarInsnNode}.
*
- * @param opcode the opcode of the local variable instruction to be
- * constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
- * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
- * @param var the operand of the instruction to be constructed. This operand
- * is the index of a local variable.
+ * @param opcode
+ * the opcode of the local variable instruction to be
+ * constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
+ * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+ * @param var
+ * the operand of the instruction to be constructed. This operand
+ * is the index of a local variable.
*/
public VarInsnNode(final int opcode, final int var) {
super(opcode);
@@ -65,9 +67,10 @@ public class VarInsnNode extends AbstractInsnNode {
/**
* Sets the opcode of this instruction.
*
- * @param opcode the new instruction opcode. This opcode must be ILOAD,
- * LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE
- * or RET.
+ * @param opcode
+ * the new instruction opcode. This opcode must be ILOAD, LLOAD,
+ * FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
+ * RET.
*/
public void setOpcode(final int opcode) {
this.opcode = opcode;
@@ -87,4 +90,4 @@ public class VarInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new VarInsnNode(opcode, var);
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/tree/analysis/Analyzer.java b/src/asm/scala/tools/asm/tree/analysis/Analyzer.java
index df387b0b8e..0134555f10 100644
--- a/src/asm/scala/tools/asm/tree/analysis/Analyzer.java
+++ b/src/asm/scala/tools/asm/tree/analysis/Analyzer.java
@@ -51,9 +51,10 @@ import scala.tools.asm.tree.VarInsnNode;
* A semantic bytecode analyzer. <i>This class does not fully check that JSR and
* RET instructions are valid.</i>
*
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ * type of the Value used for the analysis.
*
- * @author Eric Bruneton
+ * @author Eric Bruneton
*/
public class Analyzer<V extends Value> implements Opcodes {
@@ -78,8 +79,9 @@ public class Analyzer<V extends Value> implements Opcodes {
/**
* Constructs a new {@link Analyzer}.
*
- * @param interpreter the interpreter to be used to symbolically interpret
- * the bytecode instructions.
+ * @param interpreter
+ * the interpreter to be used to symbolically interpret the
+ * bytecode instructions.
*/
public Analyzer(final Interpreter<V> interpreter) {
this.interpreter = interpreter;
@@ -88,26 +90,28 @@ public class Analyzer<V extends Value> implements Opcodes {
/**
* Analyzes the given method.
*
- * @param owner the internal name of the class to which the method belongs.
- * @param m the method to be analyzed.
+ * @param owner
+ * the internal name of the class to which the method belongs.
+ * @param m
+ * the method to be analyzed.
* @return the symbolic state of the execution stack frame at each bytecode
* instruction of the method. The size of the returned array is
* equal to the number of instructions (and labels) of the method. A
* given frame is <tt>null</tt> if and only if the corresponding
* instruction cannot be reached (dead code).
- * @throws AnalyzerException if a problem occurs during the analysis.
+ * @throws AnalyzerException
+ * if a problem occurs during the analysis.
*/
public Frame<V>[] analyze(final String owner, final MethodNode m)
- throws AnalyzerException
- {
+ throws AnalyzerException {
if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
- frames = (Frame<V>[])new Frame<?>[0];
+ frames = (Frame<V>[]) new Frame<?>[0];
return frames;
}
n = m.instructions.size();
insns = m.instructions;
- handlers = (List<TryCatchBlockNode>[])new List<?>[n];
- frames = (Frame<V>[])new Frame<?>[n];
+ handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
+ frames = (Frame<V>[]) new Frame<?>[n];
subroutines = new Subroutine[n];
queued = new boolean[n];
queue = new int[n];
@@ -188,8 +192,7 @@ public class Analyzer<V extends Value> implements Opcodes {
if (insnType == AbstractInsnNode.LABEL
|| insnType == AbstractInsnNode.LINE
- || insnType == AbstractInsnNode.FRAME)
- {
+ || insnType == AbstractInsnNode.FRAME) {
merge(insn + 1, f, subroutine);
newControlFlowEdge(insn, insn + 1);
} else {
@@ -205,8 +208,7 @@ public class Analyzer<V extends Value> implements Opcodes {
int jump = insns.indexOf(j.label);
if (insnOpcode == JSR) {
merge(jump, current, new Subroutine(j.label,
- m.maxLocals,
- j));
+ m.maxLocals, j));
} else {
merge(jump, current, subroutine);
}
@@ -235,31 +237,27 @@ public class Analyzer<V extends Value> implements Opcodes {
}
} else if (insnOpcode == RET) {
if (subroutine == null) {
- throw new AnalyzerException(insnNode, "RET instruction outside of a sub routine");
+ throw new AnalyzerException(insnNode,
+ "RET instruction outside of a sub routine");
}
for (int i = 0; i < subroutine.callers.size(); ++i) {
JumpInsnNode caller = subroutine.callers.get(i);
int call = insns.indexOf(caller);
if (frames[call] != null) {
- merge(call + 1,
- frames[call],
- current,
- subroutines[call],
- subroutine.access);
+ merge(call + 1, frames[call], current,
+ subroutines[call], subroutine.access);
newControlFlowEdge(insn, call + 1);
}
}
} else if (insnOpcode != ATHROW
- && (insnOpcode < IRETURN || insnOpcode > RETURN))
- {
+ && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
if (subroutine != null) {
if (insnNode instanceof VarInsnNode) {
int var = ((VarInsnNode) insnNode).var;
subroutine.access[var] = true;
if (insnOpcode == LLOAD || insnOpcode == DLOAD
|| insnOpcode == LSTORE
- || insnOpcode == DSTORE)
- {
+ || insnOpcode == DSTORE) {
subroutine.access[var + 1] = true;
}
} else if (insnNode instanceof IincInsnNode) {
@@ -292,23 +290,23 @@ public class Analyzer<V extends Value> implements Opcodes {
}
}
} catch (AnalyzerException e) {
- throw new AnalyzerException(e.node, "Error at instruction " + insn
- + ": " + e.getMessage(), e);
+ throw new AnalyzerException(e.node, "Error at instruction "
+ + insn + ": " + e.getMessage(), e);
} catch (Exception e) {
- throw new AnalyzerException(insnNode, "Error at instruction " + insn
- + ": " + e.getMessage(), e);
+ throw new AnalyzerException(insnNode, "Error at instruction "
+ + insn + ": " + e.getMessage(), e);
}
}
return frames;
}
- private void findSubroutine(int insn, final Subroutine sub, final List<AbstractInsnNode> calls)
- throws AnalyzerException
- {
+ private void findSubroutine(int insn, final Subroutine sub,
+ final List<AbstractInsnNode> calls) throws AnalyzerException {
while (true) {
if (insn < 0 || insn >= n) {
- throw new AnalyzerException(null, "Execution can fall off end of the code");
+ throw new AnalyzerException(null,
+ "Execution can fall off end of the code");
}
if (subroutines[insn] != null) {
return;
@@ -352,18 +350,18 @@ public class Analyzer<V extends Value> implements Opcodes {
// if insn does not falls through to the next instruction, return.
switch (node.getOpcode()) {
- case GOTO:
- case RET:
- case TABLESWITCH:
- case LOOKUPSWITCH:
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- case ARETURN:
- case RETURN:
- case ATHROW:
- return;
+ case GOTO:
+ case RET:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case RETURN:
+ case ATHROW:
+ return;
}
insn++;
}
@@ -387,8 +385,9 @@ public class Analyzer<V extends Value> implements Opcodes {
/**
* Returns the exception handlers for the given instruction.
*
- * @param insn the index of an instruction of the last recently analyzed
- * method.
+ * @param insn
+ * the index of an instruction of the last recently analyzed
+ * method.
* @return a list of {@link TryCatchBlockNode} objects.
*/
public List<TryCatchBlockNode> getHandlers(final int insn) {
@@ -400,9 +399,12 @@ public class Analyzer<V extends Value> implements Opcodes {
* execution of control flow analysis loop in #analyze. The default
* implementation of this method does nothing.
*
- * @param owner the internal name of the class to which the method belongs.
- * @param m the method to be analyzed.
- * @throws AnalyzerException if a problem occurs.
+ * @param owner
+ * the internal name of the class to which the method belongs.
+ * @param m
+ * the method to be analyzed.
+ * @throws AnalyzerException
+ * if a problem occurs.
*/
protected void init(String owner, MethodNode m) throws AnalyzerException {
}
@@ -410,8 +412,10 @@ public class Analyzer<V extends Value> implements Opcodes {
/**
* Constructs a new frame with the given size.
*
- * @param nLocals the maximum number of local variables of the frame.
- * @param nStack the maximum stack size of the frame.
+ * @param nLocals
+ * the maximum number of local variables of the frame.
+ * @param nStack
+ * the maximum stack size of the frame.
* @return the created frame.
*/
protected Frame<V> newFrame(final int nLocals, final int nStack) {
@@ -421,7 +425,8 @@ public class Analyzer<V extends Value> implements Opcodes {
/**
* Constructs a new frame that is identical to the given frame.
*
- * @param src a frame.
+ * @param src
+ * a frame.
* @return the created frame.
*/
protected Frame<V> newFrame(final Frame<? extends V> src) {
@@ -434,8 +439,10 @@ public class Analyzer<V extends Value> implements Opcodes {
* control flow graph of a method (this method is called by the
* {@link #analyze analyze} method during its visit of the method's code).
*
- * @param insn an instruction index.
- * @param successor index of a successor instruction.
+ * @param insn
+ * an instruction index.
+ * @param successor
+ * index of a successor instruction.
*/
protected void newControlFlowEdge(final int insn, final int successor) {
}
@@ -447,16 +454,16 @@ public class Analyzer<V extends Value> implements Opcodes {
* method is called by the {@link #analyze analyze} method during its visit
* of the method's code).
*
- * @param insn an instruction index.
- * @param successor index of a successor instruction.
+ * @param insn
+ * an instruction index.
+ * @param successor
+ * index of a successor instruction.
* @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method always returns true.
*/
- protected boolean newControlFlowExceptionEdge(
- final int insn,
- final int successor)
- {
+ protected boolean newControlFlowExceptionEdge(final int insn,
+ final int successor) {
return true;
}
@@ -469,28 +476,25 @@ public class Analyzer<V extends Value> implements Opcodes {
* the {@link #analyze analyze} method during its visit of the method's
* code).
*
- * @param insn an instruction index.
- * @param tcb TryCatchBlockNode corresponding to this edge.
+ * @param insn
+ * an instruction index.
+ * @param tcb
+ * TryCatchBlockNode corresponding to this edge.
* @return true if this edge must be considered in the data flow analysis
* performed by this analyzer, or false otherwise. The default
* implementation of this method delegates to
* {@link #newControlFlowExceptionEdge(int, int)
* newControlFlowExceptionEdge(int, int)}.
*/
- protected boolean newControlFlowExceptionEdge(
- final int insn,
- final TryCatchBlockNode tcb)
- {
+ protected boolean newControlFlowExceptionEdge(final int insn,
+ final TryCatchBlockNode tcb) {
return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
}
// -------------------------------------------------------------------------
- private void merge(
- final int insn,
- final Frame<V> frame,
- final Subroutine subroutine) throws AnalyzerException
- {
+ private void merge(final int insn, final Frame<V> frame,
+ final Subroutine subroutine) throws AnalyzerException {
Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn];
boolean changes;
@@ -518,13 +522,9 @@ public class Analyzer<V extends Value> implements Opcodes {
}
}
- private void merge(
- final int insn,
- final Frame<V> beforeJSR,
- final Frame<V> afterRET,
- final Subroutine subroutineBeforeJSR,
- final boolean[] access) throws AnalyzerException
- {
+ private void merge(final int insn, final Frame<V> beforeJSR,
+ final Frame<V> afterRET, final Subroutine subroutineBeforeJSR,
+ final boolean[] access) throws AnalyzerException {
Frame<V> oldFrame = frames[insn];
Subroutine oldSubroutine = subroutines[insn];
boolean changes;
diff --git a/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java b/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java
index a89bb3513f..5e3f51f21a 100644
--- a/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java
+++ b/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java
@@ -46,17 +46,14 @@ public class AnalyzerException extends Exception {
this.node = node;
}
- public AnalyzerException(final AbstractInsnNode node, final String msg, final Throwable exception) {
+ public AnalyzerException(final AbstractInsnNode node, final String msg,
+ final Throwable exception) {
super(msg, exception);
this.node = node;
}
- public AnalyzerException(
- final AbstractInsnNode node,
- final String msg,
- final Object expected,
- final Value encountered)
- {
+ public AnalyzerException(final AbstractInsnNode node, final String msg,
+ final Object expected, final Value encountered) {
super((msg == null ? "Expected " : msg + ": expected ") + expected
+ ", but found " + encountered);
this.node = node;
diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java b/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java
index 64ddcc11e6..8d6653c1c5 100644
--- a/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java
+++ b/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java
@@ -50,8 +50,7 @@ import scala.tools.asm.tree.TypeInsnNode;
* @author Bing Ran
*/
public class BasicInterpreter extends Interpreter<BasicValue> implements
- Opcodes
-{
+ Opcodes {
public BasicInterpreter() {
super(ASM4);
@@ -67,292 +66,286 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements
return BasicValue.UNINITIALIZED_VALUE;
}
switch (type.getSort()) {
- case Type.VOID:
- return null;
- case Type.BOOLEAN:
- case Type.CHAR:
- case Type.BYTE:
- case Type.SHORT:
- case Type.INT:
- return BasicValue.INT_VALUE;
- case Type.FLOAT:
- return BasicValue.FLOAT_VALUE;
- case Type.LONG:
- return BasicValue.LONG_VALUE;
- case Type.DOUBLE:
- return BasicValue.DOUBLE_VALUE;
- case Type.ARRAY:
- case Type.OBJECT:
- return BasicValue.REFERENCE_VALUE;
- default:
- throw new Error("Internal error");
+ case Type.VOID:
+ return null;
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ return BasicValue.INT_VALUE;
+ case Type.FLOAT:
+ return BasicValue.FLOAT_VALUE;
+ case Type.LONG:
+ return BasicValue.LONG_VALUE;
+ case Type.DOUBLE:
+ return BasicValue.DOUBLE_VALUE;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ return BasicValue.REFERENCE_VALUE;
+ default:
+ throw new Error("Internal error");
}
}
@Override
public BasicValue newOperation(final AbstractInsnNode insn)
- throws AnalyzerException
- {
+ throws AnalyzerException {
switch (insn.getOpcode()) {
- case ACONST_NULL:
- return newValue(Type.getObjectType("null"));
- case ICONST_M1:
- case ICONST_0:
- case ICONST_1:
- case ICONST_2:
- case ICONST_3:
- case ICONST_4:
- case ICONST_5:
+ case ACONST_NULL:
+ return newValue(Type.getObjectType("null"));
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ return BasicValue.INT_VALUE;
+ case LCONST_0:
+ case LCONST_1:
+ return BasicValue.LONG_VALUE;
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ return BasicValue.FLOAT_VALUE;
+ case DCONST_0:
+ case DCONST_1:
+ return BasicValue.DOUBLE_VALUE;
+ case BIPUSH:
+ case SIPUSH:
+ return BasicValue.INT_VALUE;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ if (cst instanceof Integer) {
return BasicValue.INT_VALUE;
- case LCONST_0:
- case LCONST_1:
- return BasicValue.LONG_VALUE;
- case FCONST_0:
- case FCONST_1:
- case FCONST_2:
+ } else if (cst instanceof Float) {
return BasicValue.FLOAT_VALUE;
- case DCONST_0:
- case DCONST_1:
+ } else if (cst instanceof Long) {
+ return BasicValue.LONG_VALUE;
+ } else if (cst instanceof Double) {
return BasicValue.DOUBLE_VALUE;
- case BIPUSH:
- case SIPUSH:
- return BasicValue.INT_VALUE;
- case LDC:
- Object cst = ((LdcInsnNode) insn).cst;
- if (cst instanceof Integer) {
- return BasicValue.INT_VALUE;
- } else if (cst instanceof Float) {
- return BasicValue.FLOAT_VALUE;
- } else if (cst instanceof Long) {
- return BasicValue.LONG_VALUE;
- } else if (cst instanceof Double) {
- return BasicValue.DOUBLE_VALUE;
- } else if (cst instanceof String) {
- return newValue(Type.getObjectType("java/lang/String"));
- } else if (cst instanceof Type) {
- int sort = ((Type) cst).getSort();
- if (sort == Type.OBJECT || sort == Type.ARRAY) {
- return newValue(Type.getObjectType("java/lang/Class"));
- } else if (sort == Type.METHOD) {
- return newValue(Type.getObjectType("java/lang/invoke/MethodType"));
- } else {
- throw new IllegalArgumentException("Illegal LDC constant " + cst);
- }
- } else if (cst instanceof Handle) {
- return newValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
+ } else if (cst instanceof String) {
+ return newValue(Type.getObjectType("java/lang/String"));
+ } else if (cst instanceof Type) {
+ int sort = ((Type) cst).getSort();
+ if (sort == Type.OBJECT || sort == Type.ARRAY) {
+ return newValue(Type.getObjectType("java/lang/Class"));
+ } else if (sort == Type.METHOD) {
+ return newValue(Type
+ .getObjectType("java/lang/invoke/MethodType"));
} else {
- throw new IllegalArgumentException("Illegal LDC constant " + cst);
+ throw new IllegalArgumentException("Illegal LDC constant "
+ + cst);
}
- case JSR:
- return BasicValue.RETURNADDRESS_VALUE;
- case GETSTATIC:
- return newValue(Type.getType(((FieldInsnNode) insn).desc));
- case NEW:
- return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
- default:
- throw new Error("Internal error.");
+ } else if (cst instanceof Handle) {
+ return newValue(Type
+ .getObjectType("java/lang/invoke/MethodHandle"));
+ } else {
+ throw new IllegalArgumentException("Illegal LDC constant "
+ + cst);
+ }
+ case JSR:
+ return BasicValue.RETURNADDRESS_VALUE;
+ case GETSTATIC:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEW:
+ return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
+ default:
+ throw new Error("Internal error.");
}
}
@Override
- public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
- throws AnalyzerException
- {
+ public BasicValue copyOperation(final AbstractInsnNode insn,
+ final BasicValue value) throws AnalyzerException {
return value;
}
@Override
- public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
- throws AnalyzerException
- {
+ public BasicValue unaryOperation(final AbstractInsnNode insn,
+ final BasicValue value) throws AnalyzerException {
switch (insn.getOpcode()) {
- case INEG:
- case IINC:
- case L2I:
- case F2I:
- case D2I:
- case I2B:
- case I2C:
- case I2S:
- return BasicValue.INT_VALUE;
- case FNEG:
- case I2F:
- case L2F:
- case D2F:
- return BasicValue.FLOAT_VALUE;
- case LNEG:
- case I2L:
- case F2L:
- case D2L:
- return BasicValue.LONG_VALUE;
- case DNEG:
- case I2D:
- case L2D:
- case F2D:
- return BasicValue.DOUBLE_VALUE;
- case IFEQ:
- case IFNE:
- case IFLT:
- case IFGE:
- case IFGT:
- case IFLE:
- case TABLESWITCH:
- case LOOKUPSWITCH:
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- case ARETURN:
- case PUTSTATIC:
- return null;
- case GETFIELD:
- return newValue(Type.getType(((FieldInsnNode) insn).desc));
- case NEWARRAY:
- switch (((IntInsnNode) insn).operand) {
- case T_BOOLEAN:
- return newValue(Type.getType("[Z"));
- case T_CHAR:
- return newValue(Type.getType("[C"));
- case T_BYTE:
- return newValue(Type.getType("[B"));
- case T_SHORT:
- return newValue(Type.getType("[S"));
- case T_INT:
- return newValue(Type.getType("[I"));
- case T_FLOAT:
- return newValue(Type.getType("[F"));
- case T_DOUBLE:
- return newValue(Type.getType("[D"));
- case T_LONG:
- return newValue(Type.getType("[J"));
- default:
- throw new AnalyzerException(insn, "Invalid array type");
- }
- case ANEWARRAY:
- String desc = ((TypeInsnNode) insn).desc;
- return newValue(Type.getType("[" + Type.getObjectType(desc)));
- case ARRAYLENGTH:
- return BasicValue.INT_VALUE;
- case ATHROW:
- return null;
- case CHECKCAST:
- desc = ((TypeInsnNode) insn).desc;
- return newValue(Type.getObjectType(desc));
- case INSTANCEOF:
- return BasicValue.INT_VALUE;
- case MONITORENTER:
- case MONITOREXIT:
- case IFNULL:
- case IFNONNULL:
- return null;
+ case INEG:
+ case IINC:
+ case L2I:
+ case F2I:
+ case D2I:
+ case I2B:
+ case I2C:
+ case I2S:
+ return BasicValue.INT_VALUE;
+ case FNEG:
+ case I2F:
+ case L2F:
+ case D2F:
+ return BasicValue.FLOAT_VALUE;
+ case LNEG:
+ case I2L:
+ case F2L:
+ case D2L:
+ return BasicValue.LONG_VALUE;
+ case DNEG:
+ case I2D:
+ case L2D:
+ case F2D:
+ return BasicValue.DOUBLE_VALUE;
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case PUTSTATIC:
+ return null;
+ case GETFIELD:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEWARRAY:
+ switch (((IntInsnNode) insn).operand) {
+ case T_BOOLEAN:
+ return newValue(Type.getType("[Z"));
+ case T_CHAR:
+ return newValue(Type.getType("[C"));
+ case T_BYTE:
+ return newValue(Type.getType("[B"));
+ case T_SHORT:
+ return newValue(Type.getType("[S"));
+ case T_INT:
+ return newValue(Type.getType("[I"));
+ case T_FLOAT:
+ return newValue(Type.getType("[F"));
+ case T_DOUBLE:
+ return newValue(Type.getType("[D"));
+ case T_LONG:
+ return newValue(Type.getType("[J"));
default:
- throw new Error("Internal error.");
+ throw new AnalyzerException(insn, "Invalid array type");
+ }
+ case ANEWARRAY:
+ String desc = ((TypeInsnNode) insn).desc;
+ return newValue(Type.getType("[" + Type.getObjectType(desc)));
+ case ARRAYLENGTH:
+ return BasicValue.INT_VALUE;
+ case ATHROW:
+ return null;
+ case CHECKCAST:
+ desc = ((TypeInsnNode) insn).desc;
+ return newValue(Type.getObjectType(desc));
+ case INSTANCEOF:
+ return BasicValue.INT_VALUE;
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ return null;
+ default:
+ throw new Error("Internal error.");
}
}
@Override
- public BasicValue binaryOperation(
- final AbstractInsnNode insn,
- final BasicValue value1,
- final BasicValue value2) throws AnalyzerException
- {
+ public BasicValue binaryOperation(final AbstractInsnNode insn,
+ final BasicValue value1, final BasicValue value2)
+ throws AnalyzerException {
switch (insn.getOpcode()) {
- case IALOAD:
- case BALOAD:
- case CALOAD:
- case SALOAD:
- case IADD:
- case ISUB:
- case IMUL:
- case IDIV:
- case IREM:
- case ISHL:
- case ISHR:
- case IUSHR:
- case IAND:
- case IOR:
- case IXOR:
- return BasicValue.INT_VALUE;
- case FALOAD:
- case FADD:
- case FSUB:
- case FMUL:
- case FDIV:
- case FREM:
- return BasicValue.FLOAT_VALUE;
- case LALOAD:
- case LADD:
- case LSUB:
- case LMUL:
- case LDIV:
- case LREM:
- case LSHL:
- case LSHR:
- case LUSHR:
- case LAND:
- case LOR:
- case LXOR:
- return BasicValue.LONG_VALUE;
- case DALOAD:
- case DADD:
- case DSUB:
- case DMUL:
- case DDIV:
- case DREM:
- return BasicValue.DOUBLE_VALUE;
- case AALOAD:
- return BasicValue.REFERENCE_VALUE;
- case LCMP:
- case FCMPL:
- case FCMPG:
- case DCMPL:
- case DCMPG:
- return BasicValue.INT_VALUE;
- case IF_ICMPEQ:
- case IF_ICMPNE:
- case IF_ICMPLT:
- case IF_ICMPGE:
- case IF_ICMPGT:
- case IF_ICMPLE:
- case IF_ACMPEQ:
- case IF_ACMPNE:
- case PUTFIELD:
- return null;
- default:
- throw new Error("Internal error.");
+ case IALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ return BasicValue.INT_VALUE;
+ case FALOAD:
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ return BasicValue.FLOAT_VALUE;
+ case LALOAD:
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ return BasicValue.LONG_VALUE;
+ case DALOAD:
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ return BasicValue.DOUBLE_VALUE;
+ case AALOAD:
+ return BasicValue.REFERENCE_VALUE;
+ case LCMP:
+ case FCMPL:
+ case FCMPG:
+ case DCMPL:
+ case DCMPG:
+ return BasicValue.INT_VALUE;
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case PUTFIELD:
+ return null;
+ default:
+ throw new Error("Internal error.");
}
}
@Override
- public BasicValue ternaryOperation(
- final AbstractInsnNode insn,
- final BasicValue value1,
- final BasicValue value2,
- final BasicValue value3) throws AnalyzerException
- {
+ public BasicValue ternaryOperation(final AbstractInsnNode insn,
+ final BasicValue value1, final BasicValue value2,
+ final BasicValue value3) throws AnalyzerException {
return null;
}
@Override
- public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values)
- throws AnalyzerException
- {
+ public BasicValue naryOperation(final AbstractInsnNode insn,
+ final List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
- } else if (opcode == INVOKEDYNAMIC){
- return newValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc));
+ } else if (opcode == INVOKEDYNAMIC) {
+ return newValue(Type
+ .getReturnType(((InvokeDynamicInsnNode) insn).desc));
} else {
return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
}
}
@Override
- public void returnOperation(
- final AbstractInsnNode insn,
- final BasicValue value,
- final BasicValue expected) throws AnalyzerException
- {
+ public void returnOperation(final AbstractInsnNode insn,
+ final BasicValue value, final BasicValue expected)
+ throws AnalyzerException {
}
@Override
diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicValue.java b/src/asm/scala/tools/asm/tree/analysis/BasicValue.java
index 6c449db9b0..439941fb9f 100644
--- a/src/asm/scala/tools/asm/tree/analysis/BasicValue.java
+++ b/src/asm/scala/tools/asm/tree/analysis/BasicValue.java
@@ -48,11 +48,14 @@ public class BasicValue implements Value {
public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
- public static final BasicValue DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE);
+ public static final BasicValue DOUBLE_VALUE = new BasicValue(
+ Type.DOUBLE_TYPE);
- public static final BasicValue REFERENCE_VALUE = new BasicValue(Type.getObjectType("java/lang/Object"));
+ public static final BasicValue REFERENCE_VALUE = new BasicValue(
+ Type.getObjectType("java/lang/Object"));
- public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(Type.VOID_TYPE);
+ public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(
+ Type.VOID_TYPE);
private final Type type;
diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java b/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java
index 9297dd9294..71666edb74 100644
--- a/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java
+++ b/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java
@@ -55,47 +55,41 @@ public class BasicVerifier extends BasicInterpreter {
}
@Override
- public BasicValue copyOperation(final AbstractInsnNode insn, final BasicValue value)
- throws AnalyzerException
- {
+ public BasicValue copyOperation(final AbstractInsnNode insn,
+ final BasicValue value) throws AnalyzerException {
Value expected;
switch (insn.getOpcode()) {
- case ILOAD:
- case ISTORE:
- expected = BasicValue.INT_VALUE;
- break;
- case FLOAD:
- case FSTORE:
- expected = BasicValue.FLOAT_VALUE;
- break;
- case LLOAD:
- case LSTORE:
- expected = BasicValue.LONG_VALUE;
- break;
- case DLOAD:
- case DSTORE:
- expected = BasicValue.DOUBLE_VALUE;
- break;
- case ALOAD:
- if (!value.isReference()) {
- throw new AnalyzerException(insn,
- null,
- "an object reference",
- value);
- }
- return value;
- case ASTORE:
- if (!value.isReference()
- && !BasicValue.RETURNADDRESS_VALUE.equals(value))
- {
- throw new AnalyzerException(insn,
- null,
- "an object reference or a return address",
- value);
- }
- return value;
- default:
- return value;
+ case ILOAD:
+ case ISTORE:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FLOAD:
+ case FSTORE:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LLOAD:
+ case LSTORE:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DLOAD:
+ case DSTORE:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case ALOAD:
+ if (!value.isReference()) {
+ throw new AnalyzerException(insn, null, "an object reference",
+ value);
+ }
+ return value;
+ case ASTORE:
+ if (!value.isReference()
+ && !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
+ throw new AnalyzerException(insn, null,
+ "an object reference or a return address", value);
+ }
+ return value;
+ default:
+ return value;
}
if (!expected.equals(value)) {
throw new AnalyzerException(insn, null, expected, value);
@@ -104,91 +98,85 @@ public class BasicVerifier extends BasicInterpreter {
}
@Override
- public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value)
- throws AnalyzerException
- {
+ public BasicValue unaryOperation(final AbstractInsnNode insn,
+ final BasicValue value) throws AnalyzerException {
BasicValue expected;
switch (insn.getOpcode()) {
- case INEG:
- case IINC:
- case I2F:
- case I2L:
- case I2D:
- case I2B:
- case I2C:
- case I2S:
- case IFEQ:
- case IFNE:
- case IFLT:
- case IFGE:
- case IFGT:
- case IFLE:
- case TABLESWITCH:
- case LOOKUPSWITCH:
- case IRETURN:
- case NEWARRAY:
- case ANEWARRAY:
- expected = BasicValue.INT_VALUE;
- break;
- case FNEG:
- case F2I:
- case F2L:
- case F2D:
- case FRETURN:
- expected = BasicValue.FLOAT_VALUE;
- break;
- case LNEG:
- case L2I:
- case L2F:
- case L2D:
- case LRETURN:
- expected = BasicValue.LONG_VALUE;
- break;
- case DNEG:
- case D2I:
- case D2F:
- case D2L:
- case DRETURN:
- expected = BasicValue.DOUBLE_VALUE;
- break;
- case GETFIELD:
- expected = newValue(Type.getObjectType(((FieldInsnNode) insn).owner));
- break;
- case CHECKCAST:
- if (!value.isReference()) {
- throw new AnalyzerException(insn,
- null,
- "an object reference",
- value);
- }
- return super.unaryOperation(insn, value);
- case ARRAYLENGTH:
- if (!isArrayValue(value)) {
- throw new AnalyzerException(insn,
- null,
- "an array reference",
- value);
- }
- return super.unaryOperation(insn, value);
- case ARETURN:
- case ATHROW:
- case INSTANCEOF:
- case MONITORENTER:
- case MONITOREXIT:
- case IFNULL:
- case IFNONNULL:
- if (!value.isReference()) {
- throw new AnalyzerException(insn,
- null,
- "an object reference",
- value);
- }
- return super.unaryOperation(insn, value);
- case PUTSTATIC:
- expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
- break;
- default:
- throw new Error("Internal error.");
+ case INEG:
+ case IINC:
+ case I2F:
+ case I2L:
+ case I2D:
+ case I2B:
+ case I2C:
+ case I2S:
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case NEWARRAY:
+ case ANEWARRAY:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FNEG:
+ case F2I:
+ case F2L:
+ case F2D:
+ case FRETURN:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LNEG:
+ case L2I:
+ case L2F:
+ case L2D:
+ case LRETURN:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DNEG:
+ case D2I:
+ case D2F:
+ case D2L:
+ case DRETURN:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case GETFIELD:
+ expected = newValue(Type
+ .getObjectType(((FieldInsnNode) insn).owner));
+ break;
+ case CHECKCAST:
+ if (!value.isReference()) {
+ throw new AnalyzerException(insn, null, "an object reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case ARRAYLENGTH:
+ if (!isArrayValue(value)) {
+ throw new AnalyzerException(insn, null, "an array reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case ARETURN:
+ case ATHROW:
+ case INSTANCEOF:
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ if (!value.isReference()) {
+ throw new AnalyzerException(insn, null, "an object reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case PUTSTATIC:
+ expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
+ break;
+ default:
+ throw new Error("Internal error.");
}
if (!isSubTypeOf(value, expected)) {
throw new AnalyzerException(insn, null, expected, value);
@@ -197,125 +185,125 @@ public class BasicVerifier extends BasicInterpreter {
}
@Override
- public BasicValue binaryOperation(
- final AbstractInsnNode insn,
- final BasicValue value1,
- final BasicValue value2) throws AnalyzerException
- {
+ public BasicValue binaryOperation(final AbstractInsnNode insn,
+ final BasicValue value1, final BasicValue value2)
+ throws AnalyzerException {
BasicValue expected1;
BasicValue expected2;
switch (insn.getOpcode()) {
- case IALOAD:
- expected1 = newValue(Type.getType("[I"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case BALOAD:
- if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
- expected1 = newValue(Type.getType("[Z"));
- } else {
- expected1 = newValue(Type.getType("[B"));
- }
- expected2 = BasicValue.INT_VALUE;
- break;
- case CALOAD:
- expected1 = newValue(Type.getType("[C"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case SALOAD:
- expected1 = newValue(Type.getType("[S"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case LALOAD:
- expected1 = newValue(Type.getType("[J"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case FALOAD:
- expected1 = newValue(Type.getType("[F"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case DALOAD:
- expected1 = newValue(Type.getType("[D"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case AALOAD:
- expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
- expected2 = BasicValue.INT_VALUE;
- break;
- case IADD:
- case ISUB:
- case IMUL:
- case IDIV:
- case IREM:
- case ISHL:
- case ISHR:
- case IUSHR:
- case IAND:
- case IOR:
- case IXOR:
- case IF_ICMPEQ:
- case IF_ICMPNE:
- case IF_ICMPLT:
- case IF_ICMPGE:
- case IF_ICMPGT:
- case IF_ICMPLE:
- expected1 = BasicValue.INT_VALUE;
- expected2 = BasicValue.INT_VALUE;
- break;
- case FADD:
- case FSUB:
- case FMUL:
- case FDIV:
- case FREM:
- case FCMPL:
- case FCMPG:
- expected1 = BasicValue.FLOAT_VALUE;
- expected2 = BasicValue.FLOAT_VALUE;
- break;
- case LADD:
- case LSUB:
- case LMUL:
- case LDIV:
- case LREM:
- case LAND:
- case LOR:
- case LXOR:
- case LCMP:
- expected1 = BasicValue.LONG_VALUE;
- expected2 = BasicValue.LONG_VALUE;
- break;
- case LSHL:
- case LSHR:
- case LUSHR:
- expected1 = BasicValue.LONG_VALUE;
- expected2 = BasicValue.INT_VALUE;
- break;
- case DADD:
- case DSUB:
- case DMUL:
- case DDIV:
- case DREM:
- case DCMPL:
- case DCMPG:
- expected1 = BasicValue.DOUBLE_VALUE;
- expected2 = BasicValue.DOUBLE_VALUE;
- break;
- case IF_ACMPEQ:
- case IF_ACMPNE:
- expected1 = BasicValue.REFERENCE_VALUE;
- expected2 = BasicValue.REFERENCE_VALUE;
- break;
- case PUTFIELD:
- FieldInsnNode fin = (FieldInsnNode) insn;
- expected1 = newValue(Type.getObjectType(fin.owner));
- expected2 = newValue(Type.getType(fin.desc));
- break;
- default:
- throw new Error("Internal error.");
+ case IALOAD:
+ expected1 = newValue(Type.getType("[I"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case BALOAD:
+ if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[Z"));
+ } else {
+ expected1 = newValue(Type.getType("[B"));
+ }
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case CALOAD:
+ expected1 = newValue(Type.getType("[C"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case SALOAD:
+ expected1 = newValue(Type.getType("[S"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case LALOAD:
+ expected1 = newValue(Type.getType("[J"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FALOAD:
+ expected1 = newValue(Type.getType("[F"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DALOAD:
+ expected1 = newValue(Type.getType("[D"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case AALOAD:
+ expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ expected1 = BasicValue.INT_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ case FCMPL:
+ case FCMPG:
+ expected1 = BasicValue.FLOAT_VALUE;
+ expected2 = BasicValue.FLOAT_VALUE;
+ break;
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LAND:
+ case LOR:
+ case LXOR:
+ case LCMP:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.LONG_VALUE;
+ break;
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ case DCMPL:
+ case DCMPG:
+ expected1 = BasicValue.DOUBLE_VALUE;
+ expected2 = BasicValue.DOUBLE_VALUE;
+ break;
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ expected1 = BasicValue.REFERENCE_VALUE;
+ expected2 = BasicValue.REFERENCE_VALUE;
+ break;
+ case PUTFIELD:
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ expected1 = newValue(Type.getObjectType(fin.owner));
+ expected2 = newValue(Type.getType(fin.desc));
+ break;
+ default:
+ throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
- throw new AnalyzerException(insn, "First argument", expected1, value1);
+ throw new AnalyzerException(insn, "First argument", expected1,
+ value1);
} else if (!isSubTypeOf(value2, expected2)) {
- throw new AnalyzerException(insn, "Second argument", expected2, value2);
+ throw new AnalyzerException(insn, "Second argument", expected2,
+ value2);
}
if (insn.getOpcode() == AALOAD) {
return getElementValue(value1);
@@ -325,79 +313,73 @@ public class BasicVerifier extends BasicInterpreter {
}
@Override
- public BasicValue ternaryOperation(
- final AbstractInsnNode insn,
- final BasicValue value1,
- final BasicValue value2,
- final BasicValue value3) throws AnalyzerException
- {
+ public BasicValue ternaryOperation(final AbstractInsnNode insn,
+ final BasicValue value1, final BasicValue value2,
+ final BasicValue value3) throws AnalyzerException {
BasicValue expected1;
BasicValue expected3;
switch (insn.getOpcode()) {
- case IASTORE:
- expected1 = newValue(Type.getType("[I"));
- expected3 = BasicValue.INT_VALUE;
- break;
- case BASTORE:
- if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
- expected1 = newValue(Type.getType("[Z"));
- } else {
- expected1 = newValue(Type.getType("[B"));
- }
- expected3 = BasicValue.INT_VALUE;
- break;
- case CASTORE:
- expected1 = newValue(Type.getType("[C"));
- expected3 = BasicValue.INT_VALUE;
- break;
- case SASTORE:
- expected1 = newValue(Type.getType("[S"));
- expected3 = BasicValue.INT_VALUE;
- break;
- case LASTORE:
- expected1 = newValue(Type.getType("[J"));
- expected3 = BasicValue.LONG_VALUE;
- break;
- case FASTORE:
- expected1 = newValue(Type.getType("[F"));
- expected3 = BasicValue.FLOAT_VALUE;
- break;
- case DASTORE:
- expected1 = newValue(Type.getType("[D"));
- expected3 = BasicValue.DOUBLE_VALUE;
- break;
- case AASTORE:
- expected1 = value1;
- expected3 = BasicValue.REFERENCE_VALUE;
- break;
- default:
- throw new Error("Internal error.");
+ case IASTORE:
+ expected1 = newValue(Type.getType("[I"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case BASTORE:
+ if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[Z"));
+ } else {
+ expected1 = newValue(Type.getType("[B"));
+ }
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case CASTORE:
+ expected1 = newValue(Type.getType("[C"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case SASTORE:
+ expected1 = newValue(Type.getType("[S"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case LASTORE:
+ expected1 = newValue(Type.getType("[J"));
+ expected3 = BasicValue.LONG_VALUE;
+ break;
+ case FASTORE:
+ expected1 = newValue(Type.getType("[F"));
+ expected3 = BasicValue.FLOAT_VALUE;
+ break;
+ case DASTORE:
+ expected1 = newValue(Type.getType("[D"));
+ expected3 = BasicValue.DOUBLE_VALUE;
+ break;
+ case AASTORE:
+ expected1 = value1;
+ expected3 = BasicValue.REFERENCE_VALUE;
+ break;
+ default:
+ throw new Error("Internal error.");
}
if (!isSubTypeOf(value1, expected1)) {
- throw new AnalyzerException(insn, "First argument", "a " + expected1
- + " array reference", value1);
+ throw new AnalyzerException(insn, "First argument", "a "
+ + expected1 + " array reference", value1);
} else if (!BasicValue.INT_VALUE.equals(value2)) {
throw new AnalyzerException(insn, "Second argument",
- BasicValue.INT_VALUE,
- value2);
+ BasicValue.INT_VALUE, value2);
} else if (!isSubTypeOf(value3, expected3)) {
- throw new AnalyzerException(insn, "Third argument", expected3, value3);
+ throw new AnalyzerException(insn, "Third argument", expected3,
+ value3);
}
return null;
}
@Override
- public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values)
- throws AnalyzerException
- {
+ public BasicValue naryOperation(final AbstractInsnNode insn,
+ final List<? extends BasicValue> values) throws AnalyzerException {
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
for (int i = 0; i < values.size(); ++i) {
if (!BasicValue.INT_VALUE.equals(values.get(i))) {
- throw new AnalyzerException(insn,
- null,
- BasicValue.INT_VALUE,
- values.get(i));
+ throw new AnalyzerException(insn, null,
+ BasicValue.INT_VALUE, values.get(i));
}
}
} else {
@@ -407,22 +389,18 @@ public class BasicVerifier extends BasicInterpreter {
Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
if (!isSubTypeOf(values.get(i++), newValue(owner))) {
throw new AnalyzerException(insn, "Method owner",
- newValue(owner),
- values.get(0));
+ newValue(owner), values.get(0));
}
}
- String desc = (opcode == INVOKEDYNAMIC)?
- ((InvokeDynamicInsnNode) insn).desc:
- ((MethodInsnNode) insn).desc;
+ String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+ : ((MethodInsnNode) insn).desc;
Type[] args = Type.getArgumentTypes(desc);
while (i < values.size()) {
BasicValue expected = newValue(args[j++]);
BasicValue encountered = values.get(i++);
if (!isSubTypeOf(encountered, expected)) {
- throw new AnalyzerException(insn,
- "Argument " + j,
- expected,
- encountered);
+ throw new AnalyzerException(insn, "Argument " + j,
+ expected, encountered);
}
}
}
@@ -430,16 +408,12 @@ public class BasicVerifier extends BasicInterpreter {
}
@Override
- public void returnOperation(
- final AbstractInsnNode insn,
- final BasicValue value,
- final BasicValue expected) throws AnalyzerException
- {
+ public void returnOperation(final AbstractInsnNode insn,
+ final BasicValue value, final BasicValue expected)
+ throws AnalyzerException {
if (!isSubTypeOf(value, expected)) {
- throw new AnalyzerException(insn,
- "Incompatible return type",
- expected,
- value);
+ throw new AnalyzerException(insn, "Incompatible return type",
+ expected, value);
}
}
@@ -448,12 +422,12 @@ public class BasicVerifier extends BasicInterpreter {
}
protected BasicValue getElementValue(final BasicValue objectArrayValue)
- throws AnalyzerException
- {
+ throws AnalyzerException {
return BasicValue.REFERENCE_VALUE;
}
- protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+ protected boolean isSubTypeOf(final BasicValue value,
+ final BasicValue expected) {
return value.equals(expected);
}
}
diff --git a/src/asm/scala/tools/asm/tree/analysis/Frame.java b/src/asm/scala/tools/asm/tree/analysis/Frame.java
index fe19c2c9ae..0d92edc4d6 100644
--- a/src/asm/scala/tools/asm/tree/analysis/Frame.java
+++ b/src/asm/scala/tools/asm/tree/analysis/Frame.java
@@ -44,10 +44,11 @@ import scala.tools.asm.tree.VarInsnNode;
/**
* A symbolic execution stack frame. A stack frame contains a set of local
* variable slots, and an operand stack. Warning: long and double values are
- * represented by <i>two</i> slots in local variables, and by <i>one</i> slot
- * in the operand stack.
+ * represented by <i>two</i> slots in local variables, and by <i>one</i> slot in
+ * the operand stack.
*
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ * type of the Value used for the analysis.
*
* @author Eric Bruneton
*/
@@ -77,8 +78,10 @@ public class Frame<V extends Value> {
/**
* Constructs a new frame with the given size.
*
- * @param nLocals the maximum number of local variables of the frame.
- * @param nStack the maximum stack size of the frame.
+ * @param nLocals
+ * the maximum number of local variables of the frame.
+ * @param nStack
+ * the maximum stack size of the frame.
*/
public Frame(final int nLocals, final int nStack) {
this.values = (V[]) new Value[nLocals + nStack];
@@ -88,7 +91,8 @@ public class Frame<V extends Value> {
/**
* Constructs a new frame that is identical to the given frame.
*
- * @param src a frame.
+ * @param src
+ * a frame.
*/
public Frame(final Frame<? extends V> src) {
this(src.locals, src.values.length - src.locals);
@@ -98,7 +102,8 @@ public class Frame<V extends Value> {
/**
* Copies the state of the given frame into this frame.
*
- * @param src a frame.
+ * @param src
+ * a frame.
* @return this frame.
*/
public Frame<V> init(final Frame<? extends V> src) {
@@ -111,8 +116,9 @@ public class Frame<V extends Value> {
/**
* Sets the expected return type of the analyzed method.
*
- * @param v the expected return type of the analyzed method, or
- * <tt>null</tt> if the method returns void.
+ * @param v
+ * the expected return type of the analyzed method, or
+ * <tt>null</tt> if the method returns void.
*/
public void setReturn(final V v) {
returnValue = v;
@@ -130,13 +136,16 @@ public class Frame<V extends Value> {
/**
* Returns the value of the given local variable.
*
- * @param i a local variable index.
+ * @param i
+ * a local variable index.
* @return the value of the given local variable.
- * @throws IndexOutOfBoundsException if the variable does not exist.
+ * @throws IndexOutOfBoundsException
+ * if the variable does not exist.
*/
public V getLocal(final int i) throws IndexOutOfBoundsException {
if (i >= locals) {
- throw new IndexOutOfBoundsException("Trying to access an inexistant local variable");
+ throw new IndexOutOfBoundsException(
+ "Trying to access an inexistant local variable");
}
return values[i];
}
@@ -144,15 +153,18 @@ public class Frame<V extends Value> {
/**
* Sets the value of the given local variable.
*
- * @param i a local variable index.
- * @param value the new value of this local variable.
- * @throws IndexOutOfBoundsException if the variable does not exist.
+ * @param i
+ * a local variable index.
+ * @param value
+ * the new value of this local variable.
+ * @throws IndexOutOfBoundsException
+ * if the variable does not exist.
*/
public void setLocal(final int i, final V value)
- throws IndexOutOfBoundsException
- {
+ throws IndexOutOfBoundsException {
if (i >= locals) {
- throw new IndexOutOfBoundsException("Trying to access an inexistant local variable "+i);
+ throw new IndexOutOfBoundsException(
+ "Trying to access an inexistant local variable " + i);
}
values[i] = value;
}
@@ -170,10 +182,11 @@ public class Frame<V extends Value> {
/**
* Returns the value of the given operand stack slot.
*
- * @param i the index of an operand stack slot.
+ * @param i
+ * the index of an operand stack slot.
* @return the value of the given operand stack slot.
- * @throws IndexOutOfBoundsException if the operand stack slot does not
- * exist.
+ * @throws IndexOutOfBoundsException
+ * if the operand stack slot does not exist.
*/
public V getStack(final int i) throws IndexOutOfBoundsException {
return values[i + locals];
@@ -190,11 +203,13 @@ public class Frame<V extends Value> {
* Pops a value from the operand stack of this frame.
*
* @return the value that has been popped from the stack.
- * @throws IndexOutOfBoundsException if the operand stack is empty.
+ * @throws IndexOutOfBoundsException
+ * if the operand stack is empty.
*/
public V pop() throws IndexOutOfBoundsException {
if (top == 0) {
- throw new IndexOutOfBoundsException("Cannot pop operand off an empty stack.");
+ throw new IndexOutOfBoundsException(
+ "Cannot pop operand off an empty stack.");
}
return values[--top + locals];
}
@@ -202,466 +217,469 @@ public class Frame<V extends Value> {
/**
* Pushes a value into the operand stack of this frame.
*
- * @param value the value that must be pushed into the stack.
- * @throws IndexOutOfBoundsException if the operand stack is full.
+ * @param value
+ * the value that must be pushed into the stack.
+ * @throws IndexOutOfBoundsException
+ * if the operand stack is full.
*/
public void push(final V value) throws IndexOutOfBoundsException {
if (top + locals >= values.length) {
- throw new IndexOutOfBoundsException("Insufficient maximum stack size.");
+ throw new IndexOutOfBoundsException(
+ "Insufficient maximum stack size.");
}
values[top++ + locals] = value;
}
- public void execute(
- final AbstractInsnNode insn,
- final Interpreter<V> interpreter) throws AnalyzerException
- {
+ public void execute(final AbstractInsnNode insn,
+ final Interpreter<V> interpreter) throws AnalyzerException {
V value1, value2, value3, value4;
List<V> values;
int var;
switch (insn.getOpcode()) {
- case Opcodes.NOP:
- break;
- case Opcodes.ACONST_NULL:
- case Opcodes.ICONST_M1:
- case Opcodes.ICONST_0:
- case Opcodes.ICONST_1:
- case Opcodes.ICONST_2:
- case Opcodes.ICONST_3:
- case Opcodes.ICONST_4:
- case Opcodes.ICONST_5:
- case Opcodes.LCONST_0:
- case Opcodes.LCONST_1:
- case Opcodes.FCONST_0:
- case Opcodes.FCONST_1:
- case Opcodes.FCONST_2:
- case Opcodes.DCONST_0:
- case Opcodes.DCONST_1:
- case Opcodes.BIPUSH:
- case Opcodes.SIPUSH:
- case Opcodes.LDC:
- push(interpreter.newOperation(insn));
- break;
- case Opcodes.ILOAD:
- case Opcodes.LLOAD:
- case Opcodes.FLOAD:
- case Opcodes.DLOAD:
- case Opcodes.ALOAD:
- push(interpreter.copyOperation(insn,
- getLocal(((VarInsnNode) insn).var)));
- break;
- case Opcodes.IALOAD:
- case Opcodes.LALOAD:
- case Opcodes.FALOAD:
- case Opcodes.DALOAD:
- case Opcodes.AALOAD:
- case Opcodes.BALOAD:
- case Opcodes.CALOAD:
- case Opcodes.SALOAD:
- value2 = pop();
- value1 = pop();
- push(interpreter.binaryOperation(insn, value1, value2));
- break;
- case Opcodes.ISTORE:
- case Opcodes.LSTORE:
- case Opcodes.FSTORE:
- case Opcodes.DSTORE:
- case Opcodes.ASTORE:
- value1 = interpreter.copyOperation(insn, pop());
- var = ((VarInsnNode) insn).var;
- setLocal(var, value1);
- if (value1.getSize() == 2) {
- setLocal(var + 1, interpreter.newValue(null));
+ case Opcodes.NOP:
+ break;
+ case Opcodes.ACONST_NULL:
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ case Opcodes.LDC:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.ILOAD:
+ case Opcodes.LLOAD:
+ case Opcodes.FLOAD:
+ case Opcodes.DLOAD:
+ case Opcodes.ALOAD:
+ push(interpreter.copyOperation(insn,
+ getLocal(((VarInsnNode) insn).var)));
+ break;
+ case Opcodes.IALOAD:
+ case Opcodes.LALOAD:
+ case Opcodes.FALOAD:
+ case Opcodes.DALOAD:
+ case Opcodes.AALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ value2 = pop();
+ value1 = pop();
+ push(interpreter.binaryOperation(insn, value1, value2));
+ break;
+ case Opcodes.ISTORE:
+ case Opcodes.LSTORE:
+ case Opcodes.FSTORE:
+ case Opcodes.DSTORE:
+ case Opcodes.ASTORE:
+ value1 = interpreter.copyOperation(insn, pop());
+ var = ((VarInsnNode) insn).var;
+ setLocal(var, value1);
+ if (value1.getSize() == 2) {
+ setLocal(var + 1, interpreter.newValue(null));
+ }
+ if (var > 0) {
+ Value local = getLocal(var - 1);
+ if (local != null && local.getSize() == 2) {
+ setLocal(var - 1, interpreter.newValue(null));
}
- if (var > 0) {
- Value local = getLocal(var - 1);
- if (local != null && local.getSize() == 2) {
- setLocal(var - 1, interpreter.newValue(null));
- }
+ }
+ break;
+ case Opcodes.IASTORE:
+ case Opcodes.LASTORE:
+ case Opcodes.FASTORE:
+ case Opcodes.DASTORE:
+ case Opcodes.AASTORE:
+ case Opcodes.BASTORE:
+ case Opcodes.CASTORE:
+ case Opcodes.SASTORE:
+ value3 = pop();
+ value2 = pop();
+ value1 = pop();
+ interpreter.ternaryOperation(insn, value1, value2, value3);
+ break;
+ case Opcodes.POP:
+ if (pop().getSize() == 2) {
+ throw new AnalyzerException(insn, "Illegal use of POP");
+ }
+ break;
+ case Opcodes.POP2:
+ if (pop().getSize() == 1) {
+ if (pop().getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of POP2");
}
- break;
- case Opcodes.IASTORE:
- case Opcodes.LASTORE:
- case Opcodes.FASTORE:
- case Opcodes.DASTORE:
- case Opcodes.AASTORE:
- case Opcodes.BASTORE:
- case Opcodes.CASTORE:
- case Opcodes.SASTORE:
- value3 = pop();
+ }
+ break;
+ case Opcodes.DUP:
+ value1 = pop();
+ if (value1.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of DUP");
+ }
+ push(value1);
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ case Opcodes.DUP_X1:
+ value1 = pop();
+ value2 = pop();
+ if (value1.getSize() != 1 || value2.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of DUP_X1");
+ }
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ break;
+ case Opcodes.DUP_X2:
+ value1 = pop();
+ if (value1.getSize() == 1) {
value2 = pop();
- value1 = pop();
- interpreter.ternaryOperation(insn, value1, value2, value3);
- break;
- case Opcodes.POP:
- if (pop().getSize() == 2) {
- throw new AnalyzerException(insn, "Illegal use of POP");
- }
- break;
- case Opcodes.POP2:
- if (pop().getSize() == 1) {
- if (pop().getSize() != 1) {
- throw new AnalyzerException(insn, "Illegal use of POP2");
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value1));
+ push(value3);
+ push(value2);
+ push(value1);
+ break;
}
+ } else {
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ break;
}
- break;
- case Opcodes.DUP:
- value1 = pop();
- if (value1.getSize() != 1) {
- throw new AnalyzerException(insn, "Illegal use of DUP");
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP_X2");
+ case Opcodes.DUP2:
+ value1 = pop();
+ if (value1.getSize() == 1) {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ push(value2);
+ push(value1);
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ break;
}
+ } else {
push(value1);
push(interpreter.copyOperation(insn, value1));
break;
- case Opcodes.DUP_X1:
- value1 = pop();
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP2");
+ case Opcodes.DUP2_X1:
+ value1 = pop();
+ if (value1.getSize() == 1) {
value2 = pop();
- if (value1.getSize() != 1 || value2.getSize() != 1) {
- throw new AnalyzerException(insn, "Illegal use of DUP_X1");
- }
- push(interpreter.copyOperation(insn, value1));
- push(value2);
- push(value1);
- break;
- case Opcodes.DUP_X2:
- value1 = pop();
- if (value1.getSize() == 1) {
- value2 = pop();
- if (value2.getSize() == 1) {
- value3 = pop();
- if (value3.getSize() == 1) {
- push(interpreter.copyOperation(insn, value1));
- push(value3);
- push(value2);
- push(value1);
- break;
- }
- } else {
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
+ push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
+ push(value3);
push(value2);
push(value1);
break;
}
}
- throw new AnalyzerException(insn, "Illegal use of DUP_X2");
- case Opcodes.DUP2:
- value1 = pop();
- if (value1.getSize() == 1) {
- value2 = pop();
- if (value2.getSize() == 1) {
- push(value2);
- push(value1);
- push(interpreter.copyOperation(insn, value2));
- push(interpreter.copyOperation(insn, value1));
- break;
- }
- } else {
- push(value1);
+ } else {
+ value2 = pop();
+ if (value2.getSize() == 1) {
push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
break;
}
- throw new AnalyzerException(insn, "Illegal use of DUP2");
- case Opcodes.DUP2_X1:
- value1 = pop();
- if (value1.getSize() == 1) {
- value2 = pop();
- if (value2.getSize() == 1) {
- value3 = pop();
- if (value3.getSize() == 1) {
+ }
+ throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
+ case Opcodes.DUP2_X2:
+ value1 = pop();
+ if (value1.getSize() == 1) {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
+ value4 = pop();
+ if (value4.getSize() == 1) {
push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
+ push(value4);
push(value3);
push(value2);
push(value1);
break;
}
- }
- } else {
- value2 = pop();
- if (value2.getSize() == 1) {
+ } else {
+ push(interpreter.copyOperation(insn, value2));
push(interpreter.copyOperation(insn, value1));
+ push(value3);
push(value2);
push(value1);
break;
}
}
- throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
- case Opcodes.DUP2_X2:
- value1 = pop();
- if (value1.getSize() == 1) {
- value2 = pop();
- if (value2.getSize() == 1) {
- value3 = pop();
- if (value3.getSize() == 1) {
- value4 = pop();
- if (value4.getSize() == 1) {
- push(interpreter.copyOperation(insn, value2));
- push(interpreter.copyOperation(insn, value1));
- push(value4);
- push(value3);
- push(value2);
- push(value1);
- break;
- }
- } else {
- push(interpreter.copyOperation(insn, value2));
- push(interpreter.copyOperation(insn, value1));
- push(value3);
- push(value2);
- push(value1);
- break;
- }
- }
- } else {
- value2 = pop();
- if (value2.getSize() == 1) {
- value3 = pop();
- if (value3.getSize() == 1) {
- push(interpreter.copyOperation(insn, value1));
- push(value3);
- push(value2);
- push(value1);
- break;
- }
- } else {
+ } else {
+ value2 = pop();
+ if (value2.getSize() == 1) {
+ value3 = pop();
+ if (value3.getSize() == 1) {
push(interpreter.copyOperation(insn, value1));
+ push(value3);
push(value2);
push(value1);
break;
}
- }
- throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
- case Opcodes.SWAP:
- value2 = pop();
- value1 = pop();
- if (value1.getSize() != 1 || value2.getSize() != 1) {
- throw new AnalyzerException(insn, "Illegal use of SWAP");
- }
- push(interpreter.copyOperation(insn, value2));
- push(interpreter.copyOperation(insn, value1));
- break;
- case Opcodes.IADD:
- case Opcodes.LADD:
- case Opcodes.FADD:
- case Opcodes.DADD:
- case Opcodes.ISUB:
- case Opcodes.LSUB:
- case Opcodes.FSUB:
- case Opcodes.DSUB:
- case Opcodes.IMUL:
- case Opcodes.LMUL:
- case Opcodes.FMUL:
- case Opcodes.DMUL:
- case Opcodes.IDIV:
- case Opcodes.LDIV:
- case Opcodes.FDIV:
- case Opcodes.DDIV:
- case Opcodes.IREM:
- case Opcodes.LREM:
- case Opcodes.FREM:
- case Opcodes.DREM:
- value2 = pop();
- value1 = pop();
- push(interpreter.binaryOperation(insn, value1, value2));
- break;
- case Opcodes.INEG:
- case Opcodes.LNEG:
- case Opcodes.FNEG:
- case Opcodes.DNEG:
- push(interpreter.unaryOperation(insn, pop()));
- break;
- case Opcodes.ISHL:
- case Opcodes.LSHL:
- case Opcodes.ISHR:
- case Opcodes.LSHR:
- case Opcodes.IUSHR:
- case Opcodes.LUSHR:
- case Opcodes.IAND:
- case Opcodes.LAND:
- case Opcodes.IOR:
- case Opcodes.LOR:
- case Opcodes.IXOR:
- case Opcodes.LXOR:
- value2 = pop();
- value1 = pop();
- push(interpreter.binaryOperation(insn, value1, value2));
- break;
- case Opcodes.IINC:
- var = ((IincInsnNode) insn).var;
- setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
- break;
- case Opcodes.I2L:
- case Opcodes.I2F:
- case Opcodes.I2D:
- case Opcodes.L2I:
- case Opcodes.L2F:
- case Opcodes.L2D:
- case Opcodes.F2I:
- case Opcodes.F2L:
- case Opcodes.F2D:
- case Opcodes.D2I:
- case Opcodes.D2L:
- case Opcodes.D2F:
- case Opcodes.I2B:
- case Opcodes.I2C:
- case Opcodes.I2S:
- push(interpreter.unaryOperation(insn, pop()));
- break;
- case Opcodes.LCMP:
- case Opcodes.FCMPL:
- case Opcodes.FCMPG:
- case Opcodes.DCMPL:
- case Opcodes.DCMPG:
- value2 = pop();
- value1 = pop();
- push(interpreter.binaryOperation(insn, value1, value2));
- break;
- case Opcodes.IFEQ:
- case Opcodes.IFNE:
- case Opcodes.IFLT:
- case Opcodes.IFGE:
- case Opcodes.IFGT:
- case Opcodes.IFLE:
- interpreter.unaryOperation(insn, pop());
- break;
- case Opcodes.IF_ICMPEQ:
- case Opcodes.IF_ICMPNE:
- case Opcodes.IF_ICMPLT:
- case Opcodes.IF_ICMPGE:
- case Opcodes.IF_ICMPGT:
- case Opcodes.IF_ICMPLE:
- case Opcodes.IF_ACMPEQ:
- case Opcodes.IF_ACMPNE:
- value2 = pop();
- value1 = pop();
- interpreter.binaryOperation(insn, value1, value2);
- break;
- case Opcodes.GOTO:
- break;
- case Opcodes.JSR:
- push(interpreter.newOperation(insn));
- break;
- case Opcodes.RET:
- break;
- case Opcodes.TABLESWITCH:
- case Opcodes.LOOKUPSWITCH:
- interpreter.unaryOperation(insn, pop());
- break;
- case Opcodes.IRETURN:
- case Opcodes.LRETURN:
- case Opcodes.FRETURN:
- case Opcodes.DRETURN:
- case Opcodes.ARETURN:
- value1 = pop();
- interpreter.unaryOperation(insn, value1);
- interpreter.returnOperation(insn, value1, returnValue);
- break;
- case Opcodes.RETURN:
- if (returnValue != null) {
- throw new AnalyzerException(insn, "Incompatible return type");
- }
- break;
- case Opcodes.GETSTATIC:
- push(interpreter.newOperation(insn));
- break;
- case Opcodes.PUTSTATIC:
- interpreter.unaryOperation(insn, pop());
- break;
- case Opcodes.GETFIELD:
- push(interpreter.unaryOperation(insn, pop()));
- break;
- case Opcodes.PUTFIELD:
- value2 = pop();
- value1 = pop();
- interpreter.binaryOperation(insn, value1, value2);
- break;
- case Opcodes.INVOKEVIRTUAL:
- case Opcodes.INVOKESPECIAL:
- case Opcodes.INVOKESTATIC:
- case Opcodes.INVOKEINTERFACE: {
- values = new ArrayList<V>();
- String desc = ((MethodInsnNode) insn).desc;
- for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
- values.add(0, pop());
- }
- if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
- values.add(0, pop());
- }
- if (Type.getReturnType(desc) == Type.VOID_TYPE) {
- interpreter.naryOperation(insn, values);
} else {
- push(interpreter.naryOperation(insn, values));
+ push(interpreter.copyOperation(insn, value1));
+ push(value2);
+ push(value1);
+ break;
}
- break;
}
- case Opcodes.INVOKEDYNAMIC: {
- values = new ArrayList<V>();
- String desc = ((InvokeDynamicInsnNode) insn).desc;
- for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
- values.add(0, pop());
- }
- if (Type.getReturnType(desc) == Type.VOID_TYPE) {
- interpreter.naryOperation(insn, values);
- } else {
- push(interpreter.naryOperation(insn, values));
- }
- break;
+ throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
+ case Opcodes.SWAP:
+ value2 = pop();
+ value1 = pop();
+ if (value1.getSize() != 1 || value2.getSize() != 1) {
+ throw new AnalyzerException(insn, "Illegal use of SWAP");
}
- case Opcodes.NEW:
- push(interpreter.newOperation(insn));
- break;
- case Opcodes.NEWARRAY:
- case Opcodes.ANEWARRAY:
- case Opcodes.ARRAYLENGTH:
- push(interpreter.unaryOperation(insn, pop()));
- break;
- case Opcodes.ATHROW:
- interpreter.unaryOperation(insn, pop());
- break;
- case Opcodes.CHECKCAST:
- case Opcodes.INSTANCEOF:
- push(interpreter.unaryOperation(insn, pop()));
- break;
- case Opcodes.MONITORENTER:
- case Opcodes.MONITOREXIT:
- interpreter.unaryOperation(insn, pop());
- break;
- case Opcodes.MULTIANEWARRAY:
- values = new ArrayList<V>();
- for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
- values.add(0, pop());
- }
+ push(interpreter.copyOperation(insn, value2));
+ push(interpreter.copyOperation(insn, value1));
+ break;
+ case Opcodes.IADD:
+ case Opcodes.LADD:
+ case Opcodes.FADD:
+ case Opcodes.DADD:
+ case Opcodes.ISUB:
+ case Opcodes.LSUB:
+ case Opcodes.FSUB:
+ case Opcodes.DSUB:
+ case Opcodes.IMUL:
+ case Opcodes.LMUL:
+ case Opcodes.FMUL:
+ case Opcodes.DMUL:
+ case Opcodes.IDIV:
+ case Opcodes.LDIV:
+ case Opcodes.FDIV:
+ case Opcodes.DDIV:
+ case Opcodes.IREM:
+ case Opcodes.LREM:
+ case Opcodes.FREM:
+ case Opcodes.DREM:
+ value2 = pop();
+ value1 = pop();
+ push(interpreter.binaryOperation(insn, value1, value2));
+ break;
+ case Opcodes.INEG:
+ case Opcodes.LNEG:
+ case Opcodes.FNEG:
+ case Opcodes.DNEG:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.ISHL:
+ case Opcodes.LSHL:
+ case Opcodes.ISHR:
+ case Opcodes.LSHR:
+ case Opcodes.IUSHR:
+ case Opcodes.LUSHR:
+ case Opcodes.IAND:
+ case Opcodes.LAND:
+ case Opcodes.IOR:
+ case Opcodes.LOR:
+ case Opcodes.IXOR:
+ case Opcodes.LXOR:
+ value2 = pop();
+ value1 = pop();
+ push(interpreter.binaryOperation(insn, value1, value2));
+ break;
+ case Opcodes.IINC:
+ var = ((IincInsnNode) insn).var;
+ setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
+ break;
+ case Opcodes.I2L:
+ case Opcodes.I2F:
+ case Opcodes.I2D:
+ case Opcodes.L2I:
+ case Opcodes.L2F:
+ case Opcodes.L2D:
+ case Opcodes.F2I:
+ case Opcodes.F2L:
+ case Opcodes.F2D:
+ case Opcodes.D2I:
+ case Opcodes.D2L:
+ case Opcodes.D2F:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.LCMP:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ value2 = pop();
+ value1 = pop();
+ push(interpreter.binaryOperation(insn, value1, value2));
+ break;
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ value2 = pop();
+ value1 = pop();
+ interpreter.binaryOperation(insn, value1, value2);
+ break;
+ case Opcodes.GOTO:
+ break;
+ case Opcodes.JSR:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.RET:
+ break;
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ value1 = pop();
+ interpreter.unaryOperation(insn, value1);
+ interpreter.returnOperation(insn, value1, returnValue);
+ break;
+ case Opcodes.RETURN:
+ if (returnValue != null) {
+ throw new AnalyzerException(insn, "Incompatible return type");
+ }
+ break;
+ case Opcodes.GETSTATIC:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.PUTSTATIC:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.GETFIELD:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.PUTFIELD:
+ value2 = pop();
+ value1 = pop();
+ interpreter.binaryOperation(insn, value1, value2);
+ break;
+ case Opcodes.INVOKEVIRTUAL:
+ case Opcodes.INVOKESPECIAL:
+ case Opcodes.INVOKESTATIC:
+ case Opcodes.INVOKEINTERFACE: {
+ values = new ArrayList<V>();
+ String desc = ((MethodInsnNode) insn).desc;
+ for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+ values.add(0, pop());
+ }
+ if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
+ values.add(0, pop());
+ }
+ if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+ interpreter.naryOperation(insn, values);
+ } else {
push(interpreter.naryOperation(insn, values));
- break;
- case Opcodes.IFNULL:
- case Opcodes.IFNONNULL:
- interpreter.unaryOperation(insn, pop());
- break;
- default:
- throw new RuntimeException("Illegal opcode "+insn.getOpcode());
+ }
+ break;
+ }
+ case Opcodes.INVOKEDYNAMIC: {
+ values = new ArrayList<V>();
+ String desc = ((InvokeDynamicInsnNode) insn).desc;
+ for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+ values.add(0, pop());
+ }
+ if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+ interpreter.naryOperation(insn, values);
+ } else {
+ push(interpreter.naryOperation(insn, values));
+ }
+ break;
+ }
+ case Opcodes.NEW:
+ push(interpreter.newOperation(insn));
+ break;
+ case Opcodes.NEWARRAY:
+ case Opcodes.ANEWARRAY:
+ case Opcodes.ARRAYLENGTH:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.ATHROW:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.CHECKCAST:
+ case Opcodes.INSTANCEOF:
+ push(interpreter.unaryOperation(insn, pop()));
+ break;
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ case Opcodes.MULTIANEWARRAY:
+ values = new ArrayList<V>();
+ for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
+ values.add(0, pop());
+ }
+ push(interpreter.naryOperation(insn, values));
+ break;
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ interpreter.unaryOperation(insn, pop());
+ break;
+ default:
+ throw new RuntimeException("Illegal opcode " + insn.getOpcode());
}
}
/**
* Merges this frame with the given frame.
*
- * @param frame a frame.
- * @param interpreter the interpreter used to merge values.
+ * @param frame
+ * a frame.
+ * @param interpreter
+ * the interpreter used to merge values.
* @return <tt>true</tt> if this frame has been changed as a result of the
* merge operation, or <tt>false</tt> otherwise.
- * @throws AnalyzerException if the frames have incompatible sizes.
+ * @throws AnalyzerException
+ * if the frames have incompatible sizes.
*/
- public boolean merge(final Frame<? extends V> frame, final Interpreter<V> interpreter)
- throws AnalyzerException
- {
+ public boolean merge(final Frame<? extends V> frame,
+ final Interpreter<V> interpreter) throws AnalyzerException {
if (top != frame.top) {
throw new AnalyzerException(null, "Incompatible stack heights");
}
boolean changes = false;
for (int i = 0; i < locals + top; ++i) {
V v = interpreter.merge(values[i], frame.values[i]);
- if (v != values[i]) {
+ if (!v.equals(values[i])) {
values[i] = v;
changes = true;
}
@@ -672,9 +690,11 @@ public class Frame<V extends Value> {
/**
* Merges this frame with the given frame (case of a RET instruction).
*
- * @param frame a frame
- * @param access the local variables that have been accessed by the
- * subroutine to which the RET instruction corresponds.
+ * @param frame
+ * a frame
+ * @param access
+ * the local variables that have been accessed by the subroutine
+ * to which the RET instruction corresponds.
* @return <tt>true</tt> if this frame has been changed as a result of the
* merge operation, or <tt>false</tt> otherwise.
*/
diff --git a/src/asm/scala/tools/asm/tree/analysis/Interpreter.java b/src/asm/scala/tools/asm/tree/analysis/Interpreter.java
index 930c8f4af8..56f4bedc00 100644
--- a/src/asm/scala/tools/asm/tree/analysis/Interpreter.java
+++ b/src/asm/scala/tools/asm/tree/analysis/Interpreter.java
@@ -42,7 +42,8 @@ import scala.tools.asm.tree.AbstractInsnNode;
* various semantic interpreters, without needing to duplicate the code to
* simulate the transfer of values.
*
- * @param <V> type of the Value used for the analysis.
+ * @param <V>
+ * type of the Value used for the analysis.
*
* @author Eric Bruneton
*/
@@ -57,12 +58,13 @@ public abstract class Interpreter<V extends Value> {
/**
* Creates a new value that represents the given type.
*
- * Called for method parameters (including <code>this</code>),
- * exception handler variable and with <code>null</code> type
- * for variables reserved by long and double types.
+ * Called for method parameters (including <code>this</code>), exception
+ * handler variable and with <code>null</code> type for variables reserved
+ * by long and double types.
*
- * @param type a primitive or reference type, or <tt>null</tt> to
- * represent an uninitialized value.
+ * @param type
+ * a primitive or reference type, or <tt>null</tt> to represent
+ * an uninitialized value.
* @return a value that represents the given type. The size of the returned
* value must be equal to the size of the given type.
*/
@@ -76,9 +78,11 @@ public abstract class Interpreter<V extends Value> {
* ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
* DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
*
- * @param insn the bytecode instruction to be interpreted.
+ * @param insn
+ * the bytecode instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
public abstract V newOperation(AbstractInsnNode insn)
throws AnalyzerException;
@@ -90,11 +94,14 @@ public abstract class Interpreter<V extends Value> {
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
* ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
*
- * @param insn the bytecode instruction to be interpreted.
- * @param value the value that must be moved by the instruction.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param value
+ * the value that must be moved by the instruction.
* @return the result of the interpretation of the given instruction. The
* returned value must be <tt>equal</tt> to the given value.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
public abstract V copyOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
@@ -109,10 +116,13 @@ public abstract class Interpreter<V extends Value> {
* PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
* INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
*
- * @param insn the bytecode instruction to be interpreted.
- * @param value the argument of the instruction to be interpreted.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param value
+ * the argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
public abstract V unaryOperation(AbstractInsnNode insn, V value)
throws AnalyzerException;
@@ -128,11 +138,15 @@ public abstract class Interpreter<V extends Value> {
* DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* IF_ACMPEQ, IF_ACMPNE, PUTFIELD
*
- * @param insn the bytecode instruction to be interpreted.
- * @param value1 the first argument of the instruction to be interpreted.
- * @param value2 the second argument of the instruction to be interpreted.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param value1
+ * the first argument of the instruction to be interpreted.
+ * @param value2
+ * the second argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
throws AnalyzerException;
@@ -143,18 +157,20 @@ public abstract class Interpreter<V extends Value> {
*
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
*
- * @param insn the bytecode instruction to be interpreted.
- * @param value1 the first argument of the instruction to be interpreted.
- * @param value2 the second argument of the instruction to be interpreted.
- * @param value3 the third argument of the instruction to be interpreted.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param value1
+ * the first argument of the instruction to be interpreted.
+ * @param value2
+ * the second argument of the instruction to be interpreted.
+ * @param value3
+ * the third argument of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
- public abstract V ternaryOperation(
- AbstractInsnNode insn,
- V value1,
- V value2,
- V value3) throws AnalyzerException;
+ public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
+ V value2, V value3) throws AnalyzerException;
/**
* Interprets a bytecode instruction with a variable number of arguments.
@@ -163,14 +179,16 @@ public abstract class Interpreter<V extends Value> {
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
* MULTIANEWARRAY and INVOKEDYNAMIC
*
- * @param insn the bytecode instruction to be interpreted.
- * @param values the arguments of the instruction to be interpreted.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param values
+ * the arguments of the instruction to be interpreted.
* @return the result of the interpretation of the given instruction.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
- public abstract V naryOperation(
- AbstractInsnNode insn,
- List< ? extends V> values) throws AnalyzerException;
+ public abstract V naryOperation(AbstractInsnNode insn,
+ List<? extends V> values) throws AnalyzerException;
/**
* Interprets a bytecode return instruction. This method is called for the
@@ -178,15 +196,17 @@ public abstract class Interpreter<V extends Value> {
*
* IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
*
- * @param insn the bytecode instruction to be interpreted.
- * @param value the argument of the instruction to be interpreted.
- * @param expected the expected return type of the analyzed method.
- * @throws AnalyzerException if an error occured during the interpretation.
+ * @param insn
+ * the bytecode instruction to be interpreted.
+ * @param value
+ * the argument of the instruction to be interpreted.
+ * @param expected
+ * the expected return type of the analyzed method.
+ * @throws AnalyzerException
+ * if an error occured during the interpretation.
*/
- public abstract void returnOperation(
- AbstractInsnNode insn,
- V value,
- V expected) throws AnalyzerException;
+ public abstract void returnOperation(AbstractInsnNode insn, V value,
+ V expected) throws AnalyzerException;
/**
* Merges two values. The merge operation must return a value that
@@ -195,8 +215,10 @@ public abstract class Interpreter<V extends Value> {
* values are integer intervals, the merged value must be an interval that
* contains the previous ones. Likewise for other types of values).
*
- * @param v a value.
- * @param w another value.
+ * @param v
+ * a value.
+ * @param w
+ * another value.
* @return the merged value. If the merged value is equal to <tt>v</tt>,
* this method <i>must</i> return <tt>v</tt>.
*/
diff --git a/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java b/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java
index c4f515d328..eaecd057ea 100644
--- a/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java
+++ b/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java
@@ -79,15 +79,15 @@ public class SimpleVerifier extends BasicVerifier {
* Constructs a new {@link SimpleVerifier} to verify a specific class. This
* class will not be loaded into the JVM since it may be incorrect.
*
- * @param currentClass the class that is verified.
- * @param currentSuperClass the super class of the class that is verified.
- * @param isInterface if the class that is verified is an interface.
+ * @param currentClass
+ * the class that is verified.
+ * @param currentSuperClass
+ * the super class of the class that is verified.
+ * @param isInterface
+ * if the class that is verified is an interface.
*/
- public SimpleVerifier(
- final Type currentClass,
- final Type currentSuperClass,
- final boolean isInterface)
- {
+ public SimpleVerifier(final Type currentClass,
+ final Type currentSuperClass, final boolean isInterface) {
this(currentClass, currentSuperClass, null, isInterface);
}
@@ -95,32 +95,25 @@ public class SimpleVerifier extends BasicVerifier {
* Constructs a new {@link SimpleVerifier} to verify a specific class. This
* class will not be loaded into the JVM since it may be incorrect.
*
- * @param currentClass the class that is verified.
- * @param currentSuperClass the super class of the class that is verified.
- * @param currentClassInterfaces the interfaces implemented by the class
- * that is verified.
- * @param isInterface if the class that is verified is an interface.
+ * @param currentClass
+ * the class that is verified.
+ * @param currentSuperClass
+ * the super class of the class that is verified.
+ * @param currentClassInterfaces
+ * the interfaces implemented by the class that is verified.
+ * @param isInterface
+ * if the class that is verified is an interface.
*/
- public SimpleVerifier(
- final Type currentClass,
- final Type currentSuperClass,
- final List<Type> currentClassInterfaces,
- final boolean isInterface)
- {
- this(ASM4,
- currentClass,
- currentSuperClass,
- currentClassInterfaces,
+ public SimpleVerifier(final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces, final boolean isInterface) {
+ this(ASM4, currentClass, currentSuperClass, currentClassInterfaces,
isInterface);
}
- protected SimpleVerifier(
- final int api,
- final Type currentClass,
- final Type currentSuperClass,
- final List<Type> currentClassInterfaces,
- final boolean isInterface)
- {
+ protected SimpleVerifier(final int api, final Type currentClass,
+ final Type currentSuperClass,
+ final List<Type> currentClassInterfaces, final boolean isInterface) {
super(api);
this.currentClass = currentClass;
this.currentSuperClass = currentSuperClass;
@@ -133,7 +126,8 @@ public class SimpleVerifier extends BasicVerifier {
* classes. This is useful if you are verifying multiple interdependent
* classes.
*
- * @param loader a <code>ClassLoader</code> to use
+ * @param loader
+ * a <code>ClassLoader</code> to use
*/
public void setClassLoader(final ClassLoader loader) {
this.loader = loader;
@@ -148,11 +142,11 @@ public class SimpleVerifier extends BasicVerifier {
boolean isArray = type.getSort() == Type.ARRAY;
if (isArray) {
switch (type.getElementType().getSort()) {
- case Type.BOOLEAN:
- case Type.CHAR:
- case Type.BYTE:
- case Type.SHORT:
- return new BasicValue(type);
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ return new BasicValue(type);
}
}
@@ -181,8 +175,7 @@ public class SimpleVerifier extends BasicVerifier {
@Override
protected BasicValue getElementValue(final BasicValue objectArrayValue)
- throws AnalyzerException
- {
+ throws AnalyzerException {
Type arrayType = objectArrayValue.getType();
if (arrayType != null) {
if (arrayType.getSort() == Type.ARRAY) {
@@ -196,28 +189,28 @@ public class SimpleVerifier extends BasicVerifier {
}
@Override
- protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) {
+ protected boolean isSubTypeOf(final BasicValue value,
+ final BasicValue expected) {
Type expectedType = expected.getType();
Type type = value.getType();
switch (expectedType.getSort()) {
- case Type.INT:
- case Type.FLOAT:
- case Type.LONG:
- case Type.DOUBLE:
- return type.equals(expectedType);
- case Type.ARRAY:
- case Type.OBJECT:
- if ("Lnull;".equals(type.getDescriptor())) {
- return true;
- } else if (type.getSort() == Type.OBJECT
- || type.getSort() == Type.ARRAY)
- {
- return isAssignableFrom(expectedType, type);
- } else {
- return false;
- }
- default:
- throw new Error("Internal error");
+ case Type.INT:
+ case Type.FLOAT:
+ case Type.LONG:
+ case Type.DOUBLE:
+ return type.equals(expectedType);
+ case Type.ARRAY:
+ case Type.OBJECT:
+ if ("Lnull;".equals(type.getDescriptor())) {
+ return true;
+ } else if (type.getSort() == Type.OBJECT
+ || type.getSort() == Type.ARRAY) {
+ return isAssignableFrom(expectedType, type);
+ } else {
+ return false;
+ }
+ default:
+ throw new Error("Internal error");
}
}
@@ -227,11 +220,9 @@ public class SimpleVerifier extends BasicVerifier {
Type t = v.getType();
Type u = w.getType();
if (t != null
- && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY))
- {
+ && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
if (u != null
- && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY))
- {
+ && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
if ("Lnull;".equals(t.getDescriptor())) {
return w;
}
@@ -288,7 +279,8 @@ public class SimpleVerifier extends BasicVerifier {
return false;
} else {
if (isInterface) {
- return u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY;
+ return u.getSort() == Type.OBJECT
+ || u.getSort() == Type.ARRAY;
}
return isAssignableFrom(t, getSuperClass(u));
}
@@ -318,8 +310,7 @@ public class SimpleVerifier extends BasicVerifier {
try {
if (t.getSort() == Type.ARRAY) {
return Class.forName(t.getDescriptor().replace('/', '.'),
- false,
- loader);
+ false, loader);
}
return Class.forName(t.getClassName(), false, loader);
} catch (ClassNotFoundException e) {
diff --git a/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java b/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java
index 067200b51e..a68086c073 100644
--- a/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java
+++ b/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java
@@ -47,8 +47,7 @@ import scala.tools.asm.tree.MethodInsnNode;
* @author Eric Bruneton
*/
public class SourceInterpreter extends Interpreter<SourceValue> implements
- Opcodes
-{
+ Opcodes {
public SourceInterpreter() {
super(ASM4);
@@ -70,125 +69,118 @@ public class SourceInterpreter extends Interpreter<SourceValue> implements
public SourceValue newOperation(final AbstractInsnNode insn) {
int size;
switch (insn.getOpcode()) {
- case LCONST_0:
- case LCONST_1:
- case DCONST_0:
- case DCONST_1:
- size = 2;
- break;
- case LDC:
- Object cst = ((LdcInsnNode) insn).cst;
- size = cst instanceof Long || cst instanceof Double ? 2 : 1;
- break;
- case GETSTATIC:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
}
return new SourceValue(size, insn);
}
@Override
- public SourceValue copyOperation(final AbstractInsnNode insn, final SourceValue value) {
+ public SourceValue copyOperation(final AbstractInsnNode insn,
+ final SourceValue value) {
return new SourceValue(value.getSize(), insn);
}
@Override
- public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value)
- {
+ public SourceValue unaryOperation(final AbstractInsnNode insn,
+ final SourceValue value) {
int size;
switch (insn.getOpcode()) {
- case LNEG:
- case DNEG:
- case I2L:
- case I2D:
- case L2D:
- case F2L:
- case F2D:
- case D2L:
- size = 2;
- break;
- case GETFIELD:
- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
- break;
- default:
- size = 1;
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
}
return new SourceValue(size, insn);
}
@Override
- public SourceValue binaryOperation(
- final AbstractInsnNode insn,
- final SourceValue value1,
- final SourceValue value2)
- {
+ public SourceValue binaryOperation(final AbstractInsnNode insn,
+ final SourceValue value1, final SourceValue value2) {
int size;
switch (insn.getOpcode()) {
- case LALOAD:
- case DALOAD:
- case LADD:
- case DADD:
- case LSUB:
- case DSUB:
- case LMUL:
- case DMUL:
- case LDIV:
- case DDIV:
- case LREM:
- case DREM:
- case LSHL:
- case LSHR:
- case LUSHR:
- case LAND:
- case LOR:
- case LXOR:
- size = 2;
- break;
- default:
- size = 1;
+ case LALOAD:
+ case DALOAD:
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ default:
+ size = 1;
}
return new SourceValue(size, insn);
}
@Override
- public SourceValue ternaryOperation(
- final AbstractInsnNode insn,
- final SourceValue value1,
- final SourceValue value2,
- final SourceValue value3)
- {
+ public SourceValue ternaryOperation(final AbstractInsnNode insn,
+ final SourceValue value1, final SourceValue value2,
+ final SourceValue value3) {
return new SourceValue(1, insn);
}
@Override
- public SourceValue naryOperation(final AbstractInsnNode insn, final List<? extends SourceValue> values) {
+ public SourceValue naryOperation(final AbstractInsnNode insn,
+ final List<? extends SourceValue> values) {
int size;
int opcode = insn.getOpcode();
if (opcode == MULTIANEWARRAY) {
size = 1;
} else {
- String desc = (opcode == INVOKEDYNAMIC)?
- ((InvokeDynamicInsnNode) insn).desc:
- ((MethodInsnNode) insn).desc;
+ String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+ : ((MethodInsnNode) insn).desc;
size = Type.getReturnType(desc).getSize();
}
return new SourceValue(size, insn);
}
@Override
- public void returnOperation(
- final AbstractInsnNode insn,
- final SourceValue value,
- final SourceValue expected)
- {
+ public void returnOperation(final AbstractInsnNode insn,
+ final SourceValue value, final SourceValue expected) {
}
@Override
public SourceValue merge(final SourceValue d, final SourceValue w) {
if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
- Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns).union((SmallSet<AbstractInsnNode>) w.insns);
+ Set<AbstractInsnNode> s = ((SmallSet<AbstractInsnNode>) d.insns)
+ .union((SmallSet<AbstractInsnNode>) w.insns);
if (s == d.insns && d.size == w.size) {
return d;
} else {
diff --git a/src/asm/scala/tools/asm/tree/analysis/SourceValue.java b/src/asm/scala/tools/asm/tree/analysis/SourceValue.java
index 57ff212fb2..40d6b68180 100644
--- a/src/asm/scala/tools/asm/tree/analysis/SourceValue.java
+++ b/src/asm/scala/tools/asm/tree/analysis/SourceValue.java
@@ -48,8 +48,8 @@ public class SourceValue implements Value {
/**
* The instructions that can produce this value. For example, for the Java
- * code below, the instructions that can produce the value of <tt>i</tt>
- * at line 5 are the txo ISTORE instructions at line 1 and 3:
+ * code below, the instructions that can produce the value of <tt>i</tt> at
+ * line 5 are the txo ISTORE instructions at line 1 and 3:
*
* <pre>
* 1: i = 0;
@@ -64,7 +64,7 @@ public class SourceValue implements Value {
public final Set<AbstractInsnNode> insns;
public SourceValue(final int size) {
- this(size, SmallSet.<AbstractInsnNode>emptySet());
+ this(size, SmallSet.<AbstractInsnNode> emptySet());
}
public SourceValue(final int size, final AbstractInsnNode insn) {
@@ -84,7 +84,7 @@ public class SourceValue implements Value {
@Override
public boolean equals(final Object value) {
if (!(value instanceof SourceValue)) {
- return false;
+ return false;
}
SourceValue v = (SourceValue) value;
return size == v.size && insns.equals(v.insns);
diff --git a/src/asm/scala/tools/asm/tree/analysis/Subroutine.java b/src/asm/scala/tools/asm/tree/analysis/Subroutine.java
index 038880ddcd..d734bbd499 100644
--- a/src/asm/scala/tools/asm/tree/analysis/Subroutine.java
+++ b/src/asm/scala/tools/asm/tree/analysis/Subroutine.java
@@ -51,11 +51,8 @@ class Subroutine {
private Subroutine() {
}
- Subroutine(
- final LabelNode start,
- final int maxLocals,
- final JumpInsnNode caller)
- {
+ Subroutine(final LabelNode start, final int maxLocals,
+ final JumpInsnNode caller) {
this.start = start;
this.access = new boolean[maxLocals];
this.callers = new ArrayList<JumpInsnNode>();
@@ -90,4 +87,4 @@ class Subroutine {
}
return changes;
}
-} \ No newline at end of file
+}
diff --git a/src/asm/scala/tools/asm/util/ASMifiable.java b/src/asm/scala/tools/asm/util/ASMifiable.java
index 6a31dd508f..95cc6e3a74 100644
--- a/src/asm/scala/tools/asm/util/ASMifiable.java
+++ b/src/asm/scala/tools/asm/util/ASMifiable.java
@@ -34,7 +34,7 @@ import java.util.Map;
import scala.tools.asm.Label;
/**
- * An {@link org.objectweb.asm.Attribute Attribute} that can print the ASM code
+ * An {@link scala.tools.asm.Attribute Attribute} that can print the ASM code
* to create an equivalent attribute.
*
* @author Eugene Kuleshov
@@ -44,10 +44,13 @@ public interface ASMifiable {
/**
* Prints the ASM code to create an attribute equal to this attribute.
*
- * @param buf a buffer used for printing Java code.
- * @param varName name of the variable in a printed code used to store
- * attribute instance.
- * @param labelNames map of label instances to their names.
+ * @param buf
+ * a buffer used for printing Java code.
+ * @param varName
+ * name of the variable in a printed code used to store attribute
+ * instance.
+ * @param labelNames
+ * map of label instances to their names.
*/
void asmify(StringBuffer buf, String varName, Map<Label, String> labelNames);
}
diff --git a/src/asm/scala/tools/asm/util/ASMifier.java b/src/asm/scala/tools/asm/util/ASMifier.java
index 5967c877d1..7e6b223853 100644
--- a/src/asm/scala/tools/asm/util/ASMifier.java
+++ b/src/asm/scala/tools/asm/util/ASMifier.java
@@ -91,11 +91,14 @@ public class ASMifier extends Printer {
/**
* Constructs a new {@link ASMifier}.
*
- * @param api the ASM API version implemented by this class. Must be one of
- * {@link Opcodes#ASM4}.
- * @param name the name of the visitor variable in the produced code.
- * @param id identifier of the annotation visitor variable in the produced
- * code.
+ * @param api
+ * the ASM API version implemented by this class. Must be one of
+ * {@link Opcodes#ASM4}.
+ * @param name
+ * the name of the visitor variable in the produced code.
+ * @param id
+ * identifier of the annotation visitor variable in the produced
+ * code.
*/
protected ASMifier(final int api, final String name, final int id) {
super(api);
@@ -105,13 +108,15 @@ public class ASMifier extends Printer {
/**
* Prints the ASM source code to generate the given class to the standard
- * output. <p> Usage: ASMifier [-debug] &lt;binary
- * class name or class file name&gt;
+ * output.
+ * <p>
+ * Usage: ASMifier [-debug] &lt;binary class name or class file name&gt;
*
- * @param args the command line arguments.
+ * @param args
+ * the command line arguments.
*
- * @throws Exception if the class cannot be found, or if an IO exception
- * occurs.
+ * @throws Exception
+ * if the class cannot be found, or if an IO exception occurs.
*/
public static void main(final String[] args) throws Exception {
int i = 0;
@@ -129,22 +134,21 @@ public class ASMifier extends Printer {
}
}
if (!ok) {
- System.err.println("Prints the ASM code to generate the given class.");
+ System.err
+ .println("Prints the ASM code to generate the given class.");
System.err.println("Usage: ASMifier [-debug] "
+ "<fully qualified class name or class file name>");
return;
}
ClassReader cr;
if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
- || args[i].indexOf('/') > -1)
- {
+ || args[i].indexOf('/') > -1) {
cr = new ClassReader(new FileInputStream(args[i]));
} else {
cr = new ClassReader(args[i]);
}
- cr.accept(new TraceClassVisitor(null,
- new ASMifier(),
- new PrintWriter(System.out)), flags);
+ cr.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(
+ System.out)), flags);
}
// ------------------------------------------------------------------------
@@ -152,14 +156,9 @@ public class ASMifier extends Printer {
// ------------------------------------------------------------------------
@Override
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
String simpleName;
int n = name.lastIndexOf('/');
if (n == -1) {
@@ -170,8 +169,8 @@ public class ASMifier extends Printer {
simpleName = name.substring(n + 1);
}
text.add("import java.util.*;\n");
- text.add("import org.objectweb.asm.*;\n");
- text.add("import org.objectweb.asm.attrs.*;\n");
+ text.add("import scala.tools.asm.*;\n");
+ text.add("import scala.tools.asm.attrs.*;\n");
text.add("public class " + simpleName + "Dump implements Opcodes {\n\n");
text.add("public static byte[] dump () throws Exception {\n\n");
text.add("ClassWriter cw = new ClassWriter(0);\n");
@@ -182,30 +181,30 @@ public class ASMifier extends Printer {
buf.setLength(0);
buf.append("cw.visit(");
switch (version) {
- case Opcodes.V1_1:
- buf.append("V1_1");
- break;
- case Opcodes.V1_2:
- buf.append("V1_2");
- break;
- case Opcodes.V1_3:
- buf.append("V1_3");
- break;
- case Opcodes.V1_4:
- buf.append("V1_4");
- break;
- case Opcodes.V1_5:
- buf.append("V1_5");
- break;
- case Opcodes.V1_6:
- buf.append("V1_6");
- break;
- case Opcodes.V1_7:
- buf.append("V1_7");
- break;
- default:
- buf.append(version);
- break;
+ case Opcodes.V1_1:
+ buf.append("V1_1");
+ break;
+ case Opcodes.V1_2:
+ buf.append("V1_2");
+ break;
+ case Opcodes.V1_3:
+ buf.append("V1_3");
+ break;
+ case Opcodes.V1_4:
+ buf.append("V1_4");
+ break;
+ case Opcodes.V1_5:
+ buf.append("V1_5");
+ break;
+ case Opcodes.V1_6:
+ buf.append("V1_6");
+ break;
+ case Opcodes.V1_7:
+ buf.append("V1_7");
+ break;
+ default:
+ buf.append(version);
+ break;
}
buf.append(", ");
appendAccess(access | ACCESS_CLASS);
@@ -242,11 +241,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
buf.setLength(0);
buf.append("cw.visitOuterClass(");
appendConstant(owner);
@@ -259,10 +255,8 @@ public class ASMifier extends Printer {
}
@Override
- public ASMifier visitClassAnnotation(
- final String desc,
- final boolean visible)
- {
+ public ASMifier visitClassAnnotation(final String desc,
+ final boolean visible) {
return visitAnnotation(desc, visible);
}
@@ -272,12 +266,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
buf.setLength(0);
buf.append("cw.visitInnerClass(");
appendConstant(name);
@@ -292,13 +282,8 @@ public class ASMifier extends Printer {
}
@Override
- public ASMifier visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public ASMifier visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
buf.setLength(0);
buf.append("{\n");
buf.append("fv = cw.visitField(");
@@ -320,13 +305,8 @@ public class ASMifier extends Printer {
}
@Override
- public ASMifier visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
+ public ASMifier visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
buf.setLength(0);
buf.append("{\n");
buf.append("mv = cw.visitMethod(");
@@ -380,11 +360,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
buf.setLength(0);
buf.append("av").append(id).append(".visitEnum(");
appendConstant(buf, name);
@@ -397,10 +374,7 @@ public class ASMifier extends Printer {
}
@Override
- public ASMifier visitAnnotation(
- final String name,
- final String desc)
- {
+ public ASMifier visitAnnotation(final String name, final String desc) {
buf.setLength(0);
buf.append("{\n");
buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
@@ -443,10 +417,8 @@ public class ASMifier extends Printer {
// ------------------------------------------------------------------------
@Override
- public ASMifier visitFieldAnnotation(
- final String desc,
- final boolean visible)
- {
+ public ASMifier visitFieldAnnotation(final String desc,
+ final boolean visible) {
return visitAnnotation(desc, visible);
}
@@ -469,9 +441,7 @@ public class ASMifier extends Printer {
@Override
public ASMifier visitAnnotationDefault() {
buf.setLength(0);
- buf.append("{\n")
- .append("av0 = ")
- .append(name)
+ buf.append("{\n").append("av0 = ").append(name)
.append(".visitAnnotationDefault();\n");
text.add(buf.toString());
ASMifier a = createASMifier("av", 0);
@@ -481,23 +451,17 @@ public class ASMifier extends Printer {
}
@Override
- public ASMifier visitMethodAnnotation(
- final String desc,
- final boolean visible)
- {
+ public ASMifier visitMethodAnnotation(final String desc,
+ final boolean visible) {
return visitAnnotation(desc, visible);
}
@Override
- public ASMifier visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ public ASMifier visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
buf.setLength(0);
- buf.append("{\n")
- .append("av0 = ").append(name).append(".visitParameterAnnotation(")
- .append(parameter)
+ buf.append("{\n").append("av0 = ").append(name)
+ .append(".visitParameterAnnotation(").append(parameter)
.append(", ");
appendConstant(desc);
buf.append(", ").append(visible).append(");\n");
@@ -519,52 +483,47 @@ public class ASMifier extends Printer {
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
buf.setLength(0);
switch (type) {
- case Opcodes.F_NEW:
- case Opcodes.F_FULL:
- declareFrameTypes(nLocal, local);
- declareFrameTypes(nStack, stack);
- if (type == Opcodes.F_NEW) {
- buf.append(name).append(".visitFrame(Opcodes.F_NEW, ");
- } else {
- buf.append(name).append(".visitFrame(Opcodes.F_FULL, ");
- }
- buf.append(nLocal).append(", new Object[] {");
- appendFrameTypes(nLocal, local);
- buf.append("}, ").append(nStack).append(", new Object[] {");
- appendFrameTypes(nStack, stack);
- buf.append('}');
- break;
- case Opcodes.F_APPEND:
- declareFrameTypes(nLocal, local);
- buf.append(name).append(".visitFrame(Opcodes.F_APPEND,")
- .append(nLocal)
- .append(", new Object[] {");
- appendFrameTypes(nLocal, local);
- buf.append("}, 0, null");
- break;
- case Opcodes.F_CHOP:
- buf.append(name).append(".visitFrame(Opcodes.F_CHOP,")
- .append(nLocal)
- .append(", null, 0, null");
- break;
- case Opcodes.F_SAME:
- buf.append(name).append(".visitFrame(Opcodes.F_SAME, 0, null, 0, null");
- break;
- case Opcodes.F_SAME1:
- declareFrameTypes(1, stack);
- buf.append(name).append(".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {");
- appendFrameTypes(1, stack);
- buf.append('}');
- break;
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ declareFrameTypes(nLocal, local);
+ declareFrameTypes(nStack, stack);
+ if (type == Opcodes.F_NEW) {
+ buf.append(name).append(".visitFrame(Opcodes.F_NEW, ");
+ } else {
+ buf.append(name).append(".visitFrame(Opcodes.F_FULL, ");
+ }
+ buf.append(nLocal).append(", new Object[] {");
+ appendFrameTypes(nLocal, local);
+ buf.append("}, ").append(nStack).append(", new Object[] {");
+ appendFrameTypes(nStack, stack);
+ buf.append('}');
+ break;
+ case Opcodes.F_APPEND:
+ declareFrameTypes(nLocal, local);
+ buf.append(name).append(".visitFrame(Opcodes.F_APPEND,")
+ .append(nLocal).append(", new Object[] {");
+ appendFrameTypes(nLocal, local);
+ buf.append("}, 0, null");
+ break;
+ case Opcodes.F_CHOP:
+ buf.append(name).append(".visitFrame(Opcodes.F_CHOP,")
+ .append(nLocal).append(", null, 0, null");
+ break;
+ case Opcodes.F_SAME:
+ buf.append(name).append(
+ ".visitFrame(Opcodes.F_SAME, 0, null, 0, null");
+ break;
+ case Opcodes.F_SAME1:
+ declareFrameTypes(1, stack);
+ buf.append(name).append(
+ ".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {");
+ appendFrameTypes(1, stack);
+ buf.append('}');
+ break;
}
buf.append(");\n");
text.add(buf.toString());
@@ -573,7 +532,8 @@ public class ASMifier extends Printer {
@Override
public void visitInsn(final int opcode) {
buf.setLength(0);
- buf.append(name).append(".visitInsn(").append(OPCODES[opcode]).append(");\n");
+ buf.append(name).append(".visitInsn(").append(OPCODES[opcode])
+ .append(");\n");
text.add(buf.toString());
}
@@ -584,43 +544,35 @@ public class ASMifier extends Printer {
.append(".visitIntInsn(")
.append(OPCODES[opcode])
.append(", ")
- .append(opcode == Opcodes.NEWARRAY
- ? TYPES[operand]
- : Integer.toString(operand))
- .append(");\n");
+ .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer
+ .toString(operand)).append(");\n");
text.add(buf.toString());
}
@Override
public void visitVarInsn(final int opcode, final int var) {
buf.setLength(0);
- buf.append(name)
- .append(".visitVarInsn(")
- .append(OPCODES[opcode])
- .append(", ")
- .append(var)
- .append(");\n");
+ buf.append(name).append(".visitVarInsn(").append(OPCODES[opcode])
+ .append(", ").append(var).append(");\n");
text.add(buf.toString());
}
@Override
public void visitTypeInsn(final int opcode, final String type) {
buf.setLength(0);
- buf.append(name).append(".visitTypeInsn(").append(OPCODES[opcode]).append(", ");
+ buf.append(name).append(".visitTypeInsn(").append(OPCODES[opcode])
+ .append(", ");
appendConstant(type);
buf.append(");\n");
text.add(buf.toString());
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
buf.setLength(0);
- buf.append(this.name).append(".visitFieldInsn(").append(OPCODES[opcode]).append(", ");
+ buf.append(this.name).append(".visitFieldInsn(")
+ .append(OPCODES[opcode]).append(", ");
appendConstant(owner);
buf.append(", ");
appendConstant(name);
@@ -631,14 +583,11 @@ public class ASMifier extends Printer {
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
buf.setLength(0);
- buf.append(this.name).append(".visitMethodInsn(").append(OPCODES[opcode]).append(", ");
+ buf.append(this.name).append(".visitMethodInsn(")
+ .append(OPCODES[opcode]).append(", ");
appendConstant(owner);
buf.append(", ");
appendConstant(name);
@@ -649,12 +598,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
buf.setLength(0);
buf.append(this.name).append(".visitInvokeDynamicInsn(");
appendConstant(name);
@@ -677,7 +622,8 @@ public class ASMifier extends Printer {
public void visitJumpInsn(final int opcode, final Label label) {
buf.setLength(0);
declareLabel(label);
- buf.append(name).append(".visitJumpInsn(").append(OPCODES[opcode]).append(", ");
+ buf.append(name).append(".visitJumpInsn(").append(OPCODES[opcode])
+ .append(", ");
appendLabel(label);
buf.append(");\n");
text.add(buf.toString());
@@ -705,34 +651,22 @@ public class ASMifier extends Printer {
@Override
public void visitIincInsn(final int var, final int increment) {
buf.setLength(0);
- buf.append(name)
- .append(".visitIincInsn(")
- .append(var)
- .append(", ")
- .append(increment)
- .append(");\n");
+ buf.append(name).append(".visitIincInsn(").append(var).append(", ")
+ .append(increment).append(");\n");
text.add(buf.toString());
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
buf.setLength(0);
for (int i = 0; i < labels.length; ++i) {
declareLabel(labels[i]);
}
declareLabel(dflt);
- buf.append(name)
- .append(".visitTableSwitchInsn(")
- .append(min)
- .append(", ")
- .append(max)
- .append(", ");
+ buf.append(name).append(".visitTableSwitchInsn(").append(min)
+ .append(", ").append(max).append(", ");
appendLabel(dflt);
buf.append(", new Label[] {");
for (int i = 0; i < labels.length; ++i) {
@@ -744,11 +678,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
buf.setLength(0);
for (int i = 0; i < labels.length; ++i) {
declareLabel(labels[i]);
@@ -780,12 +711,8 @@ public class ASMifier extends Printer {
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
buf.setLength(0);
declareLabel(start);
declareLabel(end);
@@ -803,14 +730,9 @@ public class ASMifier extends Printer {
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
buf.setLength(0);
buf.append(this.name).append(".visitLocalVariable(");
appendConstant(name);
@@ -838,12 +760,8 @@ public class ASMifier extends Printer {
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
buf.setLength(0);
- buf.append(name)
- .append(".visitMaxs(")
- .append(maxStack)
- .append(", ")
- .append(maxLocals)
- .append(");\n");
+ buf.append(name).append(".visitMaxs(").append(maxStack).append(", ")
+ .append(maxLocals).append(");\n");
text.add(buf.toString());
}
@@ -858,14 +776,9 @@ public class ASMifier extends Printer {
// Common methods
// ------------------------------------------------------------------------
- public ASMifier visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public ASMifier visitAnnotation(final String desc, final boolean visible) {
buf.setLength(0);
- buf.append("{\n")
- .append("av0 = ")
- .append(name)
+ buf.append("{\n").append("av0 = ").append(name)
.append(".visitAnnotation(");
appendConstant(desc);
buf.append(", ").append(visible).append(");\n");
@@ -895,15 +808,16 @@ public class ASMifier extends Printer {
// Utility methods
// ------------------------------------------------------------------------
- protected ASMifier createASMifier(final String name, final int id) {
+ protected ASMifier createASMifier(final String name, final int id) {
return new ASMifier(Opcodes.ASM4, name, id);
}
/**
- * Appends a string representation of the given access modifiers to {@link
- * #buf buf}.
+ * Appends a string representation of the given access modifiers to
+ * {@link #buf buf}.
*
- * @param access some access modifiers.
+ * @param access
+ * some access modifiers.
*/
void appendAccess(final int access) {
boolean first = true;
@@ -945,8 +859,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_VOLATILE) != 0
- && (access & ACCESS_FIELD) != 0)
- {
+ && (access & ACCESS_FIELD) != 0) {
if (!first) {
buf.append(" + ");
}
@@ -954,8 +867,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
- && (access & ACCESS_FIELD) == 0)
- {
+ && (access & ACCESS_FIELD) == 0) {
if (!first) {
buf.append(" + ");
}
@@ -963,8 +875,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
- && (access & ACCESS_FIELD) == 0)
- {
+ && (access & ACCESS_FIELD) == 0) {
if (!first) {
buf.append(" + ");
}
@@ -972,8 +883,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_TRANSIENT) != 0
- && (access & ACCESS_FIELD) != 0)
- {
+ && (access & ACCESS_FIELD) != 0) {
if (!first) {
buf.append(" + ");
}
@@ -981,8 +891,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0
- && (access & ACCESS_FIELD) == 0)
- {
+ && (access & ACCESS_FIELD) == 0) {
if (!first) {
buf.append(" + ");
}
@@ -991,8 +900,7 @@ public class ASMifier extends Printer {
}
if ((access & Opcodes.ACC_ENUM) != 0
&& ((access & ACCESS_CLASS) != 0
- || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0))
- {
+ || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0)) {
if (!first) {
buf.append(" + ");
}
@@ -1000,8 +908,7 @@ public class ASMifier extends Printer {
first = false;
}
if ((access & Opcodes.ACC_ANNOTATION) != 0
- && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_INNER) != 0))
- {
+ && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_INNER) != 0)) {
if (!first) {
buf.append(" + ");
}
@@ -1052,8 +959,9 @@ public class ASMifier extends Printer {
* Appends a string representation of the given constant to the given
* buffer.
*
- * @param cst an {@link Integer}, {@link Float}, {@link Long},
- * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ * @param cst
+ * an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
*/
protected void appendConstant(final Object cst) {
appendConstant(buf, cst);
@@ -1063,9 +971,11 @@ public class ASMifier extends Printer {
* Appends a string representation of the given constant to the given
* buffer.
*
- * @param buf a string buffer.
- * @param cst an {@link Integer}, {@link Float}, {@link Long},
- * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ * @param buf
+ * a string buffer.
+ * @param cst
+ * an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
*/
static void appendConstant(final StringBuffer buf, final Object cst) {
if (cst == null) {
@@ -1079,14 +989,16 @@ public class ASMifier extends Printer {
} else if (cst instanceof Handle) {
buf.append("new Handle(");
Handle h = (Handle) cst;
- buf.append("Opcodes.").append(HANDLE_TAG[h.getTag()]).append(", \"");
+ buf.append("Opcodes.").append(HANDLE_TAG[h.getTag()])
+ .append(", \"");
buf.append(h.getOwner()).append("\", \"");
buf.append(h.getName()).append("\", \"");
buf.append(h.getDesc()).append("\")");
} else if (cst instanceof Byte) {
buf.append("new Byte((byte)").append(cst).append(')');
} else if (cst instanceof Boolean) {
- buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE" : "Boolean.FALSE");
+ buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE"
+ : "Boolean.FALSE");
} else if (cst instanceof Short) {
buf.append("new Short((short)").append(cst).append(')');
} else if (cst instanceof Character) {
@@ -1125,8 +1037,7 @@ public class ASMifier extends Printer {
char[] v = (char[]) cst;
buf.append("new char[] {");
for (int i = 0; i < v.length; i++) {
- buf.append(i == 0 ? "" : ",")
- .append("(char)")
+ buf.append(i == 0 ? "" : ",").append("(char)")
.append((int) v[i]);
}
buf.append('}');
@@ -1178,27 +1089,27 @@ public class ASMifier extends Printer {
appendConstant(o[i]);
} else if (o[i] instanceof Integer) {
switch (((Integer) o[i]).intValue()) {
- case 0:
- buf.append("Opcodes.TOP");
- break;
- case 1:
- buf.append("Opcodes.INTEGER");
- break;
- case 2:
- buf.append("Opcodes.FLOAT");
- break;
- case 3:
- buf.append("Opcodes.DOUBLE");
- break;
- case 4:
- buf.append("Opcodes.LONG");
- break;
- case 5:
- buf.append("Opcodes.NULL");
- break;
- case 6:
- buf.append("Opcodes.UNINITIALIZED_THIS");
- break;
+ case 0:
+ buf.append("Opcodes.TOP");
+ break;
+ case 1:
+ buf.append("Opcodes.INTEGER");
+ break;
+ case 2:
+ buf.append("Opcodes.FLOAT");
+ break;
+ case 3:
+ buf.append("Opcodes.DOUBLE");
+ break;
+ case 4:
+ buf.append("Opcodes.LONG");
+ break;
+ case 5:
+ buf.append("Opcodes.NULL");
+ break;
+ case 6:
+ buf.append("Opcodes.UNINITIALIZED_THIS");
+ break;
}
} else {
appendLabel((Label) o[i]);
@@ -1211,7 +1122,8 @@ public class ASMifier extends Printer {
* declaration is of the form "Label lXXX = new Label();". Does nothing if
* the given label has already been declared.
*
- * @param l a label.
+ * @param l
+ * a label.
*/
protected void declareLabel(final Label l) {
if (labelNames == null) {
@@ -1227,10 +1139,11 @@ public class ASMifier extends Printer {
/**
* Appends the name of the given label to {@link #buf buf}. The given label
- * <i>must</i> already have a name. One way to ensure this is to always
- * call {@link #declareLabel declared} before calling this method.
+ * <i>must</i> already have a name. One way to ensure this is to always call
+ * {@link #declareLabel declared} before calling this method.
*
- * @param l a label.
+ * @param l
+ * a label.
*/
protected void appendLabel(final Label l) {
buf.append(labelNames.get(l));
diff --git a/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java b/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java
index 8030c14f2e..f00a8f04a2 100644
--- a/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java
+++ b/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java
@@ -65,8 +65,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
|| value instanceof byte[] || value instanceof boolean[]
|| value instanceof char[] || value instanceof short[]
|| value instanceof int[] || value instanceof long[]
- || value instanceof float[] || value instanceof double[]))
- {
+ || value instanceof float[] || value instanceof double[])) {
throw new IllegalArgumentException("Invalid annotation value");
}
if (value instanceof Type) {
@@ -81,11 +80,8 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
checkEnd();
checkName(name);
CheckMethodAdapter.checkDesc(desc, false);
@@ -98,15 +94,12 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String name,
- final String desc)
- {
+ public AnnotationVisitor visitAnnotation(final String name,
+ final String desc) {
checkEnd();
checkName(name);
CheckMethodAdapter.checkDesc(desc, false);
- return new CheckAnnotationAdapter(av == null
- ? null
+ return new CheckAnnotationAdapter(av == null ? null
: av.visitAnnotation(name, desc));
}
@@ -114,8 +107,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
public AnnotationVisitor visitArray(final String name) {
checkEnd();
checkName(name);
- return new CheckAnnotationAdapter(av == null
- ? null
+ return new CheckAnnotationAdapter(av == null ? null
: av.visitArray(name), false);
}
@@ -130,13 +122,15 @@ public class CheckAnnotationAdapter extends AnnotationVisitor {
private void checkEnd() {
if (end) {
- throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ throw new IllegalStateException(
+ "Cannot call a visit method after visitEnd has been called");
}
}
private void checkName(final String name) {
if (named && name == null) {
- throw new IllegalArgumentException("Annotation value name must not be null");
+ throw new IllegalArgumentException(
+ "Annotation value name must not be null");
}
}
}
diff --git a/src/asm/scala/tools/asm/util/CheckClassAdapter.java b/src/asm/scala/tools/asm/util/CheckClassAdapter.java
index a455322531..0bfa143a95 100644
--- a/src/asm/scala/tools/asm/util/CheckClassAdapter.java
+++ b/src/asm/scala/tools/asm/util/CheckClassAdapter.java
@@ -59,10 +59,10 @@ import scala.tools.asm.tree.analysis.SimpleVerifier;
* <i>only</i> on its arguments, but does <i>not</i> check the <i>sequence</i>
* of method calls. For example, the invalid sequence
* <tt>visitField(ACC_PUBLIC, "i", "I", null)</tt> <tt>visitField(ACC_PUBLIC,
- * "i", "D", null)</tt>
- * will <i>not</i> be detected by this class adapter.
+ * "i", "D", null)</tt> will <i>not</i> be detected by this class adapter.
*
- * <p><code>CheckClassAdapter</code> can be also used to verify bytecode
+ * <p>
+ * <code>CheckClassAdapter</code> can be also used to verify bytecode
* transformations in order to make sure transformed bytecode is sane. For
* example:
*
@@ -80,19 +80,20 @@ import scala.tools.asm.tree.analysis.SimpleVerifier;
* </pre>
*
* Above code runs transformed bytecode trough the
- * <code>CheckClassAdapter</code>. It won't be exactly the same verification
- * as JVM does, but it run data flow analysis for the code of each method and
+ * <code>CheckClassAdapter</code>. It won't be exactly the same verification as
+ * JVM does, but it run data flow analysis for the code of each method and
* checks that expectations are met for each method instruction.
*
- * <p>If method bytecode has errors, assertion text will show the erroneous
+ * <p>
+ * If method bytecode has errors, assertion text will show the erroneous
* instruction number and dump of the failed method with information about
* locals and stack slot for each instruction. For example (format is -
* insnNumber locals : stack):
*
* <pre>
- * org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
- * at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:289)
- * at org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:135)
+ * scala.tools.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
+ * at scala.tools.asm.tree.analysis.Analyzer.analyze(Analyzer.java:289)
+ * at scala.tools.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:135)
* ...
* remove()V
* 00000 LinkedBlockingQueue$Itr . . . . . . . . :
@@ -114,8 +115,9 @@ import scala.tools.asm.tree.analysis.SimpleVerifier;
* initialized. You can also see that at the beginning of the method (code
* inserted by the transformation) variable 2 is initialized.
*
- * <p>Note that when used like that, <code>CheckClassAdapter.verify()</code>
- * can trigger additional class loading, because it is using
+ * <p>
+ * Note that when used like that, <code>CheckClassAdapter.verify()</code> can
+ * trigger additional class loading, because it is using
* <code>SimpleVerifier</code>.
*
* @author Eric Bruneton
@@ -159,13 +161,15 @@ public class CheckClassAdapter extends ClassVisitor {
private boolean checkDataFlow;
/**
- * Checks a given class. <p> Usage: CheckClassAdapter &lt;binary
- * class name or class file name&gt;
+ * Checks a given class.
+ * <p>
+ * Usage: CheckClassAdapter &lt;binary class name or class file name&gt;
*
- * @param args the command line arguments.
+ * @param args
+ * the command line arguments.
*
- * @throws Exception if the class cannot be found, or if an IO exception
- * occurs.
+ * @throws Exception
+ * if the class cannot be found, or if an IO exception occurs.
*/
public static void main(final String[] args) throws Exception {
if (args.length != 1) {
@@ -187,27 +191,26 @@ public class CheckClassAdapter extends ClassVisitor {
/**
* Checks a given class.
*
- * @param cr a <code>ClassReader</code> that contains bytecode for the
- * analysis.
- * @param loader a <code>ClassLoader</code> which will be used to load
- * referenced classes. This is useful if you are verifiying multiple
- * interdependent classes.
- * @param dump true if bytecode should be printed out not only when errors
- * are found.
- * @param pw write where results going to be printed
+ * @param cr
+ * a <code>ClassReader</code> that contains bytecode for the
+ * analysis.
+ * @param loader
+ * a <code>ClassLoader</code> which will be used to load
+ * referenced classes. This is useful if you are verifiying
+ * multiple interdependent classes.
+ * @param dump
+ * true if bytecode should be printed out not only when errors
+ * are found.
+ * @param pw
+ * write where results going to be printed
*/
- public static void verify(
- final ClassReader cr,
- final ClassLoader loader,
- final boolean dump,
- final PrintWriter pw)
- {
+ public static void verify(final ClassReader cr, final ClassLoader loader,
+ final boolean dump, final PrintWriter pw) {
ClassNode cn = new ClassNode();
cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
- Type syperType = cn.superName == null
- ? null
- : Type.getObjectType(cn.superName);
+ Type syperType = cn.superName == null ? null : Type
+ .getObjectType(cn.superName);
List<MethodNode> methods = cn.methods;
List<Type> interfaces = new ArrayList<Type>();
@@ -217,9 +220,8 @@ public class CheckClassAdapter extends ClassVisitor {
for (int i = 0; i < methods.size(); ++i) {
MethodNode method = methods.get(i);
- SimpleVerifier verifier = new SimpleVerifier(Type.getObjectType(cn.name),
- syperType,
- interfaces,
+ SimpleVerifier verifier = new SimpleVerifier(
+ Type.getObjectType(cn.name), syperType, interfaces,
(cn.access & Opcodes.ACC_INTERFACE) != 0);
Analyzer<BasicValue> a = new Analyzer<BasicValue>(verifier);
if (loader != null) {
@@ -241,25 +243,22 @@ public class CheckClassAdapter extends ClassVisitor {
/**
* Checks a given class
*
- * @param cr a <code>ClassReader</code> that contains bytecode for the
- * analysis.
- * @param dump true if bytecode should be printed out not only when errors
- * are found.
- * @param pw write where results going to be printed
+ * @param cr
+ * a <code>ClassReader</code> that contains bytecode for the
+ * analysis.
+ * @param dump
+ * true if bytecode should be printed out not only when errors
+ * are found.
+ * @param pw
+ * write where results going to be printed
*/
- public static void verify(
- final ClassReader cr,
- final boolean dump,
- final PrintWriter pw)
- {
+ public static void verify(final ClassReader cr, final boolean dump,
+ final PrintWriter pw) {
verify(cr, null, dump, pw);
}
- static void printAnalyzerResult(
- MethodNode method,
- Analyzer<BasicValue> a,
- final PrintWriter pw)
- {
+ static void printAnalyzerResult(MethodNode method, Analyzer<BasicValue> a,
+ final PrintWriter pw) {
Frame<BasicValue>[] frames = a.getFrames();
Textifier t = new Textifier();
TraceMethodVisitor mv = new TraceMethodVisitor(t);
@@ -310,7 +309,8 @@ public class CheckClassAdapter extends ClassVisitor {
* this constructor</i>. Instead, they must use the
* {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
*
- * @param cv the class visitor to which this adapter must delegate calls.
+ * @param cv
+ * the class visitor to which this adapter must delegate calls.
*/
public CheckClassAdapter(final ClassVisitor cv) {
this(cv, true);
@@ -321,33 +321,34 @@ public class CheckClassAdapter extends ClassVisitor {
* this constructor</i>. Instead, they must use the
* {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version.
*
- * @param cv the class visitor to which this adapter must delegate calls.
- * @param checkDataFlow <tt>true</tt> to perform basic data flow checks, or
- * <tt>false</tt> to not perform any data flow check (see
- * {@link CheckMethodAdapter}). This option requires valid maxLocals
- * and maxStack values.
+ * @param cv
+ * the class visitor to which this adapter must delegate calls.
+ * @param checkDataFlow
+ * <tt>true</tt> to perform basic data flow checks, or
+ * <tt>false</tt> to not perform any data flow check (see
+ * {@link CheckMethodAdapter}). This option requires valid
+ * maxLocals and maxStack values.
*/
- public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow)
- {
+ public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
this(Opcodes.ASM4, cv, checkDataFlow);
}
/**
* Constructs a new {@link CheckClassAdapter}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param cv the class visitor to which this adapter must delegate calls.
- * @param checkDataFlow <tt>true</tt> to perform basic data flow checks, or
- * <tt>false</tt> to not perform any data flow check (see
- * {@link CheckMethodAdapter}). This option requires valid maxLocals
- * and maxStack values.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param cv
+ * the class visitor to which this adapter must delegate calls.
+ * @param checkDataFlow
+ * <tt>true</tt> to perform basic data flow checks, or
+ * <tt>false</tt> to not perform any data flow check (see
+ * {@link CheckMethodAdapter}). This option requires valid
+ * maxLocals and maxStack values.
*/
- protected CheckClassAdapter(
- final int api,
- final ClassVisitor cv,
- final boolean checkDataFlow)
- {
+ protected CheckClassAdapter(final int api, final ClassVisitor cv,
+ final boolean checkDataFlow) {
super(api, cv);
this.labels = new HashMap<Label, Integer>();
this.checkDataFlow = checkDataFlow;
@@ -358,14 +359,9 @@ public class CheckClassAdapter extends ClassVisitor {
// ------------------------------------------------------------------------
@Override
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
if (start) {
throw new IllegalStateException("visit must be called only once");
}
@@ -375,24 +371,25 @@ public class CheckClassAdapter extends ClassVisitor {
+ Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
+ Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
+ Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
- + Opcodes.ACC_DEPRECATED
- + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
if (name == null || !name.endsWith("package-info")) {
CheckMethodAdapter.checkInternalName(name, "class name");
}
if ("java/lang/Object".equals(name)) {
if (superName != null) {
- throw new IllegalArgumentException("The super class name of the Object class must be 'null'");
+ throw new IllegalArgumentException(
+ "The super class name of the Object class must be 'null'");
}
} else {
CheckMethodAdapter.checkInternalName(superName, "super class name");
}
if (signature != null) {
- CheckMethodAdapter.checkClassSignature(signature);
+ checkClassSignature(signature);
}
if ((access & Opcodes.ACC_INTERFACE) != 0) {
if (!"java/lang/Object".equals(superName)) {
- throw new IllegalArgumentException("The super class name of interfaces must be 'java/lang/Object'");
+ throw new IllegalArgumentException(
+ "The super class name of interfaces must be 'java/lang/Object'");
}
}
if (interfaces != null) {
@@ -409,21 +406,20 @@ public class CheckClassAdapter extends ClassVisitor {
public void visitSource(final String file, final String debug) {
checkState();
if (source) {
- throw new IllegalStateException("visitSource can be called only once.");
+ throw new IllegalStateException(
+ "visitSource can be called only once.");
}
source = true;
super.visitSource(file, debug);
}
@Override
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
checkState();
if (outer) {
- throw new IllegalStateException("visitOuterClass can be called only once.");
+ throw new IllegalStateException(
+ "visitOuterClass can be called only once.");
}
outer = true;
if (owner == null) {
@@ -436,12 +432,8 @@ public class CheckClassAdapter extends ClassVisitor {
}
@Override
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
checkState();
CheckMethodAdapter.checkInternalName(name, "class name");
if (outerName != null) {
@@ -459,52 +451,44 @@ public class CheckClassAdapter extends ClassVisitor {
}
@Override
- public FieldVisitor visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
checkState();
checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
+ Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
+ Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE
+ Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC
- + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED
- + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
CheckMethodAdapter.checkUnqualifiedName(version, name, "field name");
CheckMethodAdapter.checkDesc(desc, false);
if (signature != null) {
- CheckMethodAdapter.checkFieldSignature(signature);
+ checkFieldSignature(signature);
}
if (value != null) {
CheckMethodAdapter.checkConstant(value);
}
- FieldVisitor av = super.visitField(access, name, desc, signature, value);
+ FieldVisitor av = super
+ .visitField(access, name, desc, signature, value);
return new CheckFieldAdapter(av);
}
@Override
- public MethodVisitor visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
checkState();
checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE
+ Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC
+ Opcodes.ACC_FINAL + Opcodes.ACC_SYNCHRONIZED
+ Opcodes.ACC_BRIDGE + Opcodes.ACC_VARARGS + Opcodes.ACC_NATIVE
+ Opcodes.ACC_ABSTRACT + Opcodes.ACC_STRICT
- + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED
- + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
- CheckMethodAdapter.checkMethodIdentifier(version, name, "method name");
+ + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+ if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
+ CheckMethodAdapter.checkMethodIdentifier(version, name,
+ "method name");
+ }
CheckMethodAdapter.checkMethodDesc(desc);
if (signature != null) {
- CheckMethodAdapter.checkMethodSignature(signature);
+ checkMethodSignature(signature);
}
if (exceptions != null) {
for (int i = 0; i < exceptions.length; ++i) {
@@ -514,27 +498,19 @@ public class CheckClassAdapter extends ClassVisitor {
}
CheckMethodAdapter cma;
if (checkDataFlow) {
- cma = new CheckMethodAdapter(access,
- name,
- desc,
- super.visitMethod(access, name, desc, signature, exceptions),
- labels);
+ cma = new CheckMethodAdapter(access, name, desc, super.visitMethod(
+ access, name, desc, signature, exceptions), labels);
} else {
- cma = new CheckMethodAdapter(super.visitMethod(access,
- name,
- desc,
- signature,
- exceptions), labels);
+ cma = new CheckMethodAdapter(super.visitMethod(access, name, desc,
+ signature, exceptions), labels);
}
cma.version = version;
return cma;
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
checkState();
CheckMethodAdapter.checkDesc(desc, false);
return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
@@ -544,7 +520,8 @@ public class CheckClassAdapter extends ClassVisitor {
public void visitAttribute(final Attribute attr) {
checkState();
if (attr == null) {
- throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ throw new IllegalArgumentException(
+ "Invalid attribute (must not be null)");
}
super.visitAttribute(attr);
}
@@ -566,10 +543,12 @@ public class CheckClassAdapter extends ClassVisitor {
*/
private void checkState() {
if (!start) {
- throw new IllegalStateException("Cannot visit member before visit has been called.");
+ throw new IllegalStateException(
+ "Cannot visit member before visit has been called.");
}
if (end) {
- throw new IllegalStateException("Cannot visit member after visitEnd has been called.");
+ throw new IllegalStateException(
+ "Cannot visit member after visitEnd has been called.");
}
}
@@ -578,8 +557,10 @@ public class CheckClassAdapter extends ClassVisitor {
* method also checks that mutually incompatible flags are not set
* simultaneously.
*
- * @param access the access flags to be checked
- * @param possibleAccess the valid access flags.
+ * @param access
+ * the access flags to be checked
+ * @param possibleAccess
+ * the valid access flags.
*/
static void checkAccess(final int access, final int possibleAccess) {
if ((access & ~possibleAccess) != 0) {
@@ -590,14 +571,336 @@ public class CheckClassAdapter extends ClassVisitor {
int pri = (access & Opcodes.ACC_PRIVATE) == 0 ? 0 : 1;
int pro = (access & Opcodes.ACC_PROTECTED) == 0 ? 0 : 1;
if (pub + pri + pro > 1) {
- throw new IllegalArgumentException("public private and protected are mutually exclusive: "
- + access);
+ throw new IllegalArgumentException(
+ "public private and protected are mutually exclusive: "
+ + access);
}
int fin = (access & Opcodes.ACC_FINAL) == 0 ? 0 : 1;
int abs = (access & Opcodes.ACC_ABSTRACT) == 0 ? 0 : 1;
if (fin + abs > 1) {
- throw new IllegalArgumentException("final and abstract are mutually exclusive: "
- + access);
+ throw new IllegalArgumentException(
+ "final and abstract are mutually exclusive: " + access);
+ }
+ }
+
+ /**
+ * Checks a class signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ */
+ public static void checkClassSignature(final String signature) {
+ // ClassSignature:
+ // FormalTypeParameters? ClassTypeSignature ClassTypeSignature*
+
+ int pos = 0;
+ if (getChar(signature, 0) == '<') {
+ pos = checkFormalTypeParameters(signature, pos);
+ }
+ pos = checkClassTypeSignature(signature, pos);
+ while (getChar(signature, pos) == 'L') {
+ pos = checkClassTypeSignature(signature, pos);
+ }
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ": error at index "
+ + pos);
+ }
+ }
+
+ /**
+ * Checks a method signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ */
+ public static void checkMethodSignature(final String signature) {
+ // MethodTypeSignature:
+ // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) (
+ // ^ClassTypeSignature | ^TypeVariableSignature )*
+
+ int pos = 0;
+ if (getChar(signature, 0) == '<') {
+ pos = checkFormalTypeParameters(signature, pos);
+ }
+ pos = checkChar('(', signature, pos);
+ while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
+ pos = checkTypeSignature(signature, pos);
+ }
+ pos = checkChar(')', signature, pos);
+ if (getChar(signature, pos) == 'V') {
+ ++pos;
+ } else {
+ pos = checkTypeSignature(signature, pos);
+ }
+ while (getChar(signature, pos) == '^') {
+ ++pos;
+ if (getChar(signature, pos) == 'L') {
+ pos = checkClassTypeSignature(signature, pos);
+ } else {
+ pos = checkTypeVariableSignature(signature, pos);
+ }
+ }
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ": error at index "
+ + pos);
+ }
+ }
+
+ /**
+ * Checks a field signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ */
+ public static void checkFieldSignature(final String signature) {
+ int pos = checkFieldTypeSignature(signature, 0);
+ if (pos != signature.length()) {
+ throw new IllegalArgumentException(signature + ": error at index "
+ + pos);
+ }
+ }
+
+ /**
+ * Checks the formal type parameters of a class or method signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkFormalTypeParameters(final String signature, int pos) {
+ // FormalTypeParameters:
+ // < FormalTypeParameter+ >
+
+ pos = checkChar('<', signature, pos);
+ pos = checkFormalTypeParameter(signature, pos);
+ while (getChar(signature, pos) != '>') {
+ pos = checkFormalTypeParameter(signature, pos);
+ }
+ return pos + 1;
+ }
+
+ /**
+ * Checks a formal type parameter of a class or method signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkFormalTypeParameter(final String signature, int pos) {
+ // FormalTypeParameter:
+ // Identifier : FieldTypeSignature? (: FieldTypeSignature)*
+
+ pos = checkIdentifier(signature, pos);
+ pos = checkChar(':', signature, pos);
+ if ("L[T".indexOf(getChar(signature, pos)) != -1) {
+ pos = checkFieldTypeSignature(signature, pos);
+ }
+ while (getChar(signature, pos) == ':') {
+ pos = checkFieldTypeSignature(signature, pos + 1);
+ }
+ return pos;
+ }
+
+ /**
+ * Checks a field type signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkFieldTypeSignature(final String signature, int pos) {
+ // FieldTypeSignature:
+ // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature
+ //
+ // ArrayTypeSignature:
+ // [ TypeSignature
+
+ switch (getChar(signature, pos)) {
+ case 'L':
+ return checkClassTypeSignature(signature, pos);
+ case '[':
+ return checkTypeSignature(signature, pos + 1);
+ default:
+ return checkTypeVariableSignature(signature, pos);
}
}
+
+ /**
+ * Checks a class type signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkClassTypeSignature(final String signature, int pos) {
+ // ClassTypeSignature:
+ // L Identifier ( / Identifier )* TypeArguments? ( . Identifier
+ // TypeArguments? )* ;
+
+ pos = checkChar('L', signature, pos);
+ pos = checkIdentifier(signature, pos);
+ while (getChar(signature, pos) == '/') {
+ pos = checkIdentifier(signature, pos + 1);
+ }
+ if (getChar(signature, pos) == '<') {
+ pos = checkTypeArguments(signature, pos);
+ }
+ while (getChar(signature, pos) == '.') {
+ pos = checkIdentifier(signature, pos + 1);
+ if (getChar(signature, pos) == '<') {
+ pos = checkTypeArguments(signature, pos);
+ }
+ }
+ return checkChar(';', signature, pos);
+ }
+
+ /**
+ * Checks the type arguments in a class type signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeArguments(final String signature, int pos) {
+ // TypeArguments:
+ // < TypeArgument+ >
+
+ pos = checkChar('<', signature, pos);
+ pos = checkTypeArgument(signature, pos);
+ while (getChar(signature, pos) != '>') {
+ pos = checkTypeArgument(signature, pos);
+ }
+ return pos + 1;
+ }
+
+ /**
+ * Checks a type argument in a class type signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeArgument(final String signature, int pos) {
+ // TypeArgument:
+ // * | ( ( + | - )? FieldTypeSignature )
+
+ char c = getChar(signature, pos);
+ if (c == '*') {
+ return pos + 1;
+ } else if (c == '+' || c == '-') {
+ pos++;
+ }
+ return checkFieldTypeSignature(signature, pos);
+ }
+
+ /**
+ * Checks a type variable signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeVariableSignature(final String signature,
+ int pos) {
+ // TypeVariableSignature:
+ // T Identifier ;
+
+ pos = checkChar('T', signature, pos);
+ pos = checkIdentifier(signature, pos);
+ return checkChar(';', signature, pos);
+ }
+
+ /**
+ * Checks a type signature.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkTypeSignature(final String signature, int pos) {
+ // TypeSignature:
+ // Z | C | B | S | I | F | J | D | FieldTypeSignature
+
+ switch (getChar(signature, pos)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ return pos + 1;
+ default:
+ return checkFieldTypeSignature(signature, pos);
+ }
+ }
+
+ /**
+ * Checks an identifier.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkIdentifier(final String signature, int pos) {
+ if (!Character.isJavaIdentifierStart(getChar(signature, pos))) {
+ throw new IllegalArgumentException(signature
+ + ": identifier expected at index " + pos);
+ }
+ ++pos;
+ while (Character.isJavaIdentifierPart(getChar(signature, pos))) {
+ ++pos;
+ }
+ return pos;
+ }
+
+ /**
+ * Checks a single character.
+ *
+ * @param signature
+ * a string containing the signature that must be checked.
+ * @param pos
+ * index of first character to be checked.
+ * @return the index of the first character after the checked part.
+ */
+ private static int checkChar(final char c, final String signature, int pos) {
+ if (getChar(signature, pos) == c) {
+ return pos + 1;
+ }
+ throw new IllegalArgumentException(signature + ": '" + c
+ + "' expected at index " + pos);
+ }
+
+ /**
+ * Returns the signature car at the given index.
+ *
+ * @param signature
+ * a signature.
+ * @param pos
+ * an index in signature.
+ * @return the character at the given index, or 0 if there is no such
+ * character.
+ */
+ private static char getChar(final String signature, int pos) {
+ return pos < signature.length() ? signature.charAt(pos) : (char) 0;
+ }
}
diff --git a/src/asm/scala/tools/asm/util/CheckFieldAdapter.java b/src/asm/scala/tools/asm/util/CheckFieldAdapter.java
index bdcbe14b16..4657605936 100644
--- a/src/asm/scala/tools/asm/util/CheckFieldAdapter.java
+++ b/src/asm/scala/tools/asm/util/CheckFieldAdapter.java
@@ -46,7 +46,8 @@ public class CheckFieldAdapter extends FieldVisitor {
* this constructor</i>. Instead, they must use the
* {@link #CheckFieldAdapter(int, FieldVisitor)} version.
*
- * @param fv the field visitor to which this adapter must delegate calls.
+ * @param fv
+ * the field visitor to which this adapter must delegate calls.
*/
public CheckFieldAdapter(final FieldVisitor fv) {
this(Opcodes.ASM4, fv);
@@ -55,19 +56,19 @@ public class CheckFieldAdapter extends FieldVisitor {
/**
* Constructs a new {@link CheckFieldAdapter}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param fv the field visitor to which this adapter must delegate calls.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param fv
+ * the field visitor to which this adapter must delegate calls.
*/
protected CheckFieldAdapter(final int api, final FieldVisitor fv) {
super(api, fv);
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
checkEnd();
CheckMethodAdapter.checkDesc(desc, false);
return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
@@ -77,7 +78,8 @@ public class CheckFieldAdapter extends FieldVisitor {
public void visitAttribute(final Attribute attr) {
checkEnd();
if (attr == null) {
- throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ throw new IllegalArgumentException(
+ "Invalid attribute (must not be null)");
}
super.visitAttribute(attr);
}
@@ -91,7 +93,8 @@ public class CheckFieldAdapter extends FieldVisitor {
private void checkEnd() {
if (end) {
- throw new IllegalStateException("Cannot call a visit method after visitEnd has been called");
+ throw new IllegalStateException(
+ "Cannot call a visit method after visitEnd has been called");
}
}
}
diff --git a/src/asm/scala/tools/asm/util/CheckMethodAdapter.java b/src/asm/scala/tools/asm/util/CheckMethodAdapter.java
index 7549765421..9da01c9d6e 100644
--- a/src/asm/scala/tools/asm/util/CheckMethodAdapter.java
+++ b/src/asm/scala/tools/asm/util/CheckMethodAdapter.java
@@ -58,7 +58,7 @@ import scala.tools.asm.tree.analysis.BasicVerifier;
* arguments - such as the fact that the given opcode is correct for a given
* visit method. This adapter can also perform some basic data flow checks (more
* precisely those that can be performed without the full class hierarchy - see
- * {@link org.objectweb.asm.tree.analysis.BasicVerifier}). For instance in a
+ * {@link scala.tools.asm.tree.analysis.BasicVerifier}). For instance in a
* method whose signature is <tt>void m ()</tt>, the invalid instruction
* IRETURN, or the invalid sequence IADD L2I will be detected if the data flow
* checks are enabled. These checks are enabled by using the
@@ -75,6 +75,11 @@ public class CheckMethodAdapter extends MethodVisitor {
public int version;
/**
+ * The access flags of the method.
+ */
+ private int access;
+
+ /**
* <tt>true</tt> if the visitCode method has been called.
*/
private boolean startCode;
@@ -107,6 +112,21 @@ public class CheckMethodAdapter extends MethodVisitor {
private Set<Label> usedLabels;
/**
+ * Number of visited frames in expanded form.
+ */
+ private int expandedFrames;
+
+ /**
+ * Number of visited frames in compressed form.
+ */
+ private int compressedFrames;
+
+ /**
+ * Number of instructions before the last visited frame.
+ */
+ private int lastFrame = -1;
+
+ /**
* The exception handler ranges. Each pair of list element contains the
* start and end labels of an exception handler block.
*/
@@ -352,7 +372,8 @@ public class CheckMethodAdapter extends MethodVisitor {
* <i>Subclasses must not use this constructor</i>. Instead, they must use
* the {@link #CheckMethodAdapter(int, MethodVisitor, Map)} version.
*
- * @param mv the method visitor to which this adapter must delegate calls.
+ * @param mv
+ * the method visitor to which this adapter must delegate calls.
*/
public CheckMethodAdapter(final MethodVisitor mv) {
this(mv, new HashMap<Label, Integer>());
@@ -365,13 +386,13 @@ public class CheckMethodAdapter extends MethodVisitor {
* <i>Subclasses must not use this constructor</i>. Instead, they must use
* the {@link #CheckMethodAdapter(int, MethodVisitor, Map)} version.
*
- * @param mv the method visitor to which this adapter must delegate calls.
- * @param labels a map of already visited labels (in other methods).
+ * @param mv
+ * the method visitor to which this adapter must delegate calls.
+ * @param labels
+ * a map of already visited labels (in other methods).
*/
- public CheckMethodAdapter(
- final MethodVisitor mv,
- final Map<Label, Integer> labels)
- {
+ public CheckMethodAdapter(final MethodVisitor mv,
+ final Map<Label, Integer> labels) {
this(Opcodes.ASM4, mv, labels);
}
@@ -380,14 +401,13 @@ public class CheckMethodAdapter extends MethodVisitor {
* will not perform any data flow check (see
* {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
*
- * @param mv the method visitor to which this adapter must delegate calls.
- * @param labels a map of already visited labels (in other methods).
+ * @param mv
+ * the method visitor to which this adapter must delegate calls.
+ * @param labels
+ * a map of already visited labels (in other methods).
*/
- protected CheckMethodAdapter(
- final int api,
- final MethodVisitor mv,
- final Map<Label, Integer> labels)
- {
+ protected CheckMethodAdapter(final int api, final MethodVisitor mv,
+ final Map<Label, Integer> labels) {
super(api, mv);
this.labels = labels;
this.usedLabels = new HashSet<Label>();
@@ -400,30 +420,32 @@ public class CheckMethodAdapter extends MethodVisitor {
* signature is <tt>void m ()</tt>, the invalid instruction IRETURN, or the
* invalid sequence IADD L2I will be detected.
*
- * @param access the method's access flags.
- * @param name the method's name.
- * @param desc the method's descriptor (see {@link Type Type}).
- * @param cmv the method visitor to which this adapter must delegate calls.
- * @param labels a map of already visited labels (in other methods).
+ * @param access
+ * the method's access flags.
+ * @param name
+ * the method's name.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param cmv
+ * the method visitor to which this adapter must delegate calls.
+ * @param labels
+ * a map of already visited labels (in other methods).
*/
- public CheckMethodAdapter(
- final int access,
- final String name,
- final String desc,
- final MethodVisitor cmv,
- final Map<Label, Integer> labels)
- {
+ public CheckMethodAdapter(final int access, final String name,
+ final String desc, final MethodVisitor cmv,
+ final Map<Label, Integer> labels) {
this(new MethodNode(access, name, desc, null, null) {
@Override
public void visitEnd() {
- Analyzer<BasicValue> a = new Analyzer<BasicValue>(new BasicVerifier());
+ Analyzer<BasicValue> a = new Analyzer<BasicValue>(
+ new BasicVerifier());
try {
a.analyze("dummy", this);
} catch (Exception e) {
if (e instanceof IndexOutOfBoundsException
- && maxLocals == 0 && maxStack == 0)
- {
- throw new RuntimeException("Data flow checking option requires valid, non zero maxLocals and maxStack values.");
+ && maxLocals == 0 && maxStack == 0) {
+ throw new RuntimeException(
+ "Data flow checking option requires valid, non zero maxLocals and maxStack values.");
}
e.printStackTrace();
StringWriter sw = new StringWriter();
@@ -435,15 +457,13 @@ public class CheckMethodAdapter extends MethodVisitor {
}
accept(cmv);
}
- },
- labels);
+ }, labels);
+ this.access = access;
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
checkEndMethod();
checkDesc(desc, false);
return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
@@ -456,68 +476,68 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
checkEndMethod();
checkDesc(desc, false);
- return new CheckAnnotationAdapter(super.visitParameterAnnotation(parameter,
- desc,
- visible));
+ return new CheckAnnotationAdapter(super.visitParameterAnnotation(
+ parameter, desc, visible));
}
@Override
public void visitAttribute(final Attribute attr) {
checkEndMethod();
if (attr == null) {
- throw new IllegalArgumentException("Invalid attribute (must not be null)");
+ throw new IllegalArgumentException(
+ "Invalid attribute (must not be null)");
}
super.visitAttribute(attr);
}
@Override
public void visitCode() {
+ if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+ throw new RuntimeException("Abstract methods cannot have code");
+ }
startCode = true;
super.visitCode();
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
+ if (insnCount == lastFrame) {
+ throw new IllegalStateException(
+ "At most one frame can be visited at a given code location.");
+ }
+ lastFrame = insnCount;
int mLocal;
int mStack;
switch (type) {
- case Opcodes.F_NEW:
- case Opcodes.F_FULL:
- mLocal = Integer.MAX_VALUE;
- mStack = Integer.MAX_VALUE;
- break;
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ mLocal = Integer.MAX_VALUE;
+ mStack = Integer.MAX_VALUE;
+ break;
- case Opcodes.F_SAME:
- mLocal = 0;
- mStack = 0;
- break;
+ case Opcodes.F_SAME:
+ mLocal = 0;
+ mStack = 0;
+ break;
- case Opcodes.F_SAME1:
- mLocal = 0;
- mStack = 1;
- break;
+ case Opcodes.F_SAME1:
+ mLocal = 0;
+ mStack = 1;
+ break;
- case Opcodes.F_APPEND:
- case Opcodes.F_CHOP:
- mLocal = 3;
- mStack = 0;
- break;
+ case Opcodes.F_APPEND:
+ case Opcodes.F_CHOP:
+ mLocal = 3;
+ mStack = 0;
+ break;
- default:
- throw new IllegalArgumentException("Invalid frame type " + type);
+ default:
+ throw new IllegalArgumentException("Invalid frame type " + type);
}
if (nLocal > mLocal) {
@@ -531,19 +551,29 @@ public class CheckMethodAdapter extends MethodVisitor {
if (type != Opcodes.F_CHOP) {
if (nLocal > 0 && (local == null || local.length < nLocal)) {
- throw new IllegalArgumentException("Array local[] is shorter than nLocal");
+ throw new IllegalArgumentException(
+ "Array local[] is shorter than nLocal");
}
for (int i = 0; i < nLocal; ++i) {
checkFrameValue(local[i]);
}
}
if (nStack > 0 && (stack == null || stack.length < nStack)) {
- throw new IllegalArgumentException("Array stack[] is shorter than nStack");
+ throw new IllegalArgumentException(
+ "Array stack[] is shorter than nStack");
}
for (int i = 0; i < nStack; ++i) {
checkFrameValue(stack[i]);
}
-
+ if (type == Opcodes.F_NEW) {
+ ++expandedFrames;
+ } else {
+ ++compressedFrames;
+ }
+ if (expandedFrames > 0 && compressedFrames > 0) {
+ throw new RuntimeException(
+ "Expanded and compressed frames must not be mixed.");
+ }
super.visitFrame(type, nLocal, local, nStack, stack);
}
@@ -562,18 +592,19 @@ public class CheckMethodAdapter extends MethodVisitor {
checkEndCode();
checkOpcode(opcode, 1);
switch (opcode) {
- case Opcodes.BIPUSH:
- checkSignedByte(operand, "Invalid operand");
- break;
- case Opcodes.SIPUSH:
- checkSignedShort(operand, "Invalid operand");
- break;
- // case Constants.NEWARRAY:
- default:
- if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
- throw new IllegalArgumentException("Invalid operand (must be an array type code T_...): "
- + operand);
- }
+ case Opcodes.BIPUSH:
+ checkSignedByte(operand, "Invalid operand");
+ break;
+ case Opcodes.SIPUSH:
+ checkSignedShort(operand, "Invalid operand");
+ break;
+ // case Constants.NEWARRAY:
+ default:
+ if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
+ throw new IllegalArgumentException(
+ "Invalid operand (must be an array type code T_...): "
+ + operand);
+ }
}
super.visitIntInsn(opcode, operand);
++insnCount;
@@ -596,20 +627,16 @@ public class CheckMethodAdapter extends MethodVisitor {
checkOpcode(opcode, 3);
checkInternalName(type, "type");
if (opcode == Opcodes.NEW && type.charAt(0) == '[') {
- throw new IllegalArgumentException("NEW cannot be used to create arrays: "
- + type);
+ throw new IllegalArgumentException(
+ "NEW cannot be used to create arrays: " + type);
}
super.visitTypeInsn(opcode, type);
++insnCount;
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
checkStartCode();
checkEndCode();
checkOpcode(opcode, 4);
@@ -621,16 +648,14 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
checkStartCode();
checkEndCode();
checkOpcode(opcode, 5);
- checkMethodIdentifier(version, name, "name");
+ if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
+ checkMethodIdentifier(version, name, "name");
+ }
checkInternalName(owner, "owner");
checkMethodDesc(desc);
super.visitMethodInsn(opcode, owner, name, desc);
@@ -638,19 +663,14 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
checkStartCode();
checkEndCode();
checkMethodIdentifier(version, name, "name");
checkMethodDesc(desc);
if (bsm.getTag() != Opcodes.H_INVOKESTATIC
- && bsm.getTag() != Opcodes.H_NEWINVOKESPECIAL)
- {
+ && bsm.getTag() != Opcodes.H_NEWINVOKESPECIAL) {
throw new IllegalArgumentException("invalid handle tag "
+ bsm.getTag());
}
@@ -705,12 +725,8 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
checkStartCode();
checkEndCode();
if (max < min) {
@@ -720,7 +736,8 @@ public class CheckMethodAdapter extends MethodVisitor {
checkLabel(dflt, false, "default label");
checkNonDebugLabel(dflt);
if (labels == null || labels.length != max - min + 1) {
- throw new IllegalArgumentException("There must be max - min + 1 labels");
+ throw new IllegalArgumentException(
+ "There must be max - min + 1 labels");
}
for (int i = 0; i < labels.length; ++i) {
checkLabel(labels[i], false, "label at index " + i);
@@ -734,17 +751,15 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
checkEndCode();
checkStartCode();
checkLabel(dflt, false, "default label");
checkNonDebugLabel(dflt);
if (keys == null || labels == null || keys.length != labels.length) {
- throw new IllegalArgumentException("There must be the same number of keys and labels");
+ throw new IllegalArgumentException(
+ "There must be the same number of keys and labels");
}
for (int i = 0; i < labels.length; ++i) {
checkLabel(labels[i], false, "label at index " + i);
@@ -764,28 +779,26 @@ public class CheckMethodAdapter extends MethodVisitor {
checkEndCode();
checkDesc(desc, false);
if (desc.charAt(0) != '[') {
- throw new IllegalArgumentException("Invalid descriptor (must be an array type descriptor): "
- + desc);
+ throw new IllegalArgumentException(
+ "Invalid descriptor (must be an array type descriptor): "
+ + desc);
}
if (dims < 1) {
- throw new IllegalArgumentException("Invalid dimensions (must be greater than 0): "
- + dims);
+ throw new IllegalArgumentException(
+ "Invalid dimensions (must be greater than 0): " + dims);
}
if (dims > desc.lastIndexOf('[') + 1) {
- throw new IllegalArgumentException("Invalid dimensions (must not be greater than dims(desc)): "
- + dims);
+ throw new IllegalArgumentException(
+ "Invalid dimensions (must not be greater than dims(desc)): "
+ + dims);
}
super.visitMultiANewArrayInsn(desc, dims);
++insnCount;
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
checkStartCode();
checkEndCode();
checkLabel(start, false, "start label");
@@ -795,9 +808,9 @@ public class CheckMethodAdapter extends MethodVisitor {
checkNonDebugLabel(end);
checkNonDebugLabel(handler);
if (labels.get(start) != null || labels.get(end) != null
- || labels.get(handler) != null)
- {
- throw new IllegalStateException("Try catch blocks must be visited before their labels");
+ || labels.get(handler) != null) {
+ throw new IllegalStateException(
+ "Try catch blocks must be visited before their labels");
}
if (type != null) {
checkInternalName(type, "type");
@@ -808,14 +821,9 @@ public class CheckMethodAdapter extends MethodVisitor {
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
checkStartCode();
checkEndCode();
checkUnqualifiedName(version, name, "name");
@@ -826,7 +834,8 @@ public class CheckMethodAdapter extends MethodVisitor {
int s = labels.get(start).intValue();
int e = labels.get(end).intValue();
if (e < s) {
- throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)");
+ throw new IllegalArgumentException(
+ "Invalid start and end labels (end must be greater than start)");
}
super.visitLocalVariable(name, desc, signature, start, end, index);
}
@@ -850,14 +859,16 @@ public class CheckMethodAdapter extends MethodVisitor {
throw new IllegalStateException("Undefined label used");
}
}
- for (int i = 0; i < handlers.size(); ) {
+ for (int i = 0; i < handlers.size();) {
Integer start = labels.get(handlers.get(i++));
Integer end = labels.get(handlers.get(i++));
if (start == null || end == null) {
- throw new IllegalStateException("Undefined try catch block labels");
+ throw new IllegalStateException(
+ "Undefined try catch block labels");
}
if (end.intValue() <= start.intValue()) {
- throw new IllegalStateException("Emty try catch block handler range");
+ throw new IllegalStateException(
+ "Emty try catch block handler range");
}
}
checkUnsignedShort(maxStack, "Invalid max stack");
@@ -879,7 +890,8 @@ public class CheckMethodAdapter extends MethodVisitor {
*/
void checkStartCode() {
if (!startCode) {
- throw new IllegalStateException("Cannot visit instructions before visitCode has been called.");
+ throw new IllegalStateException(
+ "Cannot visit instructions before visitCode has been called.");
}
}
@@ -888,7 +900,8 @@ public class CheckMethodAdapter extends MethodVisitor {
*/
void checkEndCode() {
if (endCode) {
- throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called.");
+ throw new IllegalStateException(
+ "Cannot visit instructions after visitMaxs has been called.");
}
}
@@ -897,21 +910,22 @@ public class CheckMethodAdapter extends MethodVisitor {
*/
void checkEndMethod() {
if (endMethod) {
- throw new IllegalStateException("Cannot visit elements after visitEnd has been called.");
+ throw new IllegalStateException(
+ "Cannot visit elements after visitEnd has been called.");
}
}
/**
* Checks a stack frame value.
*
- * @param value the value to be checked.
+ * @param value
+ * the value to be checked.
*/
void checkFrameValue(final Object value) {
if (value == Opcodes.TOP || value == Opcodes.INTEGER
|| value == Opcodes.FLOAT || value == Opcodes.LONG
|| value == Opcodes.DOUBLE || value == Opcodes.NULL
- || value == Opcodes.UNINITIALIZED_THIS)
- {
+ || value == Opcodes.UNINITIALIZED_THIS) {
return;
}
if (value instanceof String) {
@@ -929,8 +943,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the type of the given opcode is equal to the given type.
*
- * @param opcode the opcode to be checked.
- * @param type the expected opcode type.
+ * @param opcode
+ * the opcode to be checked.
+ * @param type
+ * the expected opcode type.
*/
static void checkOpcode(final int opcode, final int type) {
if (opcode < 0 || opcode > 199 || TYPE[opcode] != type) {
@@ -941,8 +957,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given value is a signed byte.
*
- * @param value the value to be checked.
- * @param msg an message to be used in case of error.
+ * @param value
+ * the value to be checked.
+ * @param msg
+ * an message to be used in case of error.
*/
static void checkSignedByte(final int value, final String msg) {
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
@@ -954,8 +972,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given value is a signed short.
*
- * @param value the value to be checked.
- * @param msg an message to be used in case of error.
+ * @param value
+ * the value to be checked.
+ * @param msg
+ * an message to be used in case of error.
*/
static void checkSignedShort(final int value, final String msg) {
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
@@ -967,8 +987,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given value is an unsigned short.
*
- * @param value the value to be checked.
- * @param msg an message to be used in case of error.
+ * @param value
+ * the value to be checked.
+ * @param msg
+ * an message to be used in case of error.
*/
static void checkUnsignedShort(final int value, final String msg) {
if (value < 0 || value > 65535) {
@@ -981,13 +1003,13 @@ public class CheckMethodAdapter extends MethodVisitor {
* Checks that the given value is an {@link Integer}, a{@link Float}, a
* {@link Long}, a {@link Double} or a {@link String}.
*
- * @param cst the value to be checked.
+ * @param cst
+ * the value to be checked.
*/
static void checkConstant(final Object cst) {
if (!(cst instanceof Integer) && !(cst instanceof Float)
&& !(cst instanceof Long) && !(cst instanceof Double)
- && !(cst instanceof String))
- {
+ && !(cst instanceof String)) {
throw new IllegalArgumentException("Invalid constant: " + cst);
}
}
@@ -999,19 +1021,21 @@ public class CheckMethodAdapter extends MethodVisitor {
throw new IllegalArgumentException("Illegal LDC constant value");
}
if (s != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) {
- throw new IllegalArgumentException("ldc of a constant class requires at least version 1.5");
+ throw new IllegalArgumentException(
+ "ldc of a constant class requires at least version 1.5");
}
if (s == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) {
- throw new IllegalArgumentException("ldc of a method type requires at least version 1.7");
+ throw new IllegalArgumentException(
+ "ldc of a method type requires at least version 1.7");
}
} else if (cst instanceof Handle) {
if ((version & 0xFFFF) < Opcodes.V1_7) {
- throw new IllegalArgumentException("ldc of a handle requires at least version 1.7");
+ throw new IllegalArgumentException(
+ "ldc of a handle requires at least version 1.7");
}
int tag = ((Handle) cst).getTag();
if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) {
- throw new IllegalArgumentException("invalid handle tag "
- + tag);
+ throw new IllegalArgumentException("invalid handle tag " + tag);
}
} else {
checkConstant(cst);
@@ -1021,15 +1045,15 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given string is a valid unqualified name.
*
- * @param version the class version.
- * @param name the string to be checked.
- * @param msg a message to be used in case of error.
+ * @param version
+ * the class version.
+ * @param name
+ * the string to be checked.
+ * @param msg
+ * a message to be used in case of error.
*/
- static void checkUnqualifiedName(
- int version,
- final String name,
- final String msg)
- {
+ static void checkUnqualifiedName(int version, final String name,
+ final String msg) {
if ((version & 0xFFFF) < Opcodes.V1_5) {
checkIdentifier(name, msg);
} else {
@@ -1045,8 +1069,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given string is a valid Java identifier.
*
- * @param name the string to be checked.
- * @param msg a message to be used in case of error.
+ * @param name
+ * the string to be checked.
+ * @param msg
+ * a message to be used in case of error.
*/
static void checkIdentifier(final String name, final String msg) {
checkIdentifier(name, 0, -1, msg);
@@ -1055,21 +1081,20 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given substring is a valid Java identifier.
*
- * @param name the string to be checked.
- * @param start index of the first character of the identifier (inclusive).
- * @param end index of the last character of the identifier (exclusive). -1
- * is equivalent to <tt>name.length()</tt> if name is not
- * <tt>null</tt>.
- * @param msg a message to be used in case of error.
+ * @param name
+ * the string to be checked.
+ * @param start
+ * index of the first character of the identifier (inclusive).
+ * @param end
+ * index of the last character of the identifier (exclusive). -1
+ * is equivalent to <tt>name.length()</tt> if name is not
+ * <tt>null</tt>.
+ * @param msg
+ * a message to be used in case of error.
*/
- static void checkIdentifier(
- final String name,
- final int start,
- final int end,
- final String msg)
- {
- if (name == null || (end == -1 ? name.length() <= start : end <= start))
- {
+ static void checkIdentifier(final String name, final int start,
+ final int end, final String msg) {
+ if (name == null || (end == -1 ? name.length() <= start : end <= start)) {
throw new IllegalArgumentException("Invalid " + msg
+ " (must not be null or empty)");
}
@@ -1087,25 +1112,21 @@ public class CheckMethodAdapter extends MethodVisitor {
}
/**
- * Checks that the given string is a valid Java identifier or is equal to
- * '&lt;init&gt;' or '&lt;clinit&gt;'.
+ * Checks that the given string is a valid Java identifier.
*
- * @param version the class version.
- * @param name the string to be checked.
- * @param msg a message to be used in case of error.
+ * @param version
+ * the class version.
+ * @param name
+ * the string to be checked.
+ * @param msg
+ * a message to be used in case of error.
*/
- static void checkMethodIdentifier(
- int version,
- final String name,
- final String msg)
- {
+ static void checkMethodIdentifier(int version, final String name,
+ final String msg) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Invalid " + msg
+ " (must not be null or empty)");
}
- if ("<init>".equals(name) || "<clinit>".equals(name)) {
- return;
- }
if ((version & 0xFFFF) >= Opcodes.V1_5) {
for (int i = 0; i < name.length(); ++i) {
if (".;[/<>".indexOf(name.charAt(i)) != -1) {
@@ -1116,17 +1137,19 @@ public class CheckMethodAdapter extends MethodVisitor {
return;
}
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
- throw new IllegalArgumentException("Invalid "
- + msg
- + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
- + name);
+ throw new IllegalArgumentException(
+ "Invalid "
+ + msg
+ + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
+ + name);
}
for (int i = 1; i < name.length(); ++i) {
if (!Character.isJavaIdentifierPart(name.charAt(i))) {
- throw new IllegalArgumentException("Invalid "
- + msg
- + " (must be '<init>' or '<clinit>' or a valid Java identifier): "
- + name);
+ throw new IllegalArgumentException(
+ "Invalid "
+ + msg
+ + " (must be '<init>' or '<clinit>' or a valid Java identifier): "
+ + name);
}
}
}
@@ -1134,8 +1157,10 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given string is a valid internal class name.
*
- * @param name the string to be checked.
- * @param msg a message to be used in case of error.
+ * @param name
+ * the string to be checked.
+ * @param msg
+ * a message to be used in case of error.
*/
static void checkInternalName(final String name, final String msg) {
if (name == null || name.length() == 0) {
@@ -1152,19 +1177,19 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given substring is a valid internal class name.
*
- * @param name the string to be checked.
- * @param start index of the first character of the identifier (inclusive).
- * @param end index of the last character of the identifier (exclusive). -1
- * is equivalent to <tt>name.length()</tt> if name is not
- * <tt>null</tt>.
- * @param msg a message to be used in case of error.
+ * @param name
+ * the string to be checked.
+ * @param start
+ * index of the first character of the identifier (inclusive).
+ * @param end
+ * index of the last character of the identifier (exclusive). -1
+ * is equivalent to <tt>name.length()</tt> if name is not
+ * <tt>null</tt>.
+ * @param msg
+ * a message to be used in case of error.
*/
- static void checkInternalName(
- final String name,
- final int start,
- final int end,
- final String msg)
- {
+ static void checkInternalName(final String name, final int start,
+ final int end, final String msg) {
int max = end == -1 ? name.length() : end;
try {
int begin = start;
@@ -1178,18 +1203,21 @@ public class CheckMethodAdapter extends MethodVisitor {
begin = slash + 1;
} while (slash != max);
} catch (IllegalArgumentException _) {
- throw new IllegalArgumentException("Invalid "
- + msg
- + " (must be a fully qualified class name in internal form): "
- + name);
+ throw new IllegalArgumentException(
+ "Invalid "
+ + msg
+ + " (must be a fully qualified class name in internal form): "
+ + name);
}
}
/**
* Checks that the given string is a valid type descriptor.
*
- * @param desc the string to be checked.
- * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+ * @param desc
+ * the string to be checked.
+ * @param canBeVoid
+ * <tt>true</tt> if <tt>V</tt> can be considered valid.
*/
static void checkDesc(final String desc, final boolean canBeVoid) {
int end = checkDesc(desc, 0, canBeVoid);
@@ -1201,75 +1229,77 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that a the given substring is a valid type descriptor.
*
- * @param desc the string to be checked.
- * @param start index of the first character of the identifier (inclusive).
- * @param canBeVoid <tt>true</tt> if <tt>V</tt> can be considered valid.
+ * @param desc
+ * the string to be checked.
+ * @param start
+ * index of the first character of the identifier (inclusive).
+ * @param canBeVoid
+ * <tt>true</tt> if <tt>V</tt> can be considered valid.
* @return the index of the last character of the type decriptor, plus one.
*/
- static int checkDesc(
- final String desc,
- final int start,
- final boolean canBeVoid)
- {
+ static int checkDesc(final String desc, final int start,
+ final boolean canBeVoid) {
if (desc == null || start >= desc.length()) {
- throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)");
+ throw new IllegalArgumentException(
+ "Invalid type descriptor (must not be null or empty)");
}
int index;
switch (desc.charAt(start)) {
- case 'V':
- if (canBeVoid) {
- return start + 1;
- } else {
- throw new IllegalArgumentException("Invalid descriptor: "
- + desc);
- }
- case 'Z':
- case 'C':
- case 'B':
- case 'S':
- case 'I':
- case 'F':
- case 'J':
- case 'D':
+ case 'V':
+ if (canBeVoid) {
return start + 1;
- case '[':
- index = start + 1;
- while (index < desc.length() && desc.charAt(index) == '[') {
- ++index;
- }
- if (index < desc.length()) {
- return checkDesc(desc, index, false);
- } else {
- throw new IllegalArgumentException("Invalid descriptor: "
- + desc);
- }
- case 'L':
- index = desc.indexOf(';', start);
- if (index == -1 || index - start < 2) {
- throw new IllegalArgumentException("Invalid descriptor: "
- + desc);
- }
- try {
- checkInternalName(desc, start + 1, index, null);
- } catch (IllegalArgumentException _) {
- throw new IllegalArgumentException("Invalid descriptor: "
- + desc);
- }
- return index + 1;
- default:
+ } else {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ return start + 1;
+ case '[':
+ index = start + 1;
+ while (index < desc.length() && desc.charAt(index) == '[') {
+ ++index;
+ }
+ if (index < desc.length()) {
+ return checkDesc(desc, index, false);
+ } else {
throw new IllegalArgumentException("Invalid descriptor: "
+ desc);
+ }
+ case 'L':
+ index = desc.indexOf(';', start);
+ if (index == -1 || index - start < 2) {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ try {
+ checkInternalName(desc, start + 1, index, null);
+ } catch (IllegalArgumentException _) {
+ throw new IllegalArgumentException("Invalid descriptor: "
+ + desc);
+ }
+ return index + 1;
+ default:
+ throw new IllegalArgumentException("Invalid descriptor: " + desc);
}
}
/**
* Checks that the given string is a valid method descriptor.
*
- * @param desc the string to be checked.
+ * @param desc
+ * the string to be checked.
*/
static void checkMethodDesc(final String desc) {
if (desc == null || desc.length() == 0) {
- throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)");
+ throw new IllegalArgumentException(
+ "Invalid method descriptor (must not be null or empty)");
}
if (desc.charAt(0) != '(' || desc.length() < 3) {
throw new IllegalArgumentException("Invalid descriptor: " + desc);
@@ -1291,322 +1321,18 @@ public class CheckMethodAdapter extends MethodVisitor {
}
/**
- * Checks a class signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- static void checkClassSignature(final String signature) {
- // ClassSignature:
- // FormalTypeParameters? ClassTypeSignature ClassTypeSignature*
-
- int pos = 0;
- if (getChar(signature, 0) == '<') {
- pos = checkFormalTypeParameters(signature, pos);
- }
- pos = checkClassTypeSignature(signature, pos);
- while (getChar(signature, pos) == 'L') {
- pos = checkClassTypeSignature(signature, pos);
- }
- if (pos != signature.length()) {
- throw new IllegalArgumentException(signature + ": error at index "
- + pos);
- }
- }
-
- /**
- * Checks a method signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- static void checkMethodSignature(final String signature) {
- // MethodTypeSignature:
- // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) (
- // ^ClassTypeSignature | ^TypeVariableSignature )*
-
- int pos = 0;
- if (getChar(signature, 0) == '<') {
- pos = checkFormalTypeParameters(signature, pos);
- }
- pos = checkChar('(', signature, pos);
- while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) {
- pos = checkTypeSignature(signature, pos);
- }
- pos = checkChar(')', signature, pos);
- if (getChar(signature, pos) == 'V') {
- ++pos;
- } else {
- pos = checkTypeSignature(signature, pos);
- }
- while (getChar(signature, pos) == '^') {
- ++pos;
- if (getChar(signature, pos) == 'L') {
- pos = checkClassTypeSignature(signature, pos);
- } else {
- pos = checkTypeVariableSignature(signature, pos);
- }
- }
- if (pos != signature.length()) {
- throw new IllegalArgumentException(signature + ": error at index "
- + pos);
- }
- }
-
- /**
- * Checks a field signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- static void checkFieldSignature(final String signature) {
- int pos = checkFieldTypeSignature(signature, 0);
- if (pos != signature.length()) {
- throw new IllegalArgumentException(signature + ": error at index "
- + pos);
- }
- }
-
- /**
- * Checks the formal type parameters of a class or method signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkFormalTypeParameters(final String signature, int pos)
- {
- // FormalTypeParameters:
- // < FormalTypeParameter+ >
-
- pos = checkChar('<', signature, pos);
- pos = checkFormalTypeParameter(signature, pos);
- while (getChar(signature, pos) != '>') {
- pos = checkFormalTypeParameter(signature, pos);
- }
- return pos + 1;
- }
-
- /**
- * Checks a formal type parameter of a class or method signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkFormalTypeParameter(final String signature, int pos)
- {
- // FormalTypeParameter:
- // Identifier : FieldTypeSignature? (: FieldTypeSignature)*
-
- pos = checkIdentifier(signature, pos);
- pos = checkChar(':', signature, pos);
- if ("L[T".indexOf(getChar(signature, pos)) != -1) {
- pos = checkFieldTypeSignature(signature, pos);
- }
- while (getChar(signature, pos) == ':') {
- pos = checkFieldTypeSignature(signature, pos + 1);
- }
- return pos;
- }
-
- /**
- * Checks a field type signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkFieldTypeSignature(final String signature, int pos)
- {
- // FieldTypeSignature:
- // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature
- //
- // ArrayTypeSignature:
- // [ TypeSignature
-
- switch (getChar(signature, pos)) {
- case 'L':
- return checkClassTypeSignature(signature, pos);
- case '[':
- return checkTypeSignature(signature, pos + 1);
- default:
- return checkTypeVariableSignature(signature, pos);
- }
- }
-
- /**
- * Checks a class type signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkClassTypeSignature(final String signature, int pos)
- {
- // ClassTypeSignature:
- // L Identifier ( / Identifier )* TypeArguments? ( . Identifier
- // TypeArguments? )* ;
-
- pos = checkChar('L', signature, pos);
- pos = checkIdentifier(signature, pos);
- while (getChar(signature, pos) == '/') {
- pos = checkIdentifier(signature, pos + 1);
- }
- if (getChar(signature, pos) == '<') {
- pos = checkTypeArguments(signature, pos);
- }
- while (getChar(signature, pos) == '.') {
- pos = checkIdentifier(signature, pos + 1);
- if (getChar(signature, pos) == '<') {
- pos = checkTypeArguments(signature, pos);
- }
- }
- return checkChar(';', signature, pos);
- }
-
- /**
- * Checks the type arguments in a class type signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkTypeArguments(final String signature, int pos) {
- // TypeArguments:
- // < TypeArgument+ >
-
- pos = checkChar('<', signature, pos);
- pos = checkTypeArgument(signature, pos);
- while (getChar(signature, pos) != '>') {
- pos = checkTypeArgument(signature, pos);
- }
- return pos + 1;
- }
-
- /**
- * Checks a type argument in a class type signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkTypeArgument(final String signature, int pos) {
- // TypeArgument:
- // * | ( ( + | - )? FieldTypeSignature )
-
- char c = getChar(signature, pos);
- if (c == '*') {
- return pos + 1;
- } else if (c == '+' || c == '-') {
- pos++;
- }
- return checkFieldTypeSignature(signature, pos);
- }
-
- /**
- * Checks a type variable signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkTypeVariableSignature(
- final String signature,
- int pos)
- {
- // TypeVariableSignature:
- // T Identifier ;
-
- pos = checkChar('T', signature, pos);
- pos = checkIdentifier(signature, pos);
- return checkChar(';', signature, pos);
- }
-
- /**
- * Checks a type signature.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkTypeSignature(final String signature, int pos) {
- // TypeSignature:
- // Z | C | B | S | I | F | J | D | FieldTypeSignature
-
- switch (getChar(signature, pos)) {
- case 'Z':
- case 'C':
- case 'B':
- case 'S':
- case 'I':
- case 'F':
- case 'J':
- case 'D':
- return pos + 1;
- default:
- return checkFieldTypeSignature(signature, pos);
- }
- }
-
- /**
- * Checks an identifier.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkIdentifier(final String signature, int pos) {
- if (!Character.isJavaIdentifierStart(getChar(signature, pos))) {
- throw new IllegalArgumentException(signature
- + ": identifier expected at index " + pos);
- }
- ++pos;
- while (Character.isJavaIdentifierPart(getChar(signature, pos))) {
- ++pos;
- }
- return pos;
- }
-
- /**
- * Checks a single character.
- *
- * @param signature a string containing the signature that must be checked.
- * @param pos index of first character to be checked.
- * @return the index of the first character after the checked part.
- */
- private static int checkChar(final char c, final String signature, int pos)
- {
- if (getChar(signature, pos) == c) {
- return pos + 1;
- }
- throw new IllegalArgumentException(signature + ": '" + c
- + "' expected at index " + pos);
- }
-
- /**
- * Returns the signature car at the given index.
- *
- * @param signature a signature.
- * @param pos an index in signature.
- * @return the character at the given index, or 0 if there is no such
- * character.
- */
- private static char getChar(final String signature, int pos) {
- return pos < signature.length() ? signature.charAt(pos) : (char) 0;
- }
-
- /**
* Checks that the given label is not null. This method can also check that
* the label has been visited.
*
- * @param label the label to be checked.
- * @param checkVisited <tt>true</tt> to check that the label has been
- * visited.
- * @param msg a message to be used in case of error.
+ * @param label
+ * the label to be checked.
+ * @param checkVisited
+ * <tt>true</tt> to check that the label has been visited.
+ * @param msg
+ * a message to be used in case of error.
*/
- void checkLabel(
- final Label label,
- final boolean checkVisited,
- final String msg)
- {
+ void checkLabel(final Label label, final boolean checkVisited,
+ final String msg) {
if (label == null) {
throw new IllegalArgumentException("Invalid " + msg
+ " (must not be null)");
@@ -1620,7 +1346,8 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Checks that the given label is not a label used only for debug purposes.
*
- * @param label the label to be checked.
+ * @param label
+ * the label to be checked.
*/
private static void checkNonDebugLabel(final Label label) {
Field f = getLabelStatusField();
@@ -1631,7 +1358,8 @@ public class CheckMethodAdapter extends MethodVisitor {
throw new Error("Internal error");
}
if ((status & 0x01) != 0) {
- throw new IllegalArgumentException("Labels used for debug info cannot be reused for control flow");
+ throw new IllegalArgumentException(
+ "Labels used for debug info cannot be reused for control flow");
}
}
@@ -1653,7 +1381,8 @@ public class CheckMethodAdapter extends MethodVisitor {
/**
* Returns the field of the Label class whose name is given.
*
- * @param name a field name.
+ * @param name
+ * a field name.
* @return the field of the Label class whose name is given, or null.
*/
private static Field getLabelField(final String name) {
diff --git a/src/asm/scala/tools/asm/util/CheckSignatureAdapter.java b/src/asm/scala/tools/asm/util/CheckSignatureAdapter.java
index 3a6c3e780f..e69302b8a6 100644
--- a/src/asm/scala/tools/asm/util/CheckSignatureAdapter.java
+++ b/src/asm/scala/tools/asm/util/CheckSignatureAdapter.java
@@ -41,19 +41,22 @@ public class CheckSignatureAdapter extends SignatureVisitor {
/**
* Type to be used to check class signatures. See
- * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+ * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+ * CheckSignatureAdapter}.
*/
public static final int CLASS_SIGNATURE = 0;
/**
* Type to be used to check method signatures. See
- * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+ * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+ * CheckSignatureAdapter}.
*/
public static final int METHOD_SIGNATURE = 1;
/**
* Type to be used to check type signatures.See
- * {@link #CheckSignatureAdapter(int, SignatureVisitor) CheckSignatureAdapter}.
+ * {@link #CheckSignatureAdapter(int, SignatureVisitor)
+ * CheckSignatureAdapter}.
*/
public static final int TYPE_SIGNATURE = 2;
@@ -101,11 +104,13 @@ public class CheckSignatureAdapter extends SignatureVisitor {
* not use this constructor</i>. Instead, they must use the
* {@link #CheckSignatureAdapter(int, int, SignatureVisitor)} version.
*
- * @param type the type of signature to be checked. See
- * {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
- * {@link #TYPE_SIGNATURE}.
- * @param sv the visitor to which this adapter must delegate calls. May be
- * <tt>null</tt>.
+ * @param type
+ * the type of signature to be checked. See
+ * {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
+ * {@link #TYPE_SIGNATURE}.
+ * @param sv
+ * the visitor to which this adapter must delegate calls. May be
+ * <tt>null</tt>.
*/
public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
this(Opcodes.ASM4, type, sv);
@@ -114,19 +119,19 @@ public class CheckSignatureAdapter extends SignatureVisitor {
/**
* Creates a new {@link CheckSignatureAdapter} object.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
- * @param type the type of signature to be checked. See
- * {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
- * {@link #TYPE_SIGNATURE}.
- * @param sv the visitor to which this adapter must delegate calls. May be
- * <tt>null</tt>.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
+ * @param type
+ * the type of signature to be checked. See
+ * {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
+ * {@link #TYPE_SIGNATURE}.
+ * @param sv
+ * the visitor to which this adapter must delegate calls. May be
+ * <tt>null</tt>.
*/
- protected CheckSignatureAdapter(
- final int api,
- final int type,
- final SignatureVisitor sv)
- {
+ protected CheckSignatureAdapter(final int api, final int type,
+ final SignatureVisitor sv) {
super(api);
this.type = type;
this.state = EMPTY;
@@ -138,8 +143,7 @@ public class CheckSignatureAdapter extends SignatureVisitor {
@Override
public void visitFormalTypeParameter(final String name) {
if (type == TYPE_SIGNATURE
- || (state != EMPTY && state != FORMAL && state != BOUND))
- {
+ || (state != EMPTY && state != FORMAL && state != BOUND)) {
throw new IllegalStateException();
}
CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
@@ -172,8 +176,7 @@ public class CheckSignatureAdapter extends SignatureVisitor {
@Override
public SignatureVisitor visitSuperclass() {
- if (type != CLASS_SIGNATURE || (state & (EMPTY | FORMAL | BOUND)) == 0)
- {
+ if (type != CLASS_SIGNATURE || (state & (EMPTY | FORMAL | BOUND)) == 0) {
throw new IllegalArgumentException();
}
state = SUPER;
@@ -195,8 +198,7 @@ public class CheckSignatureAdapter extends SignatureVisitor {
@Override
public SignatureVisitor visitParameterType() {
if (type != METHOD_SIGNATURE
- || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0)
- {
+ || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) {
throw new IllegalArgumentException();
}
state = PARAM;
@@ -207,8 +209,7 @@ public class CheckSignatureAdapter extends SignatureVisitor {
@Override
public SignatureVisitor visitReturnType() {
if (type != METHOD_SIGNATURE
- || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0)
- {
+ || (state & (EMPTY | FORMAL | BOUND | PARAM)) == 0) {
throw new IllegalArgumentException();
}
state = RETURN;
diff --git a/src/asm/scala/tools/asm/util/Printer.java b/src/asm/scala/tools/asm/util/Printer.java
index c39fd548ce..86e0f9e122 100644
--- a/src/asm/scala/tools/asm/util/Printer.java
+++ b/src/asm/scala/tools/asm/util/Printer.java
@@ -52,14 +52,14 @@ public abstract class Printer {
/**
* The names of the for <code>operand</code> parameter values of the
- * {@link org.objectweb.asm.MethodVisitor#visitIntInsn} method when
+ * {@link scala.tools.asm.MethodVisitor#visitIntInsn} method when
* <code>opcode</code> is <code>NEWARRAY</code>.
*/
public static final String[] TYPES;
/**
* The names of the <code>tag</code> field values for
- * {@link org.objectweb.asm.Handle}.
+ * {@link scala.tools.asm.Handle}.
*/
public static final String[] HANDLE_TAG;
@@ -103,8 +103,8 @@ public abstract class Printer {
}
s = "H_GETFIELD,H_GETSTATIC,H_PUTFIELD,H_PUTSTATIC,"
- + "H_INVOKEVIRTUAL,H_INVOKESTATIC,H_INVOKESPECIAL,"
- + "H_NEWINVOKESPECIAL,H_INVOKEINTERFACE,";
+ + "H_INVOKEVIRTUAL,H_INVOKESTATIC,H_INVOKESPECIAL,"
+ + "H_NEWINVOKESPECIAL,H_INVOKEINTERFACE,";
HANDLE_TAG = new String[10];
j = 0;
i = 1;
@@ -149,81 +149,58 @@ public abstract class Printer {
}
/**
- * Class header.
- * See {@link org.objectweb.asm.ClassVisitor#visit}.
+ * Class header. See {@link scala.tools.asm.ClassVisitor#visit}.
*/
- public abstract void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces);
+ public abstract void visit(final int version, final int access,
+ final String name, final String signature, final String superName,
+ final String[] interfaces);
/**
- * Class source.
- * See {@link org.objectweb.asm.ClassVisitor#visitSource}.
+ * Class source. See {@link scala.tools.asm.ClassVisitor#visitSource}.
*/
public abstract void visitSource(final String file, final String debug);
/**
- * Class outer class.
- * See {@link org.objectweb.asm.ClassVisitor#visitOuterClass}.
+ * Class outer class. See
+ * {@link scala.tools.asm.ClassVisitor#visitOuterClass}.
*/
- public abstract void visitOuterClass(
- final String owner,
- final String name,
- final String desc);
+ public abstract void visitOuterClass(final String owner, final String name,
+ final String desc);
/**
- * Class annotation.
- * See {@link org.objectweb.asm.ClassVisitor#visitAnnotation}.
+ * Class annotation. See
+ * {@link scala.tools.asm.ClassVisitor#visitAnnotation}.
*/
- public abstract Printer visitClassAnnotation(
- final String desc,
- final boolean visible);
+ public abstract Printer visitClassAnnotation(final String desc,
+ final boolean visible);
/**
- * Class attribute.
- * See {@link org.objectweb.asm.ClassVisitor#visitAttribute}.
+ * Class attribute. See
+ * {@link scala.tools.asm.ClassVisitor#visitAttribute}.
*/
public abstract void visitClassAttribute(final Attribute attr);
/**
- * Class inner name.
- * See {@link org.objectweb.asm.ClassVisitor#visitInnerClass}.
+ * Class inner name. See
+ * {@link scala.tools.asm.ClassVisitor#visitInnerClass}.
*/
- public abstract void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access);
+ public abstract void visitInnerClass(final String name,
+ final String outerName, final String innerName, final int access);
/**
- * Class field.
- * See {@link org.objectweb.asm.ClassVisitor#visitField}.
+ * Class field. See {@link scala.tools.asm.ClassVisitor#visitField}.
*/
- public abstract Printer visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value);
+ public abstract Printer visitField(final int access, final String name,
+ final String desc, final String signature, final Object value);
/**
- * Class method.
- * See {@link org.objectweb.asm.ClassVisitor#visitMethod}.
+ * Class method. See {@link scala.tools.asm.ClassVisitor#visitMethod}.
*/
- public abstract Printer visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions);
+ public abstract Printer visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions);
/**
- * Class end.
- * See {@link org.objectweb.asm.ClassVisitor#visitEnd}.
+ * Class end. See {@link scala.tools.asm.ClassVisitor#visitEnd}.
*/
public abstract void visitClassEnd();
@@ -232,37 +209,31 @@ public abstract class Printer {
// ------------------------------------------------------------------------
/**
- * Annotation value.
- * See {@link org.objectweb.asm.AnnotationVisitor#visit}.
+ * Annotation value. See {@link scala.tools.asm.AnnotationVisitor#visit}.
*/
public abstract void visit(final String name, final Object value);
/**
- * Annotation enum value.
- * See {@link org.objectweb.asm.AnnotationVisitor#visitEnum}.
+ * Annotation enum value. See
+ * {@link scala.tools.asm.AnnotationVisitor#visitEnum}.
*/
- public abstract void visitEnum(
- final String name,
- final String desc,
- final String value);
+ public abstract void visitEnum(final String name, final String desc,
+ final String value);
/**
- * Nested annotation value.
- * See {@link org.objectweb.asm.AnnotationVisitor#visitAnnotation}.
+ * Nested annotation value. See
+ * {@link scala.tools.asm.AnnotationVisitor#visitAnnotation}.
*/
- public abstract Printer visitAnnotation(
- final String name,
- final String desc);
+ public abstract Printer visitAnnotation(final String name, final String desc);
/**
- * Annotation array value.
- * See {@link org.objectweb.asm.AnnotationVisitor#visitArray}.
+ * Annotation array value. See
+ * {@link scala.tools.asm.AnnotationVisitor#visitArray}.
*/
public abstract Printer visitArray(final String name);
/**
- * Annotation end.
- * See {@link org.objectweb.asm.AnnotationVisitor#visitEnd}.
+ * Annotation end. See {@link scala.tools.asm.AnnotationVisitor#visitEnd}.
*/
public abstract void visitAnnotationEnd();
@@ -271,22 +242,20 @@ public abstract class Printer {
// ------------------------------------------------------------------------
/**
- * Field annotation.
- * See {@link org.objectweb.asm.FieldVisitor#visitAnnotation}.
+ * Field annotation. See
+ * {@link scala.tools.asm.FieldVisitor#visitAnnotation}.
*/
- public abstract Printer visitFieldAnnotation(
- final String desc,
- final boolean visible);
+ public abstract Printer visitFieldAnnotation(final String desc,
+ final boolean visible);
/**
- * Field attribute.
- * See {@link org.objectweb.asm.FieldVisitor#visitAttribute}.
+ * Field attribute. See
+ * {@link scala.tools.asm.FieldVisitor#visitAttribute}.
*/
public abstract void visitFieldAttribute(final Attribute attr);
/**
- * Field end.
- * See {@link org.objectweb.asm.FieldVisitor#visitEnd}.
+ * Field end. See {@link scala.tools.asm.FieldVisitor#visitEnd}.
*/
public abstract void visitFieldEnd();
@@ -295,193 +264,161 @@ public abstract class Printer {
// ------------------------------------------------------------------------
/**
- * Method default annotation.
- * See {@link org.objectweb.asm.MethodVisitor#visitAnnotationDefault}.
+ * Method default annotation. See
+ * {@link scala.tools.asm.MethodVisitor#visitAnnotationDefault}.
*/
public abstract Printer visitAnnotationDefault();
/**
- * Method annotation.
- * See {@link org.objectweb.asm.MethodVisitor#visitAnnotation}.
+ * Method annotation. See
+ * {@link scala.tools.asm.MethodVisitor#visitAnnotation}.
*/
- public abstract Printer visitMethodAnnotation(
- final String desc,
- final boolean visible);
+ public abstract Printer visitMethodAnnotation(final String desc,
+ final boolean visible);
/**
- * Method parameter annotation.
- * See {@link org.objectweb.asm.MethodVisitor#visitParameterAnnotation}.
+ * Method parameter annotation. See
+ * {@link scala.tools.asm.MethodVisitor#visitParameterAnnotation}.
*/
- public abstract Printer visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible);
+ public abstract Printer visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible);
/**
- * Method attribute.
- * See {@link org.objectweb.asm.MethodVisitor#visitAttribute}.
+ * Method attribute. See
+ * {@link scala.tools.asm.MethodVisitor#visitAttribute}.
*/
public abstract void visitMethodAttribute(final Attribute attr);
/**
- * Method start.
- * See {@link org.objectweb.asm.MethodVisitor#visitCode}.
+ * Method start. See {@link scala.tools.asm.MethodVisitor#visitCode}.
*/
public abstract void visitCode();
/**
- * Method stack frame.
- * See {@link org.objectweb.asm.MethodVisitor#visitFrame}.
+ * Method stack frame. See
+ * {@link scala.tools.asm.MethodVisitor#visitFrame}.
*/
- public abstract void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack);
+ public abstract void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitInsn}.
+ * Method instruction. See {@link scala.tools.asm.MethodVisitor#visitInsn}
+ * .
*/
public abstract void visitInsn(final int opcode);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitIntInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitIntInsn}.
*/
public abstract void visitIntInsn(final int opcode, final int operand);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitVarInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitVarInsn}.
*/
public abstract void visitVarInsn(final int opcode, final int var);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitTypeInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitTypeInsn}.
*/
public abstract void visitTypeInsn(final int opcode, final String type);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitFieldInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitFieldInsn}.
*/
- public abstract void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc);
+ public abstract void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitMethodInsn}.
*/
- public abstract void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc);
+ public abstract void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitInvokeDynamicInsn}.
*/
- public abstract void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs);
+ public abstract void visitInvokeDynamicInsn(String name, String desc,
+ Handle bsm, Object... bsmArgs);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitJumpInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitJumpInsn}.
*/
public abstract void visitJumpInsn(final int opcode, final Label label);
/**
- * Method label.
- * See {@link org.objectweb.asm.MethodVisitor#visitLabel}.
+ * Method label. See {@link scala.tools.asm.MethodVisitor#visitLabel}.
*/
public abstract void visitLabel(final Label label);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitLdcInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitLdcInsn}.
*/
public abstract void visitLdcInsn(final Object cst);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitIincInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitIincInsn}.
*/
public abstract void visitIincInsn(final int var, final int increment);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitTableSwitchInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitTableSwitchInsn}.
*/
- public abstract void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels);
+ public abstract void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitLookupSwitchInsn}.
*/
- public abstract void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels);
+ public abstract void visitLookupSwitchInsn(final Label dflt,
+ final int[] keys, final Label[] labels);
/**
- * Method instruction.
- * See {@link org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn}.
+ * Method instruction. See
+ * {@link scala.tools.asm.MethodVisitor#visitMultiANewArrayInsn}.
*/
- public abstract void visitMultiANewArrayInsn(
- final String desc,
- final int dims);
+ public abstract void visitMultiANewArrayInsn(final String desc,
+ final int dims);
/**
- * Method exception handler.
- * See {@link org.objectweb.asm.MethodVisitor#visitTryCatchBlock}.
+ * Method exception handler. See
+ * {@link scala.tools.asm.MethodVisitor#visitTryCatchBlock}.
*/
- public abstract void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type);
+ public abstract void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type);
/**
- * Method debug info.
- * See {@link org.objectweb.asm.MethodVisitor#visitLocalVariable}.
+ * Method debug info. See
+ * {@link scala.tools.asm.MethodVisitor#visitLocalVariable}.
*/
- public abstract void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index);
+ public abstract void visitLocalVariable(final String name,
+ final String desc, final String signature, final Label start,
+ final Label end, final int index);
/**
- * Method debug info.
- * See {@link org.objectweb.asm.MethodVisitor#visitLineNumber}.
+ * Method debug info. See
+ * {@link scala.tools.asm.MethodVisitor#visitLineNumber}.
*/
public abstract void visitLineNumber(final int line, final Label start);
/**
- * Method max stack and max locals.
- * See {@link org.objectweb.asm.MethodVisitor#visitMaxs}.
+ * Method max stack and max locals. See
+ * {@link scala.tools.asm.MethodVisitor#visitMaxs}.
*/
public abstract void visitMaxs(final int maxStack, final int maxLocals);
/**
- * Method end.
- * See {@link org.objectweb.asm.MethodVisitor#visitEnd}.
+ * Method end. See {@link scala.tools.asm.MethodVisitor#visitEnd}.
*/
public abstract void visitMethodEnd();
@@ -497,7 +434,8 @@ public abstract class Printer {
/**
* Prints the text constructed by this visitor.
*
- * @param pw the print writer to be used.
+ * @param pw
+ * the print writer to be used.
*/
public void print(final PrintWriter pw) {
printList(pw, text);
@@ -506,8 +444,10 @@ public abstract class Printer {
/**
* Appends a quoted string to a given buffer.
*
- * @param buf the buffer where the string must be added.
- * @param s the string to be added.
+ * @param buf
+ * the buffer where the string must be added.
+ * @param s
+ * the string to be added.
*/
public static void appendString(final StringBuffer buf, final String s) {
buf.append('\"');
@@ -541,9 +481,11 @@ public abstract class Printer {
/**
* Prints the given string tree.
*
- * @param pw the writer to be used to print the tree.
- * @param l a string tree, i.e., a string list that can contain other string
- * lists, and so on recursively.
+ * @param pw
+ * the writer to be used to print the tree.
+ * @param l
+ * a string tree, i.e., a string list that can contain other
+ * string lists, and so on recursively.
*/
static void printList(final PrintWriter pw, final List<?> l) {
for (int i = 0; i < l.size(); ++i) {
diff --git a/src/asm/scala/tools/asm/util/SignatureChecker.java b/src/asm/scala/tools/asm/util/SignatureChecker.java
deleted file mode 100644
index 71f0d80027..0000000000
--- a/src/asm/scala/tools/asm/util/SignatureChecker.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- */
-
-package scala.tools.asm.util;
-
-import scala.tools.asm.util.CheckMethodAdapter;
-import scala.tools.asm.MethodVisitor;
-
-/**
- * A subclass of ASM's CheckMethodAdapter for the sole purpose of accessing some protected methods there.
- *
- */
-public class SignatureChecker extends CheckMethodAdapter {
-
- public SignatureChecker(final MethodVisitor mv) {
- super(mv);
- }
-
- /**
- * Checks a class signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- public static void checkClassSignature(final String signature) {
- CheckMethodAdapter.checkClassSignature(signature);
- }
-
- /**
- * Checks a method signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- public static void checkMethodSignature(final String signature) {
- CheckMethodAdapter.checkMethodSignature(signature);
- }
-
- /**
- * Checks a field signature.
- *
- * @param signature a string containing the signature that must be checked.
- */
- public static void checkFieldSignature(final String signature) {
- CheckMethodAdapter.checkFieldSignature(signature);
- }
-
-}
diff --git a/src/asm/scala/tools/asm/util/Textifiable.java b/src/asm/scala/tools/asm/util/Textifiable.java
index b80d0139db..85e051e2f8 100644
--- a/src/asm/scala/tools/asm/util/Textifiable.java
+++ b/src/asm/scala/tools/asm/util/Textifiable.java
@@ -34,7 +34,7 @@ import java.util.Map;
import scala.tools.asm.Label;
/**
- * An {@link org.objectweb.asm.Attribute Attribute} that can print a readable
+ * An {@link scala.tools.asm.Attribute Attribute} that can print a readable
* representation of itself.
*
* Implementations should construct readable output from an attribute data
@@ -47,8 +47,10 @@ public interface Textifiable {
/**
* Build a human readable representation of this attribute.
*
- * @param buf a buffer used for printing Java code.
- * @param labelNames map of label instances to their names.
+ * @param buf
+ * a buffer used for printing Java code.
+ * @param labelNames
+ * map of label instances to their names.
*/
void textify(StringBuffer buf, Map<Label, String> labelNames);
}
diff --git a/src/asm/scala/tools/asm/util/Textifier.java b/src/asm/scala/tools/asm/util/Textifier.java
index 8d40ebd026..a5c4f6779e 100644
--- a/src/asm/scala/tools/asm/util/Textifier.java
+++ b/src/asm/scala/tools/asm/util/Textifier.java
@@ -149,22 +149,24 @@ public class Textifier extends Printer {
/**
* Constructs a new {@link Textifier}.
*
- * @param api the ASM API version implemented by this visitor. Must be one
- * of {@link Opcodes#ASM4}.
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4}.
*/
protected Textifier(final int api) {
super(api);
}
/**
- * Prints a disassembled view of the given class to the standard output. <p>
- * Usage: Textifier [-debug] &lt;binary class name or class
- * file name &gt;
+ * Prints a disassembled view of the given class to the standard output.
+ * <p>
+ * Usage: Textifier [-debug] &lt;binary class name or class file name &gt;
*
- * @param args the command line arguments.
+ * @param args
+ * the command line arguments.
*
- * @throws Exception if the class cannot be found, or if an IO exception
- * occurs.
+ * @throws Exception
+ * if the class cannot be found, or if an IO exception occurs.
*/
public static void main(final String[] args) throws Exception {
int i = 0;
@@ -182,21 +184,20 @@ public class Textifier extends Printer {
}
}
if (!ok) {
- System.err.println("Prints a disassembled view of the given class.");
+ System.err
+ .println("Prints a disassembled view of the given class.");
System.err.println("Usage: Textifier [-debug] "
+ "<fully qualified class name or class file name>");
return;
}
ClassReader cr;
if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
- || args[i].indexOf('/') > -1)
- {
+ || args[i].indexOf('/') > -1) {
cr = new ClassReader(new FileInputStream(args[i]));
} else {
cr = new ClassReader(args[i]);
}
- cr.accept(new TraceClassVisitor(new PrintWriter(System.out)),
- flags);
+ cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), flags);
}
// ------------------------------------------------------------------------
@@ -204,38 +205,27 @@ public class Textifier extends Printer {
// ------------------------------------------------------------------------
@Override
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
int major = version & 0xFFFF;
int minor = version >>> 16;
buf.setLength(0);
- buf.append("// class version ")
- .append(major)
- .append('.')
- .append(minor)
- .append(" (")
- .append(version)
- .append(")\n");
+ buf.append("// class version ").append(major).append('.').append(minor)
+ .append(" (").append(version).append(")\n");
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
buf.append("// DEPRECATED\n");
}
- buf.append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+ buf.append("// access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase()).append('\n');
appendDescriptor(CLASS_SIGNATURE, signature);
if (signature != null) {
TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
SignatureReader r = new SignatureReader(signature);
r.accept(sv);
- buf.append("// declaration: ")
- .append(name)
- .append(sv.getDeclaration())
- .append('\n');
+ buf.append("// declaration: ").append(name)
+ .append(sv.getDeclaration()).append('\n');
}
appendAccess(access & ~Opcodes.ACC_SUPER);
@@ -269,15 +259,11 @@ public class Textifier extends Printer {
public void visitSource(final String file, final String debug) {
buf.setLength(0);
if (file != null) {
- buf.append(tab)
- .append("// compiled from: ")
- .append(file)
+ buf.append(tab).append("// compiled from: ").append(file)
.append('\n');
}
if (debug != null) {
- buf.append(tab)
- .append("// debug info: ")
- .append(debug)
+ buf.append(tab).append("// debug info: ").append(debug)
.append('\n');
}
if (buf.length() > 0) {
@@ -286,11 +272,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
buf.setLength(0);
buf.append(tab).append("OUTERCLASS ");
appendDescriptor(INTERNAL_NAME, owner);
@@ -304,10 +287,8 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitClassAnnotation(
- final String desc,
- final boolean visible)
- {
+ public Textifier visitClassAnnotation(final String desc,
+ final boolean visible) {
text.add("\n");
return visitAnnotation(desc, visible);
}
@@ -319,15 +300,13 @@ public class Textifier extends Printer {
}
@Override
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
buf.setLength(0);
buf.append(tab).append("// access flags 0x");
- buf.append(Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase()).append('\n');
+ buf.append(
+ Integer.toHexString(access & ~Opcodes.ACC_SUPER).toUpperCase())
+ .append('\n');
buf.append(tab);
appendAccess(access);
buf.append("INNERCLASS ");
@@ -341,19 +320,15 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
+ public Textifier visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
buf.setLength(0);
buf.append('\n');
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
buf.append(tab).append("// DEPRECATED\n");
}
- buf.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+ buf.append(tab).append("// access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase()).append('\n');
if (signature != null) {
buf.append(tab);
appendDescriptor(FIELD_SIGNATURE, signature);
@@ -361,10 +336,8 @@ public class Textifier extends Printer {
TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
SignatureReader r = new SignatureReader(signature);
r.acceptType(sv);
- buf.append(tab)
- .append("// declaration: ")
- .append(sv.getDeclaration())
- .append('\n');
+ buf.append(tab).append("// declaration: ")
+ .append(sv.getDeclaration()).append('\n');
}
buf.append(tab);
@@ -390,19 +363,15 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
+ public Textifier visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
buf.setLength(0);
buf.append('\n');
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
buf.append(tab).append("// DEPRECATED\n");
}
- buf.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');
+ buf.append(tab).append("// access flags 0x")
+ .append(Integer.toHexString(access).toUpperCase()).append('\n');
if (signature != null) {
buf.append(tab);
@@ -415,12 +384,8 @@ public class Textifier extends Printer {
String genericReturn = v.getReturnType();
String genericExceptions = v.getExceptions();
- buf.append(tab)
- .append("// declaration: ")
- .append(genericReturn)
- .append(' ')
- .append(name)
- .append(genericDecl);
+ buf.append(tab).append("// declaration: ").append(genericReturn)
+ .append(' ').append(name).append(genericDecl);
if (genericExceptions != null) {
buf.append(" throws ").append(genericExceptions);
}
@@ -593,11 +558,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
buf.setLength(0);
appendComa(valueNumber++);
if (name != null) {
@@ -609,10 +571,7 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitAnnotation(
- final String name,
- final String desc)
- {
+ public Textifier visitAnnotation(final String name, final String desc) {
buf.setLength(0);
appendComa(valueNumber++);
if (name != null) {
@@ -629,9 +588,7 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitArray(
- final String name)
- {
+ public Textifier visitArray(final String name) {
buf.setLength(0);
appendComa(valueNumber++);
if (name != null) {
@@ -654,10 +611,8 @@ public class Textifier extends Printer {
// ------------------------------------------------------------------------
@Override
- public Textifier visitFieldAnnotation(
- final String desc,
- final boolean visible)
- {
+ public Textifier visitFieldAnnotation(final String desc,
+ final boolean visible) {
return visitAnnotation(desc, visible);
}
@@ -684,19 +639,14 @@ public class Textifier extends Printer {
}
@Override
- public Textifier visitMethodAnnotation(
- final String desc,
- final boolean visible)
- {
+ public Textifier visitMethodAnnotation(final String desc,
+ final boolean visible) {
return visitAnnotation(desc, visible);
}
@Override
- public Textifier visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
+ public Textifier visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
buf.setLength(0);
buf.append(tab2).append('@');
appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -730,40 +680,35 @@ public class Textifier extends Printer {
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
buf.setLength(0);
buf.append(ltab);
buf.append("FRAME ");
switch (type) {
- case Opcodes.F_NEW:
- case Opcodes.F_FULL:
- buf.append("FULL [");
- appendFrameTypes(nLocal, local);
- buf.append("] [");
- appendFrameTypes(nStack, stack);
- buf.append(']');
- break;
- case Opcodes.F_APPEND:
- buf.append("APPEND [");
- appendFrameTypes(nLocal, local);
- buf.append(']');
- break;
- case Opcodes.F_CHOP:
- buf.append("CHOP ").append(nLocal);
- break;
- case Opcodes.F_SAME:
- buf.append("SAME");
- break;
- case Opcodes.F_SAME1:
- buf.append("SAME1 ");
- appendFrameTypes(1, stack);
- break;
+ case Opcodes.F_NEW:
+ case Opcodes.F_FULL:
+ buf.append("FULL [");
+ appendFrameTypes(nLocal, local);
+ buf.append("] [");
+ appendFrameTypes(nStack, stack);
+ buf.append(']');
+ break;
+ case Opcodes.F_APPEND:
+ buf.append("APPEND [");
+ appendFrameTypes(nLocal, local);
+ buf.append(']');
+ break;
+ case Opcodes.F_CHOP:
+ buf.append("CHOP ").append(nLocal);
+ break;
+ case Opcodes.F_SAME:
+ buf.append("SAME");
+ break;
+ case Opcodes.F_SAME1:
+ buf.append("SAME1 ");
+ appendFrameTypes(1, stack);
+ break;
}
buf.append('\n');
text.add(buf.toString());
@@ -782,20 +727,15 @@ public class Textifier extends Printer {
buf.append(tab2)
.append(OPCODES[opcode])
.append(' ')
- .append(opcode == Opcodes.NEWARRAY
- ? TYPES[operand]
- : Integer.toString(operand))
- .append('\n');
+ .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer
+ .toString(operand)).append('\n');
text.add(buf.toString());
}
@Override
public void visitVarInsn(final int opcode, final int var) {
buf.setLength(0);
- buf.append(tab2)
- .append(OPCODES[opcode])
- .append(' ')
- .append(var)
+ buf.append(tab2).append(OPCODES[opcode]).append(' ').append(var)
.append('\n');
text.add(buf.toString());
}
@@ -810,12 +750,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
buf.setLength(0);
buf.append(tab2).append(OPCODES[opcode]).append(' ');
appendDescriptor(INTERNAL_NAME, owner);
@@ -826,12 +762,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
buf.setLength(0);
buf.append(tab2).append(OPCODES[opcode]).append(' ');
appendDescriptor(INTERNAL_NAME, owner);
@@ -842,12 +774,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
buf.setLength(0);
buf.append(tab2).append("INVOKEDYNAMIC").append(' ');
buf.append(name);
@@ -855,11 +783,11 @@ public class Textifier extends Printer {
buf.append(" [");
appendHandle(bsm);
buf.append(tab3).append("// arguments:");
- if(bsmArgs.length == 0) {
+ if (bsmArgs.length == 0) {
buf.append(" none");
} else {
buf.append('\n').append(tab3);
- for(int i = 0; i < bsmArgs.length; i++) {
+ for (int i = 0; i < bsmArgs.length; i++) {
Object cst = bsmArgs[i];
if (cst instanceof String) {
Printer.appendString(buf, (String) cst);
@@ -915,22 +843,14 @@ public class Textifier extends Printer {
@Override
public void visitIincInsn(final int var, final int increment) {
buf.setLength(0);
- buf.append(tab2)
- .append("IINC ")
- .append(var)
- .append(' ')
- .append(increment)
- .append('\n');
+ buf.append(tab2).append("IINC ").append(var).append(' ')
+ .append(increment).append('\n');
text.add(buf.toString());
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
buf.setLength(0);
buf.append(tab2).append("TABLESWITCH\n");
for (int i = 0; i < labels.length; ++i) {
@@ -945,11 +865,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
buf.setLength(0);
buf.append(tab2).append("LOOKUPSWITCH\n");
for (int i = 0; i < labels.length; ++i) {
@@ -973,12 +890,8 @@ public class Textifier extends Printer {
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
buf.setLength(0);
buf.append(tab2).append("TRYCATCHBLOCK ");
appendLabel(start);
@@ -993,14 +906,9 @@ public class Textifier extends Printer {
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
buf.setLength(0);
buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -1017,10 +925,8 @@ public class Textifier extends Printer {
TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
SignatureReader r = new SignatureReader(signature);
r.acceptType(sv);
- buf.append(tab2)
- .append("// declaration: ")
- .append(sv.getDeclaration())
- .append('\n');
+ buf.append(tab2).append("// declaration: ")
+ .append(sv.getDeclaration()).append('\n');
}
text.add(buf.toString());
}
@@ -1056,14 +962,13 @@ public class Textifier extends Printer {
/**
* Prints a disassembled view of the given annotation.
*
- * @param desc the class descriptor of the annotation class.
- * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @param desc
+ * the class descriptor of the annotation class.
+ * @param visible
+ * <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values.
*/
- public Textifier visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public Textifier visitAnnotation(final String desc, final boolean visible) {
buf.setLength(0);
buf.append(tab).append('@');
appendDescriptor(FIELD_DESCRIPTOR, desc);
@@ -1078,7 +983,8 @@ public class Textifier extends Printer {
/**
* Prints a disassembled view of the given attribute.
*
- * @param attr an attribute.
+ * @param attr
+ * an attribute.
*/
public void visitAttribute(final Attribute attr) {
buf.setLength(0);
@@ -1111,15 +1017,16 @@ public class Textifier extends Printer {
* Appends an internal name, a type descriptor or a type signature to
* {@link #buf buf}.
*
- * @param type indicates if desc is an internal name, a field descriptor, a
- * method descriptor, a class signature, ...
- * @param desc an internal name, type descriptor, or type signature. May be
- * <tt>null</tt>.
+ * @param type
+ * indicates if desc is an internal name, a field descriptor, a
+ * method descriptor, a class signature, ...
+ * @param desc
+ * an internal name, type descriptor, or type signature. May be
+ * <tt>null</tt>.
*/
protected void appendDescriptor(final int type, final String desc) {
if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE
- || type == METHOD_SIGNATURE)
- {
+ || type == METHOD_SIGNATURE) {
if (desc != null) {
buf.append("// signature ").append(desc).append('\n');
}
@@ -1132,7 +1039,8 @@ public class Textifier extends Printer {
* Appends the name of the given label to {@link #buf buf}. Creates a new
* label name if the given label does not yet have one.
*
- * @param l a label.
+ * @param l
+ * a label.
*/
protected void appendLabel(final Label l) {
if (labelNames == null) {
@@ -1149,40 +1057,42 @@ public class Textifier extends Printer {
/**
* Appends the information about the given handle to {@link #buf buf}.
*
- * @param h a handle, non null.
+ * @param h
+ * a handle, non null.
*/
protected void appendHandle(final Handle h) {
buf.append('\n').append(tab3);
int tag = h.getTag();
- buf.append("// handle kind 0x").append(Integer.toHexString(tag)).append(" : ");
+ buf.append("// handle kind 0x").append(Integer.toHexString(tag))
+ .append(" : ");
switch (tag) {
- case Opcodes.H_GETFIELD:
- buf.append("GETFIELD");
- break;
- case Opcodes.H_GETSTATIC:
- buf.append("GETSTATIC");
- break;
- case Opcodes.H_PUTFIELD:
- buf.append("PUTFIELD");
- break;
- case Opcodes.H_PUTSTATIC:
- buf.append("PUTSTATIC");
- break;
- case Opcodes.H_INVOKEINTERFACE:
- buf.append("INVOKEINTERFACE");
- break;
- case Opcodes.H_INVOKESPECIAL:
- buf.append("INVOKESPECIAL");
- break;
- case Opcodes.H_INVOKESTATIC:
- buf.append("INVOKESTATIC");
- break;
- case Opcodes.H_INVOKEVIRTUAL:
- buf.append("INVOKEVIRTUAL");
- break;
- case Opcodes.H_NEWINVOKESPECIAL:
- buf.append("NEWINVOKESPECIAL");
- break;
+ case Opcodes.H_GETFIELD:
+ buf.append("GETFIELD");
+ break;
+ case Opcodes.H_GETSTATIC:
+ buf.append("GETSTATIC");
+ break;
+ case Opcodes.H_PUTFIELD:
+ buf.append("PUTFIELD");
+ break;
+ case Opcodes.H_PUTSTATIC:
+ buf.append("PUTSTATIC");
+ break;
+ case Opcodes.H_INVOKEINTERFACE:
+ buf.append("INVOKEINTERFACE");
+ break;
+ case Opcodes.H_INVOKESPECIAL:
+ buf.append("INVOKESPECIAL");
+ break;
+ case Opcodes.H_INVOKESTATIC:
+ buf.append("INVOKESTATIC");
+ break;
+ case Opcodes.H_INVOKEVIRTUAL:
+ buf.append("INVOKEVIRTUAL");
+ break;
+ case Opcodes.H_NEWINVOKESPECIAL:
+ buf.append("NEWINVOKESPECIAL");
+ break;
}
buf.append('\n');
buf.append(tab3);
@@ -1195,10 +1105,11 @@ public class Textifier extends Printer {
}
/**
- * Appends a string representation of the given access modifiers to {@link
- * #buf buf}.
+ * Appends a string representation of the given access modifiers to
+ * {@link #buf buf}.
*
- * @param access some access modifiers.
+ * @param access
+ * some access modifiers.
*/
private void appendAccess(final int access) {
if ((access & Opcodes.ACC_PUBLIC) != 0) {
@@ -1231,6 +1142,9 @@ public class Textifier extends Printer {
if ((access & Opcodes.ACC_STRICT) != 0) {
buf.append("strictfp ");
}
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ buf.append("synthetic ");
+ }
if ((access & Opcodes.ACC_ENUM) != 0) {
buf.append("enum ");
}
@@ -1256,27 +1170,27 @@ public class Textifier extends Printer {
}
} else if (o[i] instanceof Integer) {
switch (((Integer) o[i]).intValue()) {
- case 0:
- appendDescriptor(FIELD_DESCRIPTOR, "T");
- break;
- case 1:
- appendDescriptor(FIELD_DESCRIPTOR, "I");
- break;
- case 2:
- appendDescriptor(FIELD_DESCRIPTOR, "F");
- break;
- case 3:
- appendDescriptor(FIELD_DESCRIPTOR, "D");
- break;
- case 4:
- appendDescriptor(FIELD_DESCRIPTOR, "J");
- break;
- case 5:
- appendDescriptor(FIELD_DESCRIPTOR, "N");
- break;
- case 6:
- appendDescriptor(FIELD_DESCRIPTOR, "U");
- break;
+ case 0:
+ appendDescriptor(FIELD_DESCRIPTOR, "T");
+ break;
+ case 1:
+ appendDescriptor(FIELD_DESCRIPTOR, "I");
+ break;
+ case 2:
+ appendDescriptor(FIELD_DESCRIPTOR, "F");
+ break;
+ case 3:
+ appendDescriptor(FIELD_DESCRIPTOR, "D");
+ break;
+ case 4:
+ appendDescriptor(FIELD_DESCRIPTOR, "J");
+ break;
+ case 5:
+ appendDescriptor(FIELD_DESCRIPTOR, "N");
+ break;
+ case 6:
+ appendDescriptor(FIELD_DESCRIPTOR, "U");
+ break;
}
} else {
appendLabel((Label) o[i]);
diff --git a/src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java b/src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java
index f112609031..33e7cf0b26 100644
--- a/src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java
+++ b/src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java
@@ -58,33 +58,26 @@ public final class TraceAnnotationVisitor extends AnnotationVisitor {
}
@Override
- public void visitEnum(
- final String name,
- final String desc,
- final String value)
- {
+ public void visitEnum(final String name, final String desc,
+ final String value) {
p.visitEnum(name, desc, value);
super.visitEnum(name, desc, value);
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String name,
- final String desc)
- {
+ public AnnotationVisitor visitAnnotation(final String name,
+ final String desc) {
Printer p = this.p.visitAnnotation(name, desc);
- AnnotationVisitor av = this.av == null
- ? null
- : this.av.visitAnnotation(name, desc);
+ AnnotationVisitor av = this.av == null ? null : this.av
+ .visitAnnotation(name, desc);
return new TraceAnnotationVisitor(av, p);
}
@Override
public AnnotationVisitor visitArray(final String name) {
Printer p = this.p.visitArray(name);
- AnnotationVisitor av = this.av == null
- ? null
- : this.av.visitArray(name);
+ AnnotationVisitor av = this.av == null ? null : this.av
+ .visitArray(name);
return new TraceAnnotationVisitor(av, p);
}
diff --git a/src/asm/scala/tools/asm/util/TraceClassVisitor.java b/src/asm/scala/tools/asm/util/TraceClassVisitor.java
index bb830b71ce..ff7a017482 100644
--- a/src/asm/scala/tools/asm/util/TraceClassVisitor.java
+++ b/src/asm/scala/tools/asm/util/TraceClassVisitor.java
@@ -42,30 +42,41 @@ import scala.tools.asm.Opcodes;
* A {@link ClassVisitor} that prints the classes it visits with a
* {@link Printer}. This class visitor can be used in the middle of a class
* visitor chain to trace the class that is visited at a given point in this
- * chain. This may be useful for debugging purposes. <p> The trace printed when
- * visiting the <tt>Hello</tt> class is the following: <p> <blockquote>
- *
- * <pre> // class version 49.0 (49) // access flags 0x21 public class Hello {
- *
+ * chain. This may be useful for debugging purposes.
+ * <p>
+ * The trace printed when visiting the <tt>Hello</tt> class is the following:
+ * <p>
+ * <blockquote>
+ *
+ * <pre>
+ * // class version 49.0 (49) // access flags 0x21 public class Hello {
+ *
* // compiled from: Hello.java
- *
+ *
* // access flags 0x1 public &lt;init&gt; ()V ALOAD 0 INVOKESPECIAL
* java/lang/Object &lt;init&gt; ()V RETURN MAXSTACK = 1 MAXLOCALS = 1
- *
+ *
* // access flags 0x9 public static main ([Ljava/lang/String;)V GETSTATIC
* java/lang/System out Ljava/io/PrintStream; LDC &quot;hello&quot;
* INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V RETURN
- * MAXSTACK = 2 MAXLOCALS = 1 } </pre>
- *
- * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
- *
- * <pre> public class Hello {
- *
- * public static void main(String[] args) {
- * System.out.println(&quot;hello&quot;); } } </pre>
- *
+ * MAXSTACK = 2 MAXLOCALS = 1 }
+ * </pre>
+ *
+ * </blockquote> where <tt>Hello</tt> is defined by:
+ * <p>
+ * <blockquote>
+ *
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main(String[] args) {
+ * System.out.println(&quot;hello&quot;);
+ * }
+ * }
+ * </pre>
+ *
* </blockquote>
- *
+ *
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
@@ -83,8 +94,9 @@ public final class TraceClassVisitor extends ClassVisitor {
/**
* Constructs a new {@link TraceClassVisitor}.
- *
- * @param pw the print writer to be used to print the class.
+ *
+ * @param pw
+ * the print writer to be used to print the class.
*/
public TraceClassVisitor(final PrintWriter pw) {
this(null, pw);
@@ -92,10 +104,12 @@ public final class TraceClassVisitor extends ClassVisitor {
/**
* Constructs a new {@link TraceClassVisitor}.
- *
- * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
- * May be <tt>null</tt>.
- * @param pw the print writer to be used to print the class.
+ *
+ * @param cv
+ * the {@link ClassVisitor} to which this visitor delegates
+ * calls. May be <tt>null</tt>.
+ * @param pw
+ * the print writer to be used to print the class.
*/
public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) {
this(cv, new Textifier(), pw);
@@ -103,33 +117,28 @@ public final class TraceClassVisitor extends ClassVisitor {
/**
* Constructs a new {@link TraceClassVisitor}.
- *
- * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
- * May be <tt>null</tt>.
- * @param p the object that actually converts visit events into text.
- * @param pw the print writer to be used to print the class. May be null if
- * you simply want to use the result via
- * {@link Printer#getText()}, instead of printing it.
+ *
+ * @param cv
+ * the {@link ClassVisitor} to which this visitor delegates
+ * calls. May be <tt>null</tt>.
+ * @param p
+ * the object that actually converts visit events into text.
+ * @param pw
+ * the print writer to be used to print the class. May be null if
+ * you simply want to use the result via
+ * {@link Printer#getText()}, instead of printing it.
*/
- public TraceClassVisitor(
- final ClassVisitor cv,
- final Printer p,
- final PrintWriter pw)
- {
+ public TraceClassVisitor(final ClassVisitor cv, final Printer p,
+ final PrintWriter pw) {
super(Opcodes.ASM4, cv);
this.pw = pw;
this.p = p;
}
@Override
- public void visit(
- final int version,
- final int access,
- final String name,
- final String signature,
- final String superName,
- final String[] interfaces)
- {
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
p.visit(version, access, name, signature, superName, interfaces);
super.visit(version, access, name, signature, superName, interfaces);
}
@@ -141,20 +150,15 @@ public final class TraceClassVisitor extends ClassVisitor {
}
@Override
- public void visitOuterClass(
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
p.visitOuterClass(owner, name, desc);
super.visitOuterClass(owner, name, desc);
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
Printer p = this.p.visitClassAnnotation(desc, visible);
AnnotationVisitor av = cv == null ? null : cv.visitAnnotation(desc,
visible);
@@ -168,55 +172,28 @@ public final class TraceClassVisitor extends ClassVisitor {
}
@Override
- public void visitInnerClass(
- final String name,
- final String outerName,
- final String innerName,
- final int access)
- {
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
p.visitInnerClass(name, outerName, innerName, access);
super.visitInnerClass(name, outerName, innerName, access);
}
@Override
- public FieldVisitor visitField(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final Object value)
- {
- Printer p = this.p.visitField(access,
- name,
- desc,
- signature,
- value);
- FieldVisitor fv = cv == null ? null : cv.visitField(access,
- name,
- desc,
- signature,
- value);
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ Printer p = this.p.visitField(access, name, desc, signature, value);
+ FieldVisitor fv = cv == null ? null : cv.visitField(access, name, desc,
+ signature, value);
return new TraceFieldVisitor(fv, p);
}
@Override
- public MethodVisitor visitMethod(
- final int access,
- final String name,
- final String desc,
- final String signature,
- final String[] exceptions)
- {
- Printer p = this.p.visitMethod(access,
- name,
- desc,
- signature,
- exceptions);
- MethodVisitor mv = cv == null ? null : cv.visitMethod(access,
- name,
- desc,
- signature,
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ Printer p = this.p.visitMethod(access, name, desc, signature,
exceptions);
+ MethodVisitor mv = cv == null ? null : cv.visitMethod(access, name,
+ desc, signature, exceptions);
return new TraceMethodVisitor(mv, p);
}
diff --git a/src/asm/scala/tools/asm/util/TraceFieldVisitor.java b/src/asm/scala/tools/asm/util/TraceFieldVisitor.java
index f537e83be1..9547a70008 100644
--- a/src/asm/scala/tools/asm/util/TraceFieldVisitor.java
+++ b/src/asm/scala/tools/asm/util/TraceFieldVisitor.java
@@ -37,7 +37,7 @@ import scala.tools.asm.Opcodes;
/**
* A {@link FieldVisitor} that prints the fields it visits with a
* {@link Printer}.
- *
+ *
* @author Eric Bruneton
*/
public final class TraceFieldVisitor extends FieldVisitor {
@@ -52,12 +52,10 @@ public final class TraceFieldVisitor extends FieldVisitor {
super(Opcodes.ASM4, fv);
this.p = p;
}
-
+
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
Printer p = this.p.visitFieldAnnotation(desc, visible);
AnnotationVisitor av = fv == null ? null : fv.visitAnnotation(desc,
visible);
diff --git a/src/asm/scala/tools/asm/util/TraceMethodVisitor.java b/src/asm/scala/tools/asm/util/TraceMethodVisitor.java
index 9aabf2079e..9034567c8f 100644
--- a/src/asm/scala/tools/asm/util/TraceMethodVisitor.java
+++ b/src/asm/scala/tools/asm/util/TraceMethodVisitor.java
@@ -56,10 +56,8 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitAnnotation(
- final String desc,
- final boolean visible)
- {
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
Printer p = this.p.visitMethodAnnotation(desc, visible);
AnnotationVisitor av = mv == null ? null : mv.visitAnnotation(desc,
visible);
@@ -80,17 +78,11 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public AnnotationVisitor visitParameterAnnotation(
- final int parameter,
- final String desc,
- final boolean visible)
- {
- Printer p = this.p.visitParameterAnnotation(parameter,
- desc,
- visible);
- AnnotationVisitor av = mv == null
- ? null
- : mv.visitParameterAnnotation(parameter, desc, visible);
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
+ Printer p = this.p.visitParameterAnnotation(parameter, desc, visible);
+ AnnotationVisitor av = mv == null ? null : mv.visitParameterAnnotation(
+ parameter, desc, visible);
return new TraceAnnotationVisitor(av, p);
}
@@ -101,13 +93,8 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public void visitFrame(
- final int type,
- final int nLocal,
- final Object[] local,
- final int nStack,
- final Object[] stack)
- {
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
p.visitFrame(type, nLocal, local, nStack, stack);
super.visitFrame(type, nLocal, local, nStack, stack);
}
@@ -137,34 +124,22 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public void visitFieldInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
p.visitFieldInsn(opcode, owner, name, desc);
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
- public void visitMethodInsn(
- final int opcode,
- final String owner,
- final String name,
- final String desc)
- {
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
p.visitMethodInsn(opcode, owner, name, desc);
super.visitMethodInsn(opcode, owner, name, desc);
}
@Override
- public void visitInvokeDynamicInsn(
- String name,
- String desc,
- Handle bsm,
- Object... bsmArgs)
- {
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
p.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
}
@@ -194,22 +169,15 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public void visitTableSwitchInsn(
- final int min,
- final int max,
- final Label dflt,
- final Label... labels)
- {
+ public void visitTableSwitchInsn(final int min, final int max,
+ final Label dflt, final Label... labels) {
p.visitTableSwitchInsn(min, max, dflt, labels);
super.visitTableSwitchInsn(min, max, dflt, labels);
}
@Override
- public void visitLookupSwitchInsn(
- final Label dflt,
- final int[] keys,
- final Label[] labels)
- {
+ public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+ final Label[] labels) {
p.visitLookupSwitchInsn(dflt, keys, labels);
super.visitLookupSwitchInsn(dflt, keys, labels);
}
@@ -221,25 +189,16 @@ public final class TraceMethodVisitor extends MethodVisitor {
}
@Override
- public void visitTryCatchBlock(
- final Label start,
- final Label end,
- final Label handler,
- final String type)
- {
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
p.visitTryCatchBlock(start, end, handler, type);
super.visitTryCatchBlock(start, end, handler, type);
}
@Override
- public void visitLocalVariable(
- final String name,
- final String desc,
- final String signature,
- final Label start,
- final Label end,
- final int index)
- {
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
p.visitLocalVariable(name, desc, signature, start, end, index);
super.visitLocalVariable(name, desc, signature, start, end, index);
}
diff --git a/src/asm/scala/tools/asm/util/TraceSignatureVisitor.java b/src/asm/scala/tools/asm/util/TraceSignatureVisitor.java
index a37b759811..1e23c7ef1a 100644
--- a/src/asm/scala/tools/asm/util/TraceSignatureVisitor.java
+++ b/src/asm/scala/tools/asm/util/TraceSignatureVisitor.java
@@ -117,8 +117,7 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
@Override
public SignatureVisitor visitInterface() {
- separator = seenInterface ? ", " : isInterface
- ? " extends "
+ separator = seenInterface ? ", " : isInterface ? " extends "
: " implements ";
seenInterface = true;
startType();
@@ -165,34 +164,34 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
@Override
public void visitBaseType(final char descriptor) {
switch (descriptor) {
- case 'V':
- declaration.append("void");
- break;
- case 'B':
- declaration.append("byte");
- break;
- case 'J':
- declaration.append("long");
- break;
- case 'Z':
- declaration.append("boolean");
- break;
- case 'I':
- declaration.append("int");
- break;
- case 'S':
- declaration.append("short");
- break;
- case 'C':
- declaration.append("char");
- break;
- case 'F':
- declaration.append("float");
- break;
- // case 'D':
- default:
- declaration.append("double");
- break;
+ case 'V':
+ declaration.append("void");
+ break;
+ case 'B':
+ declaration.append("byte");
+ break;
+ case 'J':
+ declaration.append("long");
+ break;
+ case 'Z':
+ declaration.append("boolean");
+ break;
+ case 'I':
+ declaration.append("int");
+ break;
+ case 'S':
+ declaration.append("short");
+ break;
+ case 'C':
+ declaration.append("char");
+ break;
+ case 'F':
+ declaration.append("float");
+ break;
+ // case 'D':
+ default:
+ declaration.append("double");
+ break;
}
endType();
}
diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala
index 0ff098e1da..3a68794c97 100644
--- a/src/compiler/scala/reflect/reify/Errors.scala
+++ b/src/compiler/scala/reflect/reify/Errors.scala
@@ -27,10 +27,10 @@ trait Errors {
}
def CannotConvertManifestToTagWithoutScalaReflect(tpe: Type, manifestInScope: Tree) = {
- val msg = s"""
- |to create a type tag here, it is necessary to interoperate with the manifest `$manifestInScope` in scope.
- |however manifest -> typetag conversion requires Scala reflection, which is not present on the classpath.
- |to proceed put scala-reflect.jar on your compilation classpath and recompile.""".trim.stripMargin
+ val msg =
+ sm"""to create a type tag here, it is necessary to interoperate with the manifest `$manifestInScope` in scope.
+ |however manifest -> typetag conversion requires Scala reflection, which is not present on the classpath.
+ |to proceed put scala-reflect.jar on your compilation classpath and recompile."""
throw new ReificationException(defaultErrorPosition, msg)
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 39103b801e..731aab93b8 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -98,7 +98,7 @@ trait GenSymbols {
def reifyFreeTerm(binding: Tree): Tree =
reifyIntoSymtab(binding.symbol) { sym =>
if (reifyDebug) println("Free term" + (if (sym.isCapturedVariable) " (captured)" else "") + ": " + sym + "(" + sym.accurateKindString + ")")
- val name = newTermName(nme.REIFY_FREE_PREFIX + sym.name + (if (sym.isType) nme.REIFY_FREE_THIS_SUFFIX else ""))
+ val name = newTermName("" + nme.REIFY_FREE_PREFIX + sym.name + (if (sym.isType) nme.REIFY_FREE_THIS_SUFFIX else ""))
if (sym.isCapturedVariable) {
assert(binding.isInstanceOf[Ident], showRaw(binding))
val capturedBinding = referenceCapturedVariable(sym)
@@ -112,14 +112,14 @@ trait GenSymbols {
reifyIntoSymtab(binding.symbol) { sym =>
if (reifyDebug) println("Free type: %s (%s)".format(sym, sym.accurateKindString))
state.reificationIsConcrete = false
- val name = newTermName(nme.REIFY_FREE_PREFIX + sym.name)
+ val name: TermName = nme.REIFY_FREE_PREFIX append sym.name
Reification(name, binding, mirrorBuildCall(nme.newFreeType, reify(sym.name.toString), mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(origin(sym))))
}
def reifySymDef(sym: Symbol): Tree =
reifyIntoSymtab(sym) { sym =>
if (reifyDebug) println("Sym def: %s (%s)".format(sym, sym.accurateKindString))
- val name = newTermName(nme.REIFY_SYMDEF_PREFIX + sym.name)
+ val name: TermName = nme.REIFY_SYMDEF_PREFIX append sym.name
def reifiedOwner = if (sym.owner.isLocatable) reify(sym.owner) else reifySymDef(sym.owner)
Reification(name, Ident(sym), mirrorBuildCall(nme.newNestedSymbol, reifiedOwner, reify(sym.name), reify(sym.pos), mirrorBuildCall(nme.flagsFromBits, reify(sym.flags)), reify(sym.isClass)))
}
@@ -143,7 +143,7 @@ trait GenSymbols {
val reification = reificode(sym)
import reification.{name, binding}
val tree = reification.tree updateAttachment ReifyBindingAttachment(binding)
- state.symtab += (sym, name, tree)
+ state.symtab += (sym, name.toTermName, tree)
}
fromSymtab
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index 86ad23cd15..f60089c935 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -45,7 +45,9 @@ trait GenTrees {
case global.EmptyTree =>
reifyMirrorObject(EmptyTree)
case global.emptyValDef =>
- mirrorBuildSelect(nme.emptyValDef)
+ mirrorSelect(nme.emptyValDef)
+ case global.pendingSuperCall =>
+ mirrorSelect(nme.pendingSuperCall)
case FreeDef(_, _, _, _, _) =>
reifyNestedFreeDef(tree)
case FreeRef(_, _) =>
@@ -101,7 +103,8 @@ trait GenTrees {
case ReifiedTree(_, _, inlinedSymtab, rtree, _, _, _) =>
if (reifyDebug) println("inlining the splicee")
// all free vars local to the enclosing reifee should've already been inlined by ``Metalevels''
- inlinedSymtab.syms foreach (sym => if (sym.isLocalToReifee) assert(false, inlinedSymtab.symDef(sym)))
+ for (sym <- inlinedSymtab.syms if sym.isLocalToReifee)
+ abort("local free var, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym))
state.symtab ++= inlinedSymtab
rtree
case tree =>
@@ -117,88 +120,102 @@ trait GenTrees {
// unlike in `reifyBoundType` we can skip checking for `tpe` being local or not local w.r.t the reifee
// a single check for a symbol of the bound term should be enough
// that's because only Idents and Thises can be bound terms, and they cannot host complex types
- private def reifyBoundTerm(tree: Tree): Tree = tree match {
- case tree @ This(_) if tree.symbol == NoSymbol =>
- throw new Error("unexpected: bound term that doesn't have a symbol: " + showRaw(tree))
- case tree @ This(_) if tree.symbol.isClass && !tree.symbol.isModuleClass && !tree.symbol.isLocalToReifee =>
- val sym = tree.symbol
- if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
- if (reifyDebug) println("Free: " + sym)
- mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym)))
- case tree @ This(_) if !tree.symbol.isLocalToReifee =>
- if (reifyDebug) println("This for %s, reified as This".format(tree.symbol))
- mirrorBuildCall(nme.This, reify(tree.symbol))
- case tree @ This(_) if tree.symbol.isLocalToReifee =>
- mirrorCall(nme.This, reify(tree.qual))
- case tree @ Ident(_) if tree.symbol == NoSymbol =>
- // this sometimes happens, e.g. for binds that don't have a body
- // or for untyped code generated during previous phases
- // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
- mirrorCall(nme.Ident, reify(tree.name))
- case tree @ Ident(_) if !tree.symbol.isLocalToReifee =>
- if (tree.symbol.isVariable && tree.symbol.owner.isTerm) {
- captureVariable(tree.symbol) // Note order dependency: captureVariable needs to come before reification here.
- mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(tree.symbol)), reify(nme.elem))
- } else {
- mirrorBuildCall(nme.Ident, reify(tree.symbol))
- }
- case tree @ Ident(_) if tree.symbol.isLocalToReifee =>
- mirrorCall(nme.Ident, reify(tree.name))
- case _ =>
- throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ private def reifyBoundTerm(tree: Tree): Tree = {
+ val sym = tree.symbol
+
+ tree match {
+ case This(qual) =>
+ assert(sym != NoSymbol, "unexpected: bound term that doesn't have a symbol: " + showRaw(tree))
+ if (sym.isLocalToReifee)
+ mirrorCall(nme.This, reify(qual))
+ else if (sym.isClass && !sym.isModuleClass) {
+ if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
+ if (reifyDebug) println("Free: " + sym)
+ mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym)))
+ }
+ else {
+ if (reifyDebug) println("This for %s, reified as This".format(sym))
+ mirrorBuildCall(nme.This, reify(sym))
+ }
+
+ case Ident(name) =>
+ if (sym == NoSymbol) {
+ // this sometimes happens, e.g. for binds that don't have a body
+ // or for untyped code generated during previous phases
+ // (see a comment in Reifiers about the latter, starting with "why do we resetAllAttrs?")
+ mirrorCall(nme.Ident, reify(name))
+ }
+ else if (!sym.isLocalToReifee) {
+ if (sym.isVariable && sym.owner.isTerm) {
+ captureVariable(sym) // Note order dependency: captureVariable needs to come before reification here.
+ mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(sym)), reify(nme.elem))
+ }
+ else mirrorBuildCall(nme.Ident, reify(sym))
+ }
+ else mirrorCall(nme.Ident, reify(name))
+
+ case Select(qual, name) =>
+ if (sym == NoSymbol || sym.name == name)
+ reifyProduct(tree)
+ else
+ reifyProduct(Select(qual, sym.name))
+
+ case _ =>
+ throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
+ }
}
private def reifyBoundType(tree: Tree): Tree = {
+ val sym = tree.symbol
+ val tpe = tree.tpe
+
def reifyBoundType(tree: Tree): Tree = {
- if (tree.tpe == null)
- throw new Error("unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
+ assert(tpe != null, "unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
// if a symbol or a type of the scrutinee are local to reifee
// (e.g. point to a locally declared class or to a path-dependent thingie that depends on a local variable)
// then we can reify the scrutinee as a symless AST and that will definitely be hygienic
// why? because then typechecking of a scrutinee doesn't depend on the environment external to the quasiquote
// otherwise we need to reify the corresponding type
- if (tree.symbol.isLocalToReifee || tree.tpe.isLocalToReifee)
+ if (sym.isLocalToReifee || tpe.isLocalToReifee)
reifyProduct(tree)
else {
- val sym = tree.symbol
- val tpe = tree.tpe
if (reifyDebug) println("reifying bound type %s (underlying type is %s)".format(sym, tpe))
if (tpe.isSpliceable) {
val spliced = spliceType(tpe)
+
if (spliced == EmptyTree) {
if (reifyDebug) println("splicing failed: reify as is")
mirrorBuildCall(nme.TypeTree, reify(tpe))
- } else {
- spliced match {
- case TypeRefToFreeType(freeType) =>
- if (reifyDebug) println("splicing returned a free type: " + freeType)
- Ident(freeType)
- case _ =>
- if (reifyDebug) println("splicing succeeded: " + spliced)
- mirrorBuildCall(nme.TypeTree, spliced)
- }
}
- } else {
- if (sym.isLocatable) {
- if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
- mirrorBuildCall(nme.Ident, reify(sym))
- } else {
- if (reifyDebug) println("tpe is not locatable: reify as TypeTree(%s)".format(tpe))
- mirrorBuildCall(nme.TypeTree, reify(tpe))
+ else spliced match {
+ case TypeRefToFreeType(freeType) =>
+ if (reifyDebug) println("splicing returned a free type: " + freeType)
+ Ident(freeType)
+ case _ =>
+ if (reifyDebug) println("splicing succeeded: " + spliced)
+ mirrorBuildCall(nme.TypeTree, spliced)
}
}
+ else if (sym.isLocatable) {
+ if (reifyDebug) println("tpe is locatable: reify as Ident(%s)".format(sym))
+ mirrorBuildCall(nme.Ident, reify(sym))
+ }
+ else {
+ if (reifyDebug) println("tpe is not locatable: reify as TypeTree(%s)".format(tpe))
+ mirrorBuildCall(nme.TypeTree, reify(tpe))
+ }
}
}
tree match {
- case Select(_, _) =>
- reifyBoundType(tree)
- case SelectFromTypeTree(_, _) =>
- reifyBoundType(tree)
- case Ident(_) =>
+ case Select(qual, name) if name != sym.name =>
+ reifyBoundType(Select(qual, sym.name))
+
+ case Select(_, _) | SelectFromTypeTree(_, _) | Ident(_) =>
reifyBoundType(tree)
+
case _ =>
throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass))
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index e2275f79ff..e0570d61f2 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -30,41 +30,32 @@ trait GenUtils {
def call(fname: String, args: Tree*): Tree =
Apply(termPath(fname), args.toList)
- def mirrorSelect(name: String): Tree =
- termPath(nme.UNIVERSE_PREFIX + name)
+ def mirrorSelect(name: String): Tree = termPath(nme.UNIVERSE_PREFIX + name)
+ def mirrorSelect(name: TermName): Tree = mirrorSelect(name.toString)
- def mirrorBuildSelect(name: String): Tree =
- termPath(nme.UNIVERSE_BUILD_PREFIX + name)
-
- def mirrorMirrorSelect(name: String): Tree =
- termPath(nme.MIRROR_PREFIX + name)
+ def mirrorMirrorSelect(name: TermName): Tree =
+ termPath("" + nme.MIRROR_PREFIX + name)
def mirrorCall(name: TermName, args: Tree*): Tree =
- call("" + (nme.UNIVERSE_PREFIX append name), args: _*)
-
- def mirrorCall(name: String, args: Tree*): Tree =
- call(nme.UNIVERSE_PREFIX + name, args: _*)
+ call("" + nme.UNIVERSE_PREFIX + name, args: _*)
def mirrorBuildCall(name: TermName, args: Tree*): Tree =
- call("" + (nme.UNIVERSE_BUILD_PREFIX append name), args: _*)
-
- def mirrorBuildCall(name: String, args: Tree*): Tree =
- call(nme.UNIVERSE_BUILD_PREFIX + name, args: _*)
+ call("" + nme.UNIVERSE_BUILD_PREFIX + name, args: _*)
def mirrorMirrorCall(name: TermName, args: Tree*): Tree =
- call("" + (nme.MIRROR_PREFIX append name), args: _*)
-
- def mirrorMirrorCall(name: String, args: Tree*): Tree =
- call(nme.MIRROR_PREFIX + name, args: _*)
+ call("" + nme.MIRROR_PREFIX + name, args: _*)
def mirrorFactoryCall(value: Product, args: Tree*): Tree =
mirrorFactoryCall(value.productPrefix, args: _*)
- def mirrorFactoryCall(prefix: String, args: Tree*): Tree =
- mirrorCall(prefix, args: _*)
+ def mirrorFactoryCall(prefix: TermName, args: Tree*): Tree =
+ mirrorCall("" + prefix, args: _*)
+
+ def scalaFactoryCall(name: TermName, args: Tree*): Tree =
+ call(s"scala.$name.apply", args: _*)
def scalaFactoryCall(name: String, args: Tree*): Tree =
- call("scala." + name + ".apply", args: _*)
+ scalaFactoryCall(name: TermName, args: _*)
def mkList(args: List[Tree]): Tree =
scalaFactoryCall("collection.immutable.List", args: _*)
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
index f31c3d4755..75384ddce1 100644
--- a/src/compiler/scala/reflect/reify/phases/Reshape.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -254,7 +254,7 @@ trait Reshape {
val flags1 = (flags0 & GetterFlags) & ~(STABLE | ACCESSOR | METHOD)
val mods1 = Modifiers(flags1, privateWithin0, annotations0) setPositions mods0.positions
val mods2 = toPreTyperModifiers(mods1, ddef.symbol)
- ValDef(mods2, name1, tpt0, extractRhs(rhs0))
+ ValDef(mods2, name1.toTermName, tpt0, extractRhs(rhs0))
}
private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = {
@@ -293,7 +293,7 @@ trait Reshape {
}
val mods2 = toPreTyperModifiers(mods1, vdef.symbol)
val name1 = nme.dropLocalSuffix(name)
- val vdef1 = ValDef(mods2, name1, tpt, rhs)
+ val vdef1 = ValDef(mods2, name1.toTermName, tpt, rhs)
if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1))
Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are now out of sync
case ddef: DefDef if !ddef.mods.isLazy =>
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index 50bd309b52..254cb02ee6 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -251,6 +251,8 @@ trait Extractors {
object BoundTerm {
def unapply(tree: Tree): Option[Tree] = tree match {
+ case Select(_, name) if name.isTermName =>
+ Some(tree)
case Ident(name) if name.isTermName =>
Some(tree)
case This(_) =>
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index 97ec479a6c..86e50e0a68 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -75,10 +75,10 @@ trait NodePrinters {
printout += universe.trim
if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim
val imports = scala.collection.mutable.ListBuffer[String]();
- imports += nme.UNIVERSE_SHORT
+ imports += nme.UNIVERSE_SHORT.toString
// if (buildIsUsed) imports += nme.build
- if (mirrorIsUsed) imports += nme.MIRROR_SHORT
- if (flagsAreUsed) imports += nme.Flag
+ if (mirrorIsUsed) imports += nme.MIRROR_SHORT.toString
+ if (flagsAreUsed) imports += nme.Flag.toString
printout += s"""import ${imports map (_ + "._") mkString ", "}"""
val name = if (isExpr) "tree" else "tpe"
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index cf3b5f949b..3b8ae202f6 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -56,8 +56,6 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `usejavacp`,
* - `failonerror`,
* - `scalacdebugging`,
- * - `assemname`,
- * - `assemrefs`.
*
* It also takes the following parameters as nested elements:
* - `src` (for `srcdir`),
@@ -100,7 +98,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** Defines valid values for the `target` property. */
object Target extends PermissibleValue {
- val values = List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "msil")
+ val values = List("jvm-1.5", "jvm-1.6", "jvm-1.7")
}
/** Defines valid values for the `deprecation` and `unchecked` properties. */
@@ -170,11 +168,6 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** Indicates whether compilation errors will fail the build; defaults to true. */
protected var failonerror: Boolean = true
- // Name of the output assembly (only relevant with -target:msil)
- protected var assemname: Option[String] = None
- // List of assemblies referenced by the program (only relevant with -target:msil)
- protected var assemrefs: Option[String] = None
-
/** Prints out the files being compiled by the scalac ant task
* (not only the number of files). */
protected var scalacDebugging: Boolean = false
@@ -421,9 +414,6 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
* @param input The specified flag */
def setScalacdebugging(input: Boolean) { scalacDebugging = input }
- def setAssemname(input: String) { assemname = Some(input) }
- def setAssemrefs(input: String) { assemrefs = Some(input) }
-
/** Sets the `compilerarg` as a nested compilerarg Ant parameter.
* @return A compiler argument to be configured. */
def createCompilerArg(): ImplementationSpecificArgument = {
@@ -616,9 +606,6 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
if (!unchecked.isEmpty) settings.unchecked.value = unchecked.get
if (!usejavacp.isEmpty) settings.usejavacp.value = usejavacp.get
- if (!assemname.isEmpty) settings.assemname.value = assemname.get
- if (!assemrefs.isEmpty) settings.assemrefs.value = assemrefs.get
-
val jvmargs = scalacCompilerArgs.getArgs filter (_ startsWith "-J")
if (!jvmargs.isEmpty) settings.jvmargs.value = jvmargs.toList
val defines = scalacCompilerArgs.getArgs filter (_ startsWith "-D")
diff --git a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
index 9cdf484080..d5545fe76a 100644
--- a/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
+++ b/src/compiler/scala/tools/ant/sabbus/ScalacFork.scala
@@ -80,7 +80,7 @@ class ScalacFork extends ScalaMatchingTask with ScalacShared with TaskArgs {
private def createMapper() = {
val mapper = new GlobPatternMapper()
- val extension = if (isMSIL) "*.msil" else "*.class"
+ val extension = "*.class"
mapper setTo extension
mapper setFrom "*.scala"
@@ -104,9 +104,6 @@ class ScalacFork extends ScalaMatchingTask with ScalacShared with TaskArgs {
sourcePath foreach (settings.sourcepath = _)
settings.extraParams = extraArgsFlat
- if (isMSIL)
- settings.sourcedir = sourceDir
-
val mapper = createMapper()
val includedFiles: Array[File] =
diff --git a/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala b/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
index 6bb1aaa306..b061bcf7fb 100644
--- a/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
+++ b/src/compiler/scala/tools/ant/sabbus/TaskArgs.scala
@@ -98,6 +98,4 @@ trait TaskArgs extends CompilationPathProperty {
val parts = a.getParts
if(parts eq null) Seq[String]() else parts.toSeq
}
-
- def isMSIL = compTarget exists (_ == "msil")
}
diff --git a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
index f1c6c52785..84ccaba749 100644
--- a/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
+++ b/src/compiler/scala/tools/ant/templates/tool-unix.tmpl
@@ -102,6 +102,9 @@ if [[ -n "$cygwin" ]]; then
format=windows
fi
SCALA_HOME="$(cygpath --$format "$SCALA_HOME")"
+ if [[ -n "$JAVA_HOME" ]]; then
+ JAVA_HOME="$(cygpath --$format "$JAVA_HOME")"
+ fi
TOOL_CLASSPATH="$(cygpath --path --$format "$TOOL_CLASSPATH")"
elif [[ -n "$mingw" ]]; then
SCALA_HOME="$(cmd //c echo "$SCALA_HOME")"
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 663fbeceb0..a2108b8ced 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi { self =>
/** the fresh name creator */
val fresh: FreshNameCreator = new FreshNameCreator.Default
@@ -47,7 +47,23 @@ trait CompilationUnits { self: Global =>
/** Synthetic definitions generated by namer, eliminated by typer.
*/
- val synthetics = mutable.HashMap[Symbol, Tree]()
+ object synthetics {
+ private val map = mutable.HashMap[Symbol, Tree]()
+ def update(sym: Symbol, tree: Tree) {
+ debuglog(s"adding synthetic ($sym, $tree) to $self")
+ map.update(sym, tree)
+ }
+ def -=(sym: Symbol) {
+ debuglog(s"removing synthetic $sym from $self")
+ map -= sym
+ }
+ def get(sym: Symbol): Option[Tree] = logResultIf[Option[Tree]](s"found synthetic for $sym in $self", _.isDefined) {
+ map get sym
+ }
+ def keys: Iterable[Symbol] = map.keys
+ def clear(): Unit = map.clear()
+ override def toString = map.toString
+ }
/** things to check at end of compilation unit */
val toCheck = new ListBuffer[() => Unit]
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index f79990d526..e4c250a3d9 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -56,9 +56,6 @@ class StandardCompileServer extends SocketServer {
(totalMemory - freeMemory).toDouble / maxMemory.toDouble > MaxCharge
}
- protected def newOfflineCompilerCommand(arguments: List[String], settings: FscSettings): OfflineCompilerCommand =
- new OfflineCompilerCommand(arguments, settings)
-
/** Problematically, Settings are only considered equal if every setting
* is exactly equal. In fsc this immediately breaks down because the randomly
* chosen temporary outdirs differ between client and server. Among other
@@ -91,7 +88,7 @@ class StandardCompileServer extends SocketServer {
val args = input.split("\0", -1).toList
val newSettings = new FscSettings(fscError)
this.verbose = newSettings.verbose.value
- val command = newOfflineCompilerCommand(args, newSettings)
+ val command = new OfflineCompilerCommand(args, newSettings)
info("Settings after normalizing paths: " + newSettings)
printMemoryStats()
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 397e6c42d7..34d5d10cbf 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -23,8 +23,8 @@ import ast.parser._
import typechecker._
import transform._
import backend.icode.{ ICodes, GenICode, ICodeCheckers }
-import backend.{ ScalaPrimitives, Platform, MSILPlatform, JavaPlatform }
-import backend.jvm.{GenJVM, GenASM}
+import backend.{ ScalaPrimitives, Platform, JavaPlatform }
+import backend.jvm.GenASM
import backend.opt.{ Inliners, InlineExceptionHandlers, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
import scala.language.postfixOps
@@ -77,8 +77,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
type ThisPlatform = Platform { val global: Global.this.type }
lazy val platform: ThisPlatform =
- if (forMSIL) new { val global: Global.this.type = Global.this } with MSILPlatform
- else new { val global: Global.this.type = Global.this } with JavaPlatform
+ new { val global: Global.this.type = Global.this } with JavaPlatform
type PlatformClassPath = ClassPath[platform.BinaryRepr]
type OptClassPath = Option[PlatformClassPath]
@@ -594,13 +593,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val runsRightAfter = None
} with DeadCodeElimination
- // phaseName = "jvm", FJBG-based version
- object genJVM extends {
- val global: Global.this.type = Global.this
- val runsAfter = List("dce")
- val runsRightAfter = None
- } with GenJVM
-
// phaseName = "jvm", ASM-based version
object genASM extends {
val global: Global.this.type = Global.this
@@ -620,7 +612,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
object terminal extends {
val global: Global.this.type = Global.this
val phaseName = "terminal"
- val runsAfter = List("jvm", "msil")
+ val runsAfter = List("jvm")
val runsRightAfter = None
} with SubComponent {
private var cache: Option[GlobalPhase] = None
@@ -1314,7 +1306,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val closelimPhase = phaseNamed("closelim")
val dcePhase = phaseNamed("dce")
// val jvmPhase = phaseNamed("jvm")
- // val msilPhase = phaseNamed("msil")
def runIsAt(ph: Phase) = globalPhase.id == ph.id
def runIsAtOptimiz = {
@@ -1675,14 +1666,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
})
}
- // In order to not outright break code which overrides onlyPresentation (like sbt 0.7.5.RC0)
- // I restored and deprecated it. That would be enough to avoid the compilation
- // failure, but the override wouldn't accomplish anything. So now forInteractive
- // and forScaladoc default to onlyPresentation, which is the same as defaulting
- // to false except in old code. The downside is that this leaves us calling a
- // deprecated method: but I see no simple way out, so I leave it for now.
- // def forJVM = settings.target.value startsWith "jvm"
- override def forMSIL = settings.target.value startsWith "msil"
def forInteractive = false
def forScaladoc = false
def createJavadoc = false
diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala
index 5a3ea56f67..a4b22b0e11 100644
--- a/src/compiler/scala/tools/nsc/Main.scala
+++ b/src/compiler/scala/tools/nsc/Main.scala
@@ -9,7 +9,6 @@ import java.io.File
import File.pathSeparator
import scala.tools.nsc.interactive.{ RefinedBuildManager, SimpleBuildManager }
import scala.tools.nsc.io.AbstractFile
-import Properties.msilLibPath
/** The main class for NSC, a compiler for the programming
* language Scala.
@@ -60,11 +59,7 @@ object Main extends Driver with EvalLoop {
}
false
}
- else {
- if (settings.target.value == "msil")
- msilLibPath foreach (x => settings.assemrefs.value += (pathSeparator + x))
- true
- }
+ else true
override def newCompiler(): Global =
if (settings.Yrangepos.value) new Global(settings, reporter) with interactive.RangePositions
diff --git a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
index 8a3c531ff0..2f4975e681 100644
--- a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
@@ -26,8 +26,8 @@ class OfflineCompilerCommand(arguments: List[String], settings: FscSettings) ext
// instead of whatever it's supposed to be doing.
val baseDirectory = {
val pwd = System.getenv("PWD")
- if (pwd != null && !isWin) Directory(pwd)
- else Directory.Current getOrElse Directory("/")
+ if (pwd == null || isWin) Directory.Current getOrElse Directory("/")
+ else Directory(pwd)
}
currentDir.value = baseDirectory.path
}
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala
index 570d5572d6..feb4ded2f2 100644
--- a/src/compiler/scala/tools/nsc/Properties.scala
+++ b/src/compiler/scala/tools/nsc/Properties.scala
@@ -16,9 +16,6 @@ object Properties extends scala.util.PropertiesTrait {
def residentPromptString = scalaPropOrElse("resident.prompt", "\nnsc> ")
def shellPromptString = scalaPropOrElse("shell.prompt", "\nscala> ")
- // settings based on system properties
- def msilLibPath = propOrNone("msil.libpath")
-
// derived values
def isEmacsShell = propOrEmpty("env.emacs") != ""
}
diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/compiler/scala/tools/nsc/ScalaDoc.scala
index ba434bc797..14b76b53b3 100644
--- a/src/compiler/scala/tools/nsc/ScalaDoc.scala
+++ b/src/compiler/scala/tools/nsc/ScalaDoc.scala
@@ -10,7 +10,6 @@ import java.io.File.pathSeparator
import scala.tools.nsc.doc.DocFactory
import scala.tools.nsc.reporters.ConsoleReporter
import scala.reflect.internal.util.FakePos
-import Properties.msilLibPath
/** The main class for scaladoc, a front-end for the Scala compiler
* that generates documentation from source files.
@@ -42,12 +41,8 @@ class ScalaDoc {
reporter.warning(null, "Phases are restricted when using Scaladoc")
else if (docSettings.help.value || !hasFiles)
reporter.echo(command.usageMsg)
- else try {
- if (docSettings.target.value == "msil")
- msilLibPath foreach (x => docSettings.assemrefs.value += (pathSeparator + x))
-
- new DocFactory(reporter, docSettings) document command.files
- }
+ else
+ try { new DocFactory(reporter, docSettings) document command.files }
catch {
case ex @ FatalError(msg) =>
if (docSettings.debug.value) ex.printStackTrace()
diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala
index 77acbba056..e7bd5da9dd 100644
--- a/src/compiler/scala/tools/nsc/ast/Positions.scala
+++ b/src/compiler/scala/tools/nsc/ast/Positions.scala
@@ -20,7 +20,7 @@ trait Positions extends scala.reflect.internal.Positions {
// When we prune due to encountering a position, traverse the
// pruned children so we can warn about those lacking positions.
t.children foreach { c =>
- if ((c eq EmptyTree) || (c eq emptyValDef)) ()
+ if (!c.canHaveAttrs) ()
else if (c.pos == NoPosition) {
reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
inform("parent: " + treeSymStatus(t))
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index e8bc932bf5..1c6bba19b3 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -30,24 +30,17 @@ trait TreeDSL {
def returning[T](x: T)(f: T => Unit): T = util.returning(x)(f)
object LIT extends (Any => Literal) {
+ def typed(x: Any) = apply(x) setType ConstantType(Constant(x))
def apply(x: Any) = Literal(Constant(x))
def unapply(x: Any) = condOpt(x) { case Literal(Constant(value)) => value }
}
- // You might think these could all be vals, but empirically I have found that
- // at least in the case of UNIT the compiler breaks if you re-use trees.
- // However we need stable identifiers to have attractive pattern matching.
- // So it's inconsistent until I devise a better way.
- val TRUE = LIT(true)
- val FALSE = LIT(false)
- val ZERO = LIT(0)
- def NULL = LIT(null)
- def UNIT = LIT(())
-
- // for those preferring boring, predictable lives, without the thrills of tree-sharing
- // (but with the perk of typed trees)
- def TRUE_typed = LIT(true) setType ConstantType(Constant(true))
- def FALSE_typed = LIT(false) setType ConstantType(Constant(false))
+ // Boring, predictable trees.
+ def TRUE = LIT typed true
+ def FALSE = LIT typed false
+ def ZERO = LIT(0)
+ def NULL = LIT(null)
+ def UNIT = LIT(())
object WILD {
def empty = Ident(nme.WILDCARD)
@@ -106,6 +99,10 @@ trait TreeDSL {
def DOT(sym: Symbol) = SelectStart(Select(target, sym))
/** Assignment */
+ // !!! This method is responsible for some tree sharing, but a diligent
+ // reviewer pointed out that we shouldn't blindly duplicate these trees
+ // as there might be DefTrees nested beneath them. It's not entirely
+ // clear how to proceed, so for now it retains the non-duplicating behavior.
def ===(rhs: Tree) = Assign(target, rhs)
/** Methods for sequences **/
@@ -181,7 +178,7 @@ trait TreeDSL {
self: VODDStart =>
type ResultTreeType = ValDef
- def mkTree(rhs: Tree): ValDef = ValDef(mods, name, tpt, rhs)
+ def mkTree(rhs: Tree): ValDef = ValDef(mods, name.toTermName, tpt, rhs)
}
trait DefCreator {
self: VODDStart =>
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 1adcf46958..af874ed28c 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -60,33 +60,15 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) {
// This can't be "Annotated(New(UncheckedClass), expr)" because annotations
// are very picky about things and it crashes the compiler with "unexpected new".
- Annotated(New(scalaDot(UncheckedClass.name), ListOfNil), expr)
+ Annotated(New(scalaDot(UncheckedClass.name), Nil), expr)
}
// Builds a tree of the form "{ lhs = rhs ; lhs }"
def mkAssignAndReturn(lhs: Symbol, rhs: Tree): Tree = {
- val lhsRef = mkUnattributedRef(lhs)
+ def lhsRef = if (lhs.owner.isClass) Select(This(lhs.owner), lhs) else Ident(lhs)
Block(Assign(lhsRef, rhs) :: Nil, lhsRef)
}
- def mkModuleVarDef(accessor: Symbol) = {
- val inClass = accessor.owner.isClass
- val extraFlags = if (inClass) PrivateLocal | SYNTHETIC else 0
-
- val mval = (
- accessor.owner.newVariable(nme.moduleVarName(accessor.name), accessor.pos.focus, MODULEVAR | extraFlags)
- setInfo accessor.tpe.finalResultType
- addAnnotation VolatileAttr
- )
- if (inClass)
- mval.owner.info.decls enter mval
-
- ValDef(mval)
- }
-
- def mkModuleAccessDef(accessor: Symbol, msym: Symbol) =
- DefDef(accessor, Select(This(msym.owner), msym))
-
def newModule(accessor: Symbol, tpe: Type) = {
val ps = tpe.typeSymbol.primaryConstructor.info.paramTypes
if (ps.isEmpty) New(tpe)
@@ -210,7 +192,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
*/
private def mkPackedValDef(expr: Tree, owner: Symbol, name: Name): (ValDef, () => Ident) = {
val packedType = typer.packedType(expr, owner)
- val sym = owner.newValue(name, expr.pos.makeTransparent, SYNTHETIC) setInfo packedType
+ val sym = owner.newValue(name.toTermName, expr.pos.makeTransparent, SYNTHETIC) setInfo packedType
(ValDef(sym, expr), () => Ident(sym) setPos sym.pos.focus setType expr.tpe)
}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index c78c40dcd3..0e3e2fe644 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -56,7 +56,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* The class `C` is stored as a tree attachment.
*/
case class InjectDerivedValue(arg: Tree)
- extends SymTree
+ extends SymTree with TermTree
class PostfixSelect(qual: Tree, name: Name) extends Select(qual, name)
@@ -65,6 +65,13 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// --- factory methods ----------------------------------------------------------
+ /** Factory method for a primary constructor super call `super.<init>(args_1)...(args_n)`
+ */
+ def PrimarySuperCall(argss: List[List[Tree]]): Tree = argss match {
+ case Nil => Apply(gen.mkSuperInitCall, Nil)
+ case xs :: rest => rest.foldLeft(Apply(gen.mkSuperInitCall, xs): Tree)(Apply.apply)
+ }
+
/** Generates a template with constructor corresponding to
*
* constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
@@ -82,7 +89,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* body
* }
*/
- def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
+ def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = {
/* Add constructor to template */
// create parameters for <init> as synthetic trees.
@@ -104,7 +111,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
rhs = EmptyTree
)
}
- val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = Modifiers(PRESUPER)) }
+ val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = vdef.mods | PRESUPER) }
val constrs = {
if (constrMods hasFlag TRAIT) {
@@ -117,9 +124,16 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperInitCall)
- val superCall = (superRef /: argss) (Apply.apply)
+ val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass
+ // this requires knowing which of the parents is a type macro and which is not
+ // and that's something that cannot be found out before typer
+ // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon)
+ // this means that we don't know what will be the arguments of the super call
+ // therefore here we emit a dummy which gets populated when the template is named and typechecked
List(
- atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
+ // TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)`
+ // is it going to be a problem that we can no longer include the `argss`?
+ atPos(wrappingPos(superPos, lvdefs)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
@@ -137,11 +151,10 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
* @param vparamss the value parameters -- if they have symbols they
* should be owned by `sym`
- * @param argss the supercall arguments
* @param body the template statements without primary constructor
* and value parameter fields.
*/
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): ClassDef = {
// "if they have symbols they should be owned by `sym`"
assert(
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
@@ -151,7 +164,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
- constrMods, vparamss, argss, body, superPos))
+ constrMods, vparamss, body, superPos))
}
// --- subcomponents --------------------------------------------------
@@ -324,6 +337,8 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
else
super.transform {
tree match {
+ case tree if !tree.canHaveAttrs =>
+ tree
case tpt: TypeTree =>
if (tpt.original != null)
transform(tpt.original)
@@ -337,8 +352,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
transform(fn)
case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
tree
- case EmptyTree =>
- tree
case _ =>
val dupl = tree.duplicate
if (tree.hasSymbolField && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index f430f1fc34..76d7af7cc6 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -701,10 +701,10 @@ self =>
tree match {
case Ident(name) =>
removeAsPlaceholder(name)
- makeParam(name, TypeTree() setPos o2p(tree.pos.endOrPoint))
+ makeParam(name.toTermName, TypeTree() setPos o2p(tree.pos.endOrPoint))
case Typed(Ident(name), tpe) if tpe.isType => // get the ident!
removeAsPlaceholder(name)
- makeParam(name, tpe)
+ makeParam(name.toTermName, tpe)
case _ =>
syntaxError(tree.pos, "not a legal formal parameter", false)
makeParam(nme.ERROR, errorTypeTree setPos o2p(tree.pos.endOrPoint))
@@ -783,7 +783,7 @@ self =>
val rPos = top.pos
val end = if (rPos.isDefined) rPos.endOrPoint else opPos.endOrPoint
top = atPos(start, opinfo.offset, end) {
- makeBinop(isExpr, opinfo.operand, opinfo.operator, top, opPos)
+ makeBinop(isExpr, opinfo.operand, opinfo.operator.toTermName, top, opPos)
}
}
top
@@ -1306,7 +1306,7 @@ self =>
val cond = condExpr()
newLinesOpt()
val body = expr()
- makeWhile(lname, cond, body)
+ makeWhile(lname.toTermName, cond, body)
}
}
parseWhile
@@ -1318,7 +1318,7 @@ self =>
if (isStatSep) in.nextToken()
accept(WHILE)
val cond = condExpr()
- makeDoWhile(lname, body, cond)
+ makeDoWhile(lname.toTermName, body, cond)
}
}
parseDo
@@ -1477,7 +1477,7 @@ self =>
def prefixExpr(): Tree = {
if (isUnaryOp) {
atPos(in.offset) {
- val name = nme.toUnaryName(rawIdent())
+ val name = nme.toUnaryName(rawIdent().toTermName)
if (name == nme.UNARY_- && isNumericLit)
simpleExprRest(atPos(in.offset)(literal(isNegated = true)), canApply = true)
else
@@ -1515,7 +1515,7 @@ self =>
val pname = freshName("x$")
in.nextToken()
val id = atPos(start) (Ident(pname))
- val param = atPos(id.pos.focus){ makeSyntheticParam(pname) }
+ val param = atPos(id.pos.focus){ makeSyntheticParam(pname.toTermName) }
placeholderParams = param :: placeholderParams
id
case LPAREN =>
@@ -1528,9 +1528,9 @@ self =>
val nstart = in.skipToken()
val npos = r2p(nstart, nstart, in.lastOffset)
val tstart = in.offset
- val (parents, argss, self, stats) = template(isTrait = false)
+ val (parents, self, stats) = template()
val cpos = r2p(tstart, tstart, in.lastOffset max tstart)
- makeNew(parents, self, stats, argss, npos, cpos)
+ makeNew(parents, self, stats, npos, cpos)
case _ =>
syntaxErrorOrIncomplete("illegal start of simple expression", true)
errorTermTree
@@ -1898,7 +1898,7 @@ self =>
case _ =>
}
val typeAppliedTree = in.token match {
- case LBRACKET => atPos(start, in.offset)(TypeApply(convertToTypeId(t), typeArgs()))
+ case LBRACKET => atPos(start, in.offset)(AppliedTypeTree(convertToTypeId(t), typeArgs()))
case _ => t
}
in.token match {
@@ -2070,7 +2070,7 @@ self =>
def annotationExpr(): Tree = atPos(in.offset) {
val t = exprSimpleType()
if (in.token == LPAREN) New(t, multipleArgumentExprs())
- else New(t, ListOfNil)
+ else New(t, Nil)
}
/* -------- PARAMETERS ------------------------------------------- */
@@ -2136,7 +2136,7 @@ self =>
expr()
} else EmptyTree
atPos(start, if (name == nme.ERROR) start else nameOffset) {
- ValDef((mods | implicitmod | bynamemod) withAnnotations annots, name, tpt, default)
+ ValDef((mods | implicitmod | bynamemod) withAnnotations annots, name.toTermName, tpt, default)
}
}
def paramClause(): List[ValDef] = {
@@ -2696,7 +2696,7 @@ self =>
atPos(start, if (name == nme.ERROR) start else nameOffset) {
val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods
val template = templateOpt(mods1, name, NoMods, Nil, tstart)
- ModuleDef(mods1, name, template)
+ ModuleDef(mods1, name.toTermName, template)
}
}
@@ -2705,20 +2705,17 @@ self =>
* TraitParents ::= AnnotType {with AnnotType}
* }}}
*/
- def templateParents(isTrait: Boolean): (List[Tree], List[List[Tree]]) = {
- val parents = new ListBuffer[Tree] += startAnnotType()
- val argss = (
- // TODO: the insertion of ListOfNil here is where "new Foo" becomes
- // indistinguishable from "new Foo()".
- if (in.token == LPAREN && !isTrait) multipleArgumentExprs()
- else ListOfNil
- )
-
- while (in.token == WITH) {
- in.nextToken()
- parents += startAnnotType()
+ def templateParents(): List[Tree] = {
+ val parents = new ListBuffer[Tree]
+ def readAppliedParent() = {
+ val start = in.offset
+ val parent = startAnnotType()
+ val argss = if (in.token == LPAREN) multipleArgumentExprs() else Nil
+ parents += atPos(start)((parent /: argss)(Apply.apply))
}
- (parents.toList, argss)
+ readAppliedParent()
+ while (in.token == WITH) { in.nextToken(); readAppliedParent() }
+ parents.toList
}
/** {{{
@@ -2728,12 +2725,12 @@ self =>
* EarlyDef ::= Annotations Modifiers PatDef
* }}}
*/
- def template(isTrait: Boolean): (List[Tree], List[List[Tree]], ValDef, List[Tree]) = {
+ def template(): (List[Tree], ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
// @S: pre template body cannot stub like post body can!
val (self, body) = templateBody(isPre = true)
- if (in.token == WITH && self.isEmpty) {
+ if (in.token == WITH && (self eq emptyValDef)) {
val earlyDefs: List[Tree] = body flatMap {
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
List(copyValDef(vdef)(mods = mods | Flags.PRESUPER))
@@ -2745,16 +2742,16 @@ self =>
case _ => List()
}
in.nextToken()
- val (parents, argss) = templateParents(isTrait = isTrait)
- val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait)
- (parents, argss, self1, earlyDefs ::: body1)
+ val parents = templateParents()
+ val (self1, body1) = templateBodyOpt(parenMeansSyntaxError = false)
+ (parents, self1, earlyDefs ::: body1)
} else {
- (List(), ListOfNil, self, body)
+ (List(), self, body)
}
} else {
- val (parents, argss) = templateParents(isTrait = isTrait)
- val (self, body) = templateBodyOpt(traitParentSeen = isTrait)
- (parents, argss, self, body)
+ val parents = templateParents()
+ val (self, body) = templateBodyOpt(parenMeansSyntaxError = false)
+ (parents, self, body)
}
}
@@ -2768,15 +2765,15 @@ self =>
* }}}
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
- val (parents0, argss, self, body) = (
+ val (parents0, self, body) = (
if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) {
in.nextToken()
- template(isTrait = mods.isTrait)
+ template()
}
else {
newLineOptWhenFollowedBy(LBRACE)
- val (self, body) = templateBodyOpt(traitParentSeen = false)
- (List(), ListOfNil, self, body)
+ val (self, body) = templateBodyOpt(parenMeansSyntaxError = mods.isTrait || name.isTermName)
+ (List(), self, body)
}
)
def anyrefParents() = {
@@ -2798,7 +2795,7 @@ self =>
if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents0, self, anyvalConstructor :: body)
else
- Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
+ Template(anyrefParents, self, constrMods, vparamss, body, o2p(tstart))
}
}
@@ -2813,14 +2810,15 @@ self =>
case (self, Nil) => (self, EmptyTree.asList)
case result => result
}
- def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = {
+ def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
templateBody(isPre = false)
} else {
- if (in.token == LPAREN)
- syntaxError((if (traitParentSeen) "parents of traits" else "traits or objects")+
- " may not have parameters", true)
+ if (in.token == LPAREN) {
+ if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", true)
+ else abort("unexpected opening parenthesis")
+ }
(emptyValDef, List())
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index d6c499d838..39270719fb 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -201,20 +201,26 @@ abstract class TreeBuilder {
*/
def makeAnonymousNew(stats: List[Tree]): Tree = {
val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats
- makeNew(Nil, emptyValDef, stats1, ListOfNil, NoPosition, NoPosition)
+ makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition)
}
/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
* @param cpos the position of the anonymous class starting with parents
*/
- def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
+ def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree],
npos: Position, cpos: Position): Tree =
if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr), self, stats, argss, npos, cpos)
- else if (parents.tail.isEmpty && stats.isEmpty)
- atPos(npos union cpos) { New(parents.head, argss) }
- else {
+ makeNew(List(scalaAnyRefConstr), self, stats, npos, cpos)
+ else if (parents.tail.isEmpty && stats.isEmpty) {
+ // `Parsers.template` no longer differentiates tpts and their argss
+ // e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil)
+ // instead of parents = Ident(C), argss = Nil as before
+ // this change works great for things that are actually templates
+ // but in this degenerate case we need to perform postprocessing
+ val app = treeInfo.dissectApplied(parents.head)
+ atPos(npos union cpos) { New(app.callee, app.argss) }
+ } else {
val x = tpnme.ANON_CLASS_NAME
atPos(npos union cpos) {
Block(
@@ -222,12 +228,12 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, ListOfNil, argss, stats, cpos.focus))
+ Template(parents, self, NoMods, ListOfNil, stats, cpos.focus))
}),
atPos(npos) {
New(
Ident(x) setPos npos.focus,
- ListOfNil)
+ Nil)
}
)
}
diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
index fd4366baf1..5cc4404ca1 100644
--- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
@@ -42,13 +42,9 @@ trait JavaPlatform extends Platform {
if (settings.make.isDefault) Nil
else List(dependencyAnalysis)
- private def classEmitPhase =
- if (settings.target.value == "jvm-1.5-fjbg") genJVM
- else genASM
-
def platformPhases = List(
flatten, // get rid of inner classes
- classEmitPhase // generate .class files
+ genASM // generate .class files
) ++ depAnalysisPhase
lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)
diff --git a/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala b/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala
deleted file mode 100644
index 4493685b52..0000000000
--- a/src/compiler/scala/tools/nsc/backend/MSILPlatform.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.tools.nsc
-package backend
-
-import ch.epfl.lamp.compiler.{ msil => msillib }
-import util.{ ClassPath, MsilClassPath }
-import msil.GenMSIL
-import io.{ AbstractFile, MsilFile }
-
-trait MSILPlatform extends Platform {
- import global._
- import definitions.{ ComparatorClass, BoxedNumberClass, getMember }
-
- type BinaryRepr = MsilFile
-
- if (settings.verbose.value)
- inform("[AssemRefs = " + settings.assemrefs.value + "]")
-
- // phaseName = "msil"
- object genMSIL extends {
- val global: MSILPlatform.this.global.type = MSILPlatform.this.global
- val runsAfter = List[String]("dce")
- val runsRightAfter = None
- } with GenMSIL
-
- lazy val classPath = MsilClassPath.fromSettings(settings)
- def rootLoader = new loaders.PackageLoader(classPath.asInstanceOf[ClassPath[platform.BinaryRepr]])
- // See discussion in JavaPlatForm for why we need a cast here.
-
- /** Update classpath with a substituted subentry */
- def updateClassPath(subst: Map[ClassPath[BinaryRepr], ClassPath[BinaryRepr]]) =
- throw new UnsupportedOperationException("classpath invalidations not supported on MSIL")
-
- def platformPhases = List(
- genMSIL // generate .msil files
- )
-
- lazy val externalEquals = getMember(ComparatorClass.companionModule, nme.equals_)
- def isMaybeBoxed(sym: Symbol) = sym isNonBottomSubClass BoxedNumberClass
-
- def newClassLoader(bin: MsilFile): loaders.SymbolLoader = new loaders.MsilFileLoader(bin)
-
- /**
- * Tells whether a class should be loaded and entered into the package
- * scope. On .NET, this method returns `false` for all synthetic classes
- * (anonymous classes, implementation classes, module classes), their
- * symtab is encoded in the pickle of another class.
- */
- def doLoad(cls: ClassPath[BinaryRepr]#ClassRep): Boolean = {
- if (cls.binary.isDefined) {
- val typ = cls.binary.get.msilType
- if (typ.IsDefined(loaders.clrTypes.SCALA_SYMTAB_ATTR, false)) {
- val attrs = typ.GetCustomAttributes(loaders.clrTypes.SCALA_SYMTAB_ATTR, false)
- assert(attrs.length == 1, attrs.length)
- val a = attrs(0).asInstanceOf[msillib.Attribute]
- // symtab_constr takes a byte array argument (the pickle), i.e. typ has a pickle.
- // otherwise, symtab_default_constr was used, which marks typ as scala-synthetic.
- a.getConstructor() == loaders.clrTypes.SYMTAB_CONSTR
- } else true // always load non-scala types
- } else true // always load source
- }
-
- def needCompile(bin: MsilFile, src: AbstractFile) =
- false // always use compiled file on .net
-}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
index 7c2961778f..a872e9cd00 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
@@ -27,9 +27,6 @@ trait ExceptionHandlers {
private var _startBlock: BasicBlock = _;
var finalizer: Finalizer = _;
- /** Needed for the MSIL backend. */
- var resultKind: TypeKind = _;
-
def setStartBlock(b: BasicBlock) = {
_startBlock = b;
b.exceptionHandlerStart = true
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index f07c331fb0..cc3562079e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -164,10 +164,7 @@ abstract class GenICode extends SubComponent {
private def genStat(tree: Tree, ctx: Context): Context = tree match {
case Assign(lhs @ Select(_, _), rhs) =>
val isStatic = lhs.symbol.isStaticMember
- var ctx1 = if (isStatic) ctx
- else if (forMSIL && msil_IsValuetypeInstField(lhs.symbol))
- msil_genLoadQualifierAddress(lhs, ctx)
- else genLoadQualifier(lhs, ctx)
+ var ctx1 = if (isStatic) ctx else genLoadQualifier(lhs, ctx)
ctx1 = genLoad(rhs, ctx1, toTypeKind(lhs.symbol.info))
ctx1.bb.emit(STORE_FIELD(lhs.symbol, isStatic), tree.pos)
@@ -301,9 +298,6 @@ abstract class GenICode extends SubComponent {
val Apply(fun, args) = tree
val monitor = ctx.makeLocal(tree.pos, ObjectClass.tpe, "monitor")
var monitorResult: Local = null
-
- // if the synchronized block returns a result, store it in a local variable. just leaving
- // it on the stack is not valid in MSIL (stack is cleaned when leaving try-blocks)
val argTpe = args.head.tpe
val hasResult = expectedType != UNIT
if (hasResult)
@@ -462,131 +456,6 @@ abstract class GenICode extends SubComponent {
}
/**
- * forMSIL
- */
- private def msil_IsValuetypeInstMethod(msym: Symbol) = (
- loaders.clrTypes.methods get msym exists (mMSIL =>
- mMSIL.IsInstance && mMSIL.DeclaringType.IsValueType
- )
- )
- private def msil_IsValuetypeInstField(fsym: Symbol) = (
- loaders.clrTypes.fields get fsym exists (fMSIL =>
- !fMSIL.IsStatic && fMSIL.DeclaringType.IsValueType
- )
- )
-
- /**
- * forMSIL: Adds a local var, the emitted code requires one more slot on the stack as on entry
- */
- private def msil_genLoadZeroOfNonEnumValuetype(ctx: Context, kind: TypeKind, pos: Position, leaveAddressOnStackInstead: Boolean) {
- val REFERENCE(clssym) = kind
- assert(loaders.clrTypes.isNonEnumValuetype(clssym), clssym)
- val local = ctx.makeLocal(pos, clssym.tpe, "tmp")
- ctx.method.addLocal(local)
- ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(local), pos)
- ctx.bb.emit(CIL_INITOBJ(kind), pos)
- val instr = if (leaveAddressOnStackInstead)
- CIL_LOAD_LOCAL_ADDRESS(local)
- else
- LOAD_LOCAL(local)
- ctx.bb.emit(instr, pos)
- }
-
- /**
- * forMSIL
- */
- private def msil_genLoadAddressOf(tree: Tree, ctx: Context, expectedType: TypeKind, butRawValueIsAlsoGoodEnough: Boolean): Context = {
- var generatedType = expectedType
- var addressTaken = false
- debuglog("at line: " + (if (tree.pos.isDefined) tree.pos.line else tree.pos))
-
- var resCtx: Context = tree match {
-
- // emits CIL_LOAD_FIELD_ADDRESS
- case Select(qualifier, selector) if (!tree.symbol.isModule) =>
- addressTaken = true
- val sym = tree.symbol
- generatedType = toTypeKind(sym.info)
-
- if (sym.isStaticMember) {
- ctx.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, true), tree.pos)
- ctx
- } else {
- val ctx1 = genLoadQualifier(tree, ctx)
- ctx1.bb.emit(CIL_LOAD_FIELD_ADDRESS(sym, false), tree.pos)
- ctx1
- }
-
- // emits CIL_LOAD_LOCAL_ADDRESS
- case Ident(name) if (!tree.symbol.isPackage && !tree.symbol.isModule)=>
- addressTaken = true
- val sym = tree.symbol
- try {
- val Some(l) = ctx.method.lookupLocal(sym)
- ctx.bb.emit(CIL_LOAD_LOCAL_ADDRESS(l), tree.pos)
- generatedType = l.kind // actually, should be "V&" but the callsite is aware of this
- } catch {
- case ex: MatchError =>
- abort("symbol " + sym + " does not exist in " + ctx.method)
- }
- ctx
-
- // emits CIL_LOAD_ARRAY_ITEM_ADDRESS
- case Apply(fun, args) =>
- if (isPrimitive(fun.symbol)) {
- val sym = tree.symbol
- val Select(receiver, _) = fun
- val code = scalaPrimitives.getPrimitive(sym, receiver.tpe)
-
- if (isArrayOp(code)) {
- val arrayObj = receiver
- val k = toTypeKind(arrayObj.tpe)
- val ARRAY(elementType) = k
- if (scalaPrimitives.isArrayGet(code)) {
- var ctx1 = genLoad(arrayObj, ctx, k)
- // load argument on stack
- debugassert(args.length == 1, "Too many arguments for array get operation: " + tree)
- ctx1 = genLoad(args.head, ctx1, INT)
- generatedType = elementType // actually "managed pointer to element type" but the callsite is aware of this
- ctx1.bb.emit(CIL_LOAD_ARRAY_ITEM_ADDRESS(elementType), tree.pos)
- addressTaken = true
- ctx1
- } else null
- } else null
- } else null
-
- case This(qual) =>
- /* TODO: this case handler is a placeholder for the time when Level 2 support for valuetypes is in place,
- in particular when invoking other methods on this where this is a valuetype value (boxed or not).
- As receiver, a managed pointer is expected, and a plain ldarg.0 achieves just that. */
- addressTaken = true
- genLoad(tree, ctx, expectedType)
-
- case _ =>
- null /* A method returning ByRef won't pass peverify, so I guess this case handler is dead code.
- Even if it's not, the code below to handler !addressTaken below. */
- }
-
- if (!addressTaken) {
- resCtx = genLoad(tree, ctx, expectedType)
- if (!butRawValueIsAlsoGoodEnough) {
- // raw value on stack (must be an intermediate result, e.g. returned by method call), take address
- addressTaken = true
- val boxType = expectedType // toTypeKind(expectedType /* TODO FIXME */)
- resCtx.bb.emit(BOX(boxType), tree.pos)
- resCtx.bb.emit(CIL_UNBOX(boxType), tree.pos)
- }
- }
-
- // emit conversion
- if (generatedType != expectedType)
- abort("Unexpected tree in msil_genLoadAddressOf: " + tree + " at: " + tree.pos)
-
- resCtx
- }
-
-
- /**
* Generate code for trees that produce values on the stack
*
* @param tree The tree to be translated
@@ -743,7 +612,8 @@ abstract class GenICode extends SubComponent {
} else
ctx1.bb.emit(CONSTANT(Constant(false)))
} else if (r.isValueType && cast) {
- assert(false, tree) /* Erasure should have added an unboxing operation to prevent that. */
+ /* Erasure should have added an unboxing operation to prevent that. */
+ abort("should have been unboxed by erasure: " + tree)
} else if (r.isValueType) {
ctx.bb.emit(IS_INSTANCE(REFERENCE(definitions.boxedClass(r.toType.typeSymbol))))
} else {
@@ -808,31 +678,15 @@ abstract class GenICode extends SubComponent {
debugassert(ctor.owner == cls,
"Symbol " + ctor.owner.fullName + " is different than " + tpt)
- val ctx2 = if (forMSIL && loaders.clrTypes.isNonEnumValuetype(cls)) {
- /* parameterful constructors are the only possible custom constructors,
- a default constructor can't be defined for valuetypes, CLR dixit */
- val isDefaultConstructor = args.isEmpty
- if (isDefaultConstructor) {
- msil_genLoadZeroOfNonEnumValuetype(ctx, rt, tree.pos, leaveAddressOnStackInstead = false)
- ctx
- } else {
- val ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx)
- ctx1.bb.emit(CIL_NEWOBJ(ctor), tree.pos)
- ctx1
- }
- } else {
- val nw = NEW(rt)
- ctx.bb.emit(nw, tree.pos)
- ctx.bb.emit(DUP(generatedType))
- val ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx)
-
- val init = CALL_METHOD(ctor, Static(true))
- nw.init = init
- ctx1.bb.emit(init, tree.pos)
- ctx1
- }
- ctx2
+ val nw = NEW(rt)
+ ctx.bb.emit(nw, tree.pos)
+ ctx.bb.emit(DUP(generatedType))
+ val ctx1 = genLoadArguments(args, ctor.info.paramTypes, ctx)
+ val init = CALL_METHOD(ctor, Static(true))
+ nw.init = init
+ ctx1.bb.emit(init, tree.pos)
+ ctx1
case _ =>
abort("Cannot instantiate " + tpt + " of kind: " + generatedType)
}
@@ -866,12 +720,6 @@ abstract class GenICode extends SubComponent {
ctx1.bb.emit(UNBOX(boxType), expr.pos)
ctx1
- case Apply(fun @ _, List(expr)) if (forMSIL && loaders.clrTypes.isAddressOf(fun.symbol)) =>
- debuglog("ADDRESSOF : " + fun.symbol.fullName);
- val ctx1 = msil_genLoadAddressOf(expr, ctx, toTypeKind(expr.tpe), butRawValueIsAlsoGoodEnough = false)
- generatedType = toTypeKind(fun.symbol.tpe.resultType)
- ctx1
-
case app @ Apply(fun, args) =>
def genLoadApply6 = {
val sym = fun.symbol
@@ -913,19 +761,12 @@ abstract class GenICode extends SubComponent {
else
Dynamic
- var ctx1 =
- if (invokeStyle.hasInstance) {
- if (forMSIL && !(invokeStyle.isInstanceOf[SuperCall]) && msil_IsValuetypeInstMethod(sym))
- msil_genLoadQualifierAddress(fun, ctx)
- else
- genLoadQualifier(fun, ctx)
- } else ctx
-
+ var ctx1 = if (invokeStyle.hasInstance) genLoadQualifier(fun, ctx) else ctx
ctx1 = genLoadArguments(args, sym.info.paramTypes, ctx1)
val cm = CALL_METHOD(sym, invokeStyle)
/** In a couple cases, squirrel away a little extra information in the
- * CALL_METHOD for use by GenJVM.
+ * CALL_METHOD for use by GenASM.
*/
fun match {
case Select(qual, _) =>
@@ -956,7 +797,6 @@ abstract class GenICode extends SubComponent {
genLoadApply6
case ApplyDynamic(qual, args) =>
- assert(!forMSIL, tree)
// TODO - this is where we'd catch dynamic applies for invokedynamic.
sys.error("No invokedynamic support yet.")
// val ctx1 = genLoad(qual, ctx, ObjectReference)
@@ -1189,15 +1029,6 @@ abstract class GenICode extends SubComponent {
abort("Unknown qualifier " + tree)
}
- /** forMSIL */
- private def msil_genLoadQualifierAddress(tree: Tree, ctx: Context): Context =
- tree match {
- case Select(qualifier, _) =>
- msil_genLoadAddressOf(qualifier, ctx, toTypeKind(qualifier.tpe), butRawValueIsAlsoGoodEnough = false)
- case _ =>
- abort("Unknown qualifier " + tree)
- }
-
/**
* Generate code that loads args into label parameters.
*/
@@ -1243,8 +1074,7 @@ abstract class GenICode extends SubComponent {
val sym = (
if (!tree.symbol.isPackageClass) tree.symbol
else tree.symbol.info.member(nme.PACKAGE) match {
- case NoSymbol =>
- abort("Cannot use package as value: " + tree)
+ case NoSymbol => abort("Cannot use package as value: " + tree)
case s =>
devWarning(s"Found ${tree.symbol} where a package object is required. Converting to ${s.moduleClass}")
s.moduleClass
@@ -1385,7 +1215,7 @@ abstract class GenICode extends SubComponent {
def genStringConcat(tree: Tree, ctx: Context): Context = {
liftStringConcat(tree) match {
// Optimization for expressions of the form "" + x. We can avoid the StringBuilder.
- case List(Literal(Constant("")), arg) if !forMSIL =>
+ case List(Literal(Constant("")), arg) =>
debuglog("Rewriting \"\" + x as String.valueOf(x) for: " + arg)
val ctx1 = genLoad(arg, ctx, ObjectReference)
ctx1.bb.emit(CALL_METHOD(String_valueOf, Static(false)), arg.pos)
@@ -1565,7 +1395,7 @@ abstract class GenICode extends SubComponent {
*/
def genEqEqPrimitive(l: Tree, r: Tree, ctx: Context)(thenCtx: Context, elseCtx: Context): Unit = {
def getTempLocal = ctx.method.lookupLocal(nme.EQEQ_LOCAL_VAR) getOrElse {
- ctx.makeLocal(l.pos, AnyRefClass.tpe, nme.EQEQ_LOCAL_VAR)
+ ctx.makeLocal(l.pos, AnyRefClass.tpe, nme.EQEQ_LOCAL_VAR.toString)
}
/** True if the equality comparison is between values that require the use of the rich equality
@@ -1988,10 +1818,9 @@ abstract class GenICode extends SubComponent {
* 'covered' by this exception handler (in addition to the
* previously active handlers).
*/
- private def newExceptionHandler(cls: Symbol, resultKind: TypeKind, pos: Position): ExceptionHandler = {
+ private def newExceptionHandler(cls: Symbol, pos: Position): ExceptionHandler = {
handlerCount += 1
val exh = new ExceptionHandler(method, newTermNameCached("" + handlerCount), cls, pos)
- exh.resultKind = resultKind
method.addHandler(exh)
handlers = exh :: handlers
debuglog("added handler: " + exh);
@@ -2051,7 +1880,7 @@ abstract class GenICode extends SubComponent {
def Try(body: Context => Context,
handlers: List[(Symbol, TypeKind, Context => Context)],
finalizer: Tree,
- tree: Tree) = if (forMSIL) TryMsil(body, handlers, finalizer, tree) else {
+ tree: Tree) = {
val outerCtx = this.dup // context for generating exception handlers, covered by finalizer
val finalizerCtx = this.dup // context for generating finalizer handler
@@ -2083,7 +1912,7 @@ abstract class GenICode extends SubComponent {
if (finalizer != EmptyTree) {
- val exh = outerCtx.newExceptionHandler(NoSymbol, toTypeKind(finalizer.tpe), finalizer.pos) // finalizer covers exception handlers
+ val exh = outerCtx.newExceptionHandler(NoSymbol, finalizer.pos) // finalizer covers exception handlers
this.addActiveHandler(exh) // .. and body aswell
val ctx = finalizerCtx.enterExceptionHandler(exh)
val exception = ctx.makeLocal(finalizer.pos, ThrowableClass.tpe, "exc")
@@ -2098,7 +1927,7 @@ abstract class GenICode extends SubComponent {
}
for ((sym, kind, handler) <- handlers) {
- val exh = this.newExceptionHandler(sym, kind, tree.pos)
+ val exh = this.newExceptionHandler(sym, tree.pos)
var ctx1 = outerCtx.enterExceptionHandler(exh)
ctx1.addFinalizer(finalizer, finalizerCtx)
loadException(ctx1, exh, tree.pos)
@@ -2122,67 +1951,6 @@ abstract class GenICode extends SubComponent {
afterCtx
}
-
-
- /** try-catch-finally blocks are actually simpler to emit in MSIL, because there
- * is support for `finally` in bytecode.
- *
- * A
- * try { .. } catch { .. } finally { .. }
- * block is de-sugared into
- * try { try { ..} catch { .. } } finally { .. }
- *
- * In ICode `finally` block is represented exactly the same as an exception handler,
- * but with `NoSymbol` as the exception class. The covered blocks are all blocks of
- * the `try { .. } catch { .. }`.
- *
- * Also, TryMsil does not enter any Finalizers into the `cleanups`, because the
- * CLI takes care of running the finalizer when seeing a `leave` statement inside
- * a try / catch.
- */
- def TryMsil(body: Context => Context,
- handlers: List[(Symbol, TypeKind, (Context => Context))],
- finalizer: Tree,
- tree: Tree) = {
-
- val outerCtx = this.dup // context for generating exception handlers, covered by finalizer
- val finalizerCtx = this.dup // context for generating finalizer handler
- val afterCtx = outerCtx.newBlock
-
- if (finalizer != EmptyTree) {
- // finalizer is covers try and all catch blocks, i.e.
- // try { try { .. } catch { ..} } finally { .. }
- val exh = outerCtx.newExceptionHandler(NoSymbol, UNIT, tree.pos)
- this.addActiveHandler(exh)
- val ctx = finalizerCtx.enterExceptionHandler(exh)
- loadException(ctx, exh, tree.pos)
- val ctx1 = genLoad(finalizer, ctx, UNIT)
- // need jump for the ICode to be valid. MSIL backend will emit `Endfinally` instead.
- ctx1.bb.closeWith(JUMP(afterCtx.bb))
- finalizerCtx.endHandler()
- }
-
- for (handler <- handlers) {
- val exh = this.newExceptionHandler(handler._1, handler._2, tree.pos)
- var ctx1 = outerCtx.enterExceptionHandler(exh)
- loadException(ctx1, exh, tree.pos)
- ctx1 = handler._3(ctx1)
- // msil backend will emit `Leave` to jump out of a handler
- ctx1.bb.closeWith(JUMP(afterCtx.bb))
- outerCtx.endHandler()
- }
-
- val bodyCtx = this.newBlock
-
- val finalCtx = body(bodyCtx)
-
- outerCtx.bb.closeWith(JUMP(bodyCtx.bb))
-
- // msil backend will emit `Leave` to jump out of a try-block
- finalCtx.bb.closeWith(JUMP(afterCtx.bb))
-
- afterCtx
- }
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
index b8a98955c9..80477f0c6e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
@@ -197,142 +197,4 @@ trait Linearizers {
def linearize(m: IMethod): List[BasicBlock] = m.blocks
def linearizeAt(m: IMethod, start: BasicBlock): List[BasicBlock] = sys.error("not implemented")
}
-
- /** The MSIL linearizer is used only for methods with at least one exception handler.
- * It makes sure that all the blocks belonging to a `try`, `catch` or `finally` block
- * are emitted in an order that allows the lexical nesting of try-catch-finally, just
- * like in the source code.
- */
- class MSILLinearizer extends Linearizer {
- /** The MSIL linearizer first calls a NormalLInearizer. This is because the ILGenerator checks
- * the stack size before emitting instructions. For instance, to emit a `store`, there needs
- * to be some value on the stack. This can blow up in situations like this:
- * ...
- * jump 3
- * 4: store_local 0
- * jump 5
- * 3: load_value
- * jump 4
- * 5: ...
- * here, 3 must be scheduled first.
- *
- * The NormalLinearizer also removes dead blocks (blocks without predecessor). This is important
- * in the following example:
- * try { throw new Exception }
- * catch { case e => throw e }
- * which adds a dead block containing just a "throw" (which, again, would blow up code generation
- * because of the stack size; there's no value on the stack when emitting that `throw`)
- */
- val normalLinearizer = new NormalLinearizer()
-
- def linearize(m: IMethod): List[BasicBlock] = {
-
- val handlersByCovered = m.exh.groupBy(_.covered)
-
- // number of basic blocks covered by the entire try-catch expression
- def size(covered: scala.collection.immutable.Set[BasicBlock]) = {
- val hs = handlersByCovered(covered)
- covered.size + (hs :\ 0)((h, s) => h.blocks.length + s)
- }
-
- val tryBlocks = handlersByCovered.keys.toList sortBy size
- var result = normalLinearizer.linearize(m)
- val frozen = mutable.HashSet[BasicBlock](result.head)
-
- for (tryBlock <- tryBlocks) {
- result = groupBlocks(m, result, handlersByCovered(tryBlock), frozen)
- }
- result
- }
-
- /** @param handlers a list of handlers covering the same blocks (same try, multiple catches)
- * @param frozen blocks can't be moved (fist block of a method, blocks directly following a try-catch)
- */
- def groupBlocks(method: IMethod, blocks: List[BasicBlock], handlers: List[ExceptionHandler], frozen: mutable.HashSet[BasicBlock]) = {
- assert(blocks.head == method.startBlock, method)
-
- // blocks before the try, and blocks for the try
- val beforeAndTry = new ListBuffer[BasicBlock]()
- // blocks for the handlers
- val catches = handlers map (_ => new ListBuffer[BasicBlock]())
- // blocks to be put at the end
- val after = new ListBuffer[BasicBlock]()
-
- var beforeTry = true
- val head = handlers.head
-
- for (b <- blocks) {
- if (head covers b) {
- beforeTry = false
- beforeAndTry += b
- } else {
- val handlerIndex = handlers.indexWhere(_.blocks.contains(b))
- if (handlerIndex >= 0) {
- catches(handlerIndex) += b
- } else if (beforeTry) {
- beforeAndTry += b
- } else {
- after += b
- }
- }
- }
-
- // reorder the blocks in "catches" so that the "firstBlock" is actually first
- (catches, handlers).zipped foreach { (lb, handler) =>
- lb -= handler.startBlock
- handler.startBlock +=: lb
- }
-
- // The first block emitted after a try-catch must be the one that the try / catch
- // blocks jump to (because in msil, these jumps cannot be emitted manually)
- var firstAfter: Option[BasicBlock] = None
-
- // Find the (hopefully) unique successor, look at the try and all catch blocks
- var blks = head.covered.toList :: handlers.map(_.blocks)
- while (firstAfter.isEmpty && !blks.isEmpty) {
- val b = blks.head
- blks = blks.tail
-
- val leaving = leavingBlocks(b)
- // no leaving blocks when the try or catch ends with THROW or RET
- if (!leaving.isEmpty) {
- assert(leaving.size <= 1, leaving)
- firstAfter = Some(leaving.head)
- }
- }
- if (firstAfter.isDefined) {
- val b = firstAfter.get
- if (frozen(b)) {
- assert(after contains b, b +", "+ method)
- } else {
- frozen += b
- if (beforeAndTry contains b) {
- beforeAndTry -= b
- } else {
- assert(after contains b, after)
- after -= b
- }
- b +=: after
- }
- }
-
- for (lb <- catches) { beforeAndTry ++= lb }
- beforeAndTry ++= after
- beforeAndTry.toList
- }
-
- /** Returns all direct successors of `blocks` wich are not part
- * that list, i.e. successors outside the `blocks` list.
- */
- private def leavingBlocks(blocks: List[BasicBlock]) = {
- val res = new mutable.HashSet[BasicBlock]()
- for (b <- blocks; s <- b.directSuccessors; if (!blocks.contains(s)))
- res += s
- res
- }
-
- def linearizeAt(m: IMethod, start: BasicBlock): List[BasicBlock] = {
- sys.error("not implemented")
- }
- }
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
index eaa742a1da..137e2b556f 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
@@ -734,74 +734,5 @@ trait Opcodes { self: ICodes =>
case class SuperCall(mix: Name) extends InvokeStyle {
override def toString(): String = { "super(" + mix + ")" }
}
-
-
- // CLR backend
-
- case class CIL_LOAD_LOCAL_ADDRESS(local: Local) extends Instruction {
- /** Returns a string representation of this instruction */
- override def toString(): String = "CIL_LOAD_LOCAL_ADDRESS "+local //+isArgument?" (argument)":"";
-
- override def consumed = 0
- override def produced = 1
-
- override def producedTypes = msil_mgdptr(local.kind) :: Nil
-
- override def category = localsCat
- }
-
- case class CIL_LOAD_FIELD_ADDRESS(field: Symbol, isStatic: Boolean) extends Instruction {
- /** Returns a string representation of this instruction */
- override def toString(): String =
- "CIL_LOAD_FIELD_ADDRESS " + (if (isStatic) field.fullName else field.toString)
-
- override def consumed = if (isStatic) 0 else 1
- override def produced = 1
-
- override def consumedTypes = if (isStatic) Nil else REFERENCE(field.owner) :: Nil;
- override def producedTypes = msil_mgdptr(REFERENCE(field.owner)) :: Nil;
-
- override def category = fldsCat
- }
-
- case class CIL_LOAD_ARRAY_ITEM_ADDRESS(kind: TypeKind) extends Instruction {
- /** Returns a string representation of this instruction */
- override def toString(): String = "CIL_LOAD_ARRAY_ITEM_ADDRESS (" + kind + ")"
-
- override def consumed = 2
- override def produced = 1
-
- override def consumedTypes = ARRAY(kind) :: INT :: Nil
- override def producedTypes = msil_mgdptr(kind) :: Nil
-
- override def category = arraysCat
- }
-
- case class CIL_UNBOX(valueType: TypeKind) extends Instruction {
- override def toString(): String = "CIL_UNBOX " + valueType
- override def consumed = 1
- override def consumedTypes = ObjectReferenceList // actually consumes a 'boxed valueType'
- override def produced = 1
- override def producedTypes = msil_mgdptr(valueType) :: Nil
- override def category = objsCat
- }
-
- case class CIL_INITOBJ(valueType: TypeKind) extends Instruction {
- override def toString(): String = "CIL_INITOBJ " + valueType
- override def consumed = 1
- override def consumedTypes = ObjectReferenceList // actually consumes a managed pointer
- override def produced = 0
- override def category = objsCat
- }
-
- case class CIL_NEWOBJ(method: Symbol) extends Instruction {
- override def toString(): String = "CIL_NEWOBJ " + hostClass.fullName + method.fullName
- val hostClass: Symbol = method.owner;
- override def consumed = method.tpe.paramTypes.length
- override def consumedTypes = method.tpe.paramTypes map toTypeKind
- override def produced = 1
- override def producedTypes = toTypeKind(method.tpe.resultType) :: Nil
- override def category = objsCat
- }
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 0990cfba6f..84f5fe2678 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -427,11 +427,4 @@ trait TypeKinds { self: ICodes =>
primitiveTypeMap.getOrElse(sym, newReference(sym))
private def primitiveOrClassType(sym: Symbol, targs: List[Type]) =
primitiveTypeMap.getOrElse(sym, arrayOrClassType(sym, targs))
-
- def msil_mgdptr(tk: TypeKind): TypeKind = (tk: @unchecked) match {
- case REFERENCE(cls) => REFERENCE(loaders.clrTypes.mdgptrcls4clssym(cls))
- // TODO have ready class-symbols for the by-ref versions of built-in valuetypes
- case _ => abort("cannot obtain a managed pointer for " + tk)
- }
-
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
index 8c8950d295..941ccd9a2d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
@@ -9,7 +9,7 @@ package backend.jvm
import java.io.{ DataOutputStream, FileOutputStream, OutputStream, File => JFile }
import scala.tools.nsc.io._
import scala.tools.nsc.util.ScalaClassLoader
-import scala.tools.util.JavapClass
+import scala.tools.util.{ Javap, JavapClass }
import java.util.jar.Attributes.Name
import scala.language.postfixOps
@@ -59,27 +59,32 @@ trait BytecodeWriters {
override def close() = writer.close()
}
+ /** To be mixed-in with the BytecodeWriter that generates
+ * the class file to be disassembled.
+ */
trait JavapBytecodeWriter extends BytecodeWriter {
val baseDir = Directory(settings.Ygenjavap.value).createDirectory()
-
- def emitJavap(bytes: Array[Byte], javapFile: io.File) {
- val pw = javapFile.printWriter()
- val javap = new JavapClass(ScalaClassLoader.appLoader, pw) {
- override def findBytes(path: String): Array[Byte] = bytes
- }
-
- try javap(Seq("-verbose", "dummy")) foreach (_.show())
- finally pw.close()
+ val cl = ScalaClassLoader.appLoader
+
+ def emitJavap(classFile: AbstractFile, javapFile: File) {
+ val pw = javapFile.printWriter()
+ try {
+ val javap = new JavapClass(cl, pw) {
+ override def findBytes(path: String): Array[Byte] = classFile.toByteArray
+ }
+ javap(Seq("-verbose", "-protected", classFile.name)) foreach (_.show())
+ } finally pw.close()
}
abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) {
super.writeClass(label, jclassName, jclassBytes, sym)
- val bytes = getFile(sym, jclassName, ".class").toByteArray
+ val classFile = getFile(sym, jclassName, ".class")
val segments = jclassName.split("[./]")
val javapFile = segments.foldLeft(baseDir: Path)(_ / _) changeExtension "javap" toFile;
-
javapFile.parent.createDirectory()
- emitJavap(bytes, javapFile)
+
+ if (Javap.isAvailable(cl)) emitJavap(classFile, javapFile)
+ else warning("No javap on classpath, skipping javap output.")
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 1aa80d5c5b..92d732ed04 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -18,7 +18,7 @@ import asm.Label
*
* Documentation at http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/2012Q2/GenASM.pdf
*/
-abstract class GenASM extends SubComponent with BytecodeWriters {
+abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
import global._
import icodes._
import icodes.opcodes._
@@ -50,61 +50,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// cause cycles before Global has finished initialization.
lazy val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
- def isJavaEntryPoint(icls: IClass) = {
- val sym = icls.symbol
- def fail(msg: String, pos: Position = sym.pos) = {
- icls.cunit.warning(sym.pos,
- sym.name + " has a main method with parameter type Array[String], but " + sym.fullName('.') + " will not be a runnable program.\n" +
- " Reason: " + msg
- // TODO: make this next claim true, if possible
- // by generating valid main methods as static in module classes
- // not sure what the jvm allows here
- // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
- )
- false
- }
- def failNoForwarder(msg: String) = {
- fail(msg + ", which means no static forwarder can be generated.\n")
- }
- val possibles = if (sym.hasModuleFlag) (sym.tpe nonPrivateMember nme.main).alternatives else Nil
- val hasApproximate = possibles exists { m =>
- m.info match {
- case MethodType(p :: Nil, _) => p.tpe.typeSymbol == ArrayClass
- case _ => false
- }
- }
- // At this point it's a module with a main-looking method, so either succeed or warn that it isn't.
- hasApproximate && {
- // Before erasure so we can identify generic mains.
- enteringErasure {
- val companion = sym.linkedClassOfClass
-
- if (hasJavaMainMethod(companion))
- failNoForwarder("companion contains its own main method")
- else if (companion.tpe.member(nme.main) != NoSymbol)
- // this is only because forwarders aren't smart enough yet
- failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
- else if (companion.isTrait)
- failNoForwarder("companion is a trait")
- // Now either succeeed, or issue some additional warnings for things which look like
- // attempts to be java main methods.
- else possibles exists { m =>
- m.info match {
- case PolyType(_, _) =>
- fail("main methods cannot be generic.")
- case MethodType(params, res) =>
- if (res.typeSymbol :: params exists (_.isAbstractType))
- fail("main methods cannot refer to type parameters or abstract types.", m.pos)
- else
- isJavaMainMethod(m) || fail("main method must have exact signature (Array[String])Unit", m.pos)
- case tp =>
- fail("don't know what this is: " + tp, m.pos)
- }
- }
- }
- }
- }
-
private def initBytecodeWriter(entryPoints: List[IClass]): BytecodeWriter = {
settings.outputDirs.getSingleOutput match {
case Some(f) if f hasExtension "jar" =>
@@ -126,13 +71,18 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
new DirectToJarfileWriter(f.file)
case _ =>
+ import scala.tools.util.Javap
if (settings.Ygenjavap.isDefault) {
if(settings.Ydumpclasses.isDefault)
new ClassBytecodeWriter { }
else
new ClassBytecodeWriter with DumpBytecodeWriter { }
}
- else new ClassBytecodeWriter with JavapBytecodeWriter { }
+ else if (Javap.isAvailable()) new ClassBytecodeWriter with JavapBytecodeWriter { }
+ else {
+ warning("No javap on classpath, skipping javap output.")
+ new ClassBytecodeWriter { }
+ }
// TODO A ScalapBytecodeWriter could take asm.util.Textifier as starting point.
// Three areas where javap ouput is less than ideal (e.g. when comparing versions of the same classfile) are:
@@ -154,7 +104,14 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
}
// For predictably ordered error messages.
- var sortedClasses = classes.values.toList sortBy ("" + _.symbol.fullName)
+ var sortedClasses = classes.values.toList sortBy (_.symbol.fullName)
+
+ // Warn when classes will overwrite one another on case-insensitive systems.
+ for ((_, v1 :: v2 :: _) <- sortedClasses groupBy (_.symbol.javaClassName.toString.toLowerCase)) {
+ v1.cunit.warning(v1.symbol.pos,
+ s"Class ${v1.symbol.javaClassName} differs only in case from ${v2.symbol.javaClassName}. " +
+ "Such classes will overwrite one another on case-insensitive filesystems.")
+ }
debuglog("Created new bytecode generator for " + classes.size + " classes.")
val bytecodeWriter = initBytecodeWriter(sortedClasses filter isJavaEntryPoint)
@@ -190,7 +147,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
/* don't javaNameCache.clear() because that causes the following tests to fail:
* test/files/run/macro-repl-dontexpand.scala
* test/files/jvm/interpreter.scala
- * TODO but why? what use could javaNameCache possibly see once GenJVM is over?
+ * TODO but why? what use could javaNameCache possibly see once GenASM is over?
*/
/* TODO After emitting all class files (e.g., in a separate compiler phase) ASM can perform bytecode verification:
@@ -888,10 +845,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// Run the signature parser to catch bogus signatures.
val isValidSignature = wrap {
// Alternative: scala.tools.reflect.SigParser (frontend to sun.reflect.generics.parser.SignatureParser)
- import scala.tools.asm.util.SignatureChecker
- if (sym.isMethod) { SignatureChecker checkMethodSignature sig } // requires asm-util.jar
- else if (sym.isTerm) { SignatureChecker checkFieldSignature sig }
- else { SignatureChecker checkClassSignature sig }
+ import scala.tools.asm.util.CheckClassAdapter
+ if (sym.isMethod) { CheckClassAdapter checkMethodSignature sig } // requires asm-util.jar
+ else if (sym.isTerm) { CheckClassAdapter checkFieldSignature sig }
+ else { CheckClassAdapter checkClassSignature sig }
}
if(!isValidSignature) {
@@ -1088,12 +1045,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
// a plain class lacking companion module, for details see `isCandidateForForwarders`).
// -----------------------------------------------------------------------------------------
- val ExcludedForwarderFlags = {
- import Flags._
- // Should include DEFERRED but this breaks findMember.
- ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags )
- }
-
/** Add a forwarder for method m. Used only from addForwarders(). */
private def addForwarder(isRemoteClass: Boolean, jclass: asm.ClassVisitor, module: Symbol, m: Symbol) {
val moduleName = javaName(module)
@@ -1198,7 +1149,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
/* Typestate: should be called before emitting fields (because it adds an IField to the current IClass). */
def addCreatorCode(block: BasicBlock) {
val fieldSymbol = (
- clasz.symbol.newValue(newTermName(androidFieldName), NoPosition, Flags.STATIC | Flags.FINAL)
+ clasz.symbol.newValue(androidFieldName, NoPosition, Flags.STATIC | Flags.FINAL)
setInfo AndroidCreatorClass.tpe
)
val methodSymbol = definitions.getMember(clasz.symbol.companionModule, androidFieldName)
@@ -1213,7 +1164,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
jclass.visitField(
PublicStaticFinal,
- androidFieldName,
+ androidFieldName.toString,
tdesc_creator,
null, // no java-generic-signature
null // no initial value
@@ -1233,7 +1184,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
clinit.visitMethodInsn(
asm.Opcodes.INVOKEVIRTUAL,
moduleName,
- androidFieldName,
+ androidFieldName.toString,
asm.Type.getMethodDescriptor(creatorType, Array.empty[asm.Type]: _*)
)
@@ -1241,7 +1192,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
clinit.visitFieldInsn(
asm.Opcodes.PUTSTATIC,
thisName,
- androidFieldName,
+ androidFieldName.toString,
tdesc_creator
)
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
deleted file mode 100644
index 72b7e35408..0000000000
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Stephane Micheloud
- */
-
-
-package scala.tools.nsc
-package backend.jvm
-
-import ch.epfl.lamp.fjbg._
-import symtab.Flags
-
-trait GenAndroid {
- self: GenJVM =>
-
- import global._
- import icodes._
- import opcodes._
-
- /** From the reference documentation of the Android SDK:
- * The `Parcelable` interface identifies classes whose instances can be
- * written to and restored from a `Parcel`. Classes implementing the
- * `Parcelable` interface must also have a static field called `CREATOR`,
- * which is an object implementing the `Parcelable.Creator` interface.
- */
- private val fieldName = newTermName("CREATOR")
-
- private lazy val AndroidParcelableInterface = rootMirror.getClassIfDefined("android.os.Parcelable")
- private lazy val AndroidCreatorClass = rootMirror.getClassIfDefined("android.os.Parcelable$Creator")
-
- def isAndroidParcelableClass(sym: Symbol) =
- (AndroidParcelableInterface != NoSymbol) &&
- (sym.parentSymbols contains AndroidParcelableInterface)
-
- def addCreatorCode(codegen: BytecodeGenerator, block: BasicBlock) {
- import codegen._
- val fieldSymbol = (
- clasz.symbol.newValue(newTermName(fieldName), NoPosition, Flags.STATIC | Flags.FINAL)
- setInfo AndroidCreatorClass.tpe
- )
- val methodSymbol = definitions.getMember(clasz.symbol.companionModule, fieldName)
- clasz addField new IField(fieldSymbol)
- block emit CALL_METHOD(methodSymbol, Static(false))
- block emit STORE_FIELD(fieldSymbol, true)
- }
-
- def legacyAddCreatorCode(codegen: BytecodeGenerator, clinit: JExtendedCode) {
- import codegen._
- val creatorType = javaType(AndroidCreatorClass)
- jclass.addNewField(PublicStaticFinal,
- fieldName,
- creatorType)
- val moduleName = javaName(clasz.symbol)+"$"
- clinit.emitGETSTATIC(moduleName,
- nme.MODULE_INSTANCE_FIELD.toString,
- new JObjectType(moduleName))
- clinit.emitINVOKEVIRTUAL(moduleName, fieldName,
- new JMethodType(creatorType, Array()))
- clinit.emitPUTSTATIC(jclass.getName(), fieldName, creatorType)
- }
-
-}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
deleted file mode 100644
index e1484d1f97..0000000000
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ /dev/null
@@ -1,1950 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Iulian Dragos
- */
-
-package scala.tools.nsc
-package backend.jvm
-
-import java.nio.ByteBuffer
-import scala.collection.{ mutable, immutable }
-import scala.reflect.internal.pickling.{ PickleFormat, PickleBuffer }
-import scala.tools.nsc.symtab._
-import scala.reflect.internal.util.{ SourceFile, NoSourceFile }
-import scala.reflect.internal.ClassfileConstants._
-import ch.epfl.lamp.fjbg._
-import JAccessFlags._
-import JObjectType.{ JAVA_LANG_STRING, JAVA_LANG_OBJECT }
-import scala.language.postfixOps
-
-/** This class ...
- *
- * @author Iulian Dragos
- * @version 1.0
- *
- */
-abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with BytecodeWriters {
- import global._
- import icodes._
- import icodes.opcodes._
- import definitions._
-
- val phaseName = "jvm"
-
- /** Create a new phase */
- override def newPhase(p: Phase): Phase = new JvmPhase(p)
-
- /** JVM code generation phase
- */
- class JvmPhase(prev: Phase) extends ICodePhase(prev) {
- def name = phaseName
- override def erasedTypes = true
- def apply(cls: IClass) = sys.error("no implementation")
-
- def isJavaEntryPoint(clasz: IClass) = {
- val sym = clasz.symbol
- def fail(msg: String, pos: Position = sym.pos) = {
- clasz.cunit.warning(sym.pos,
- sym.name + " has a main method with parameter type Array[String], but " + sym.fullName('.') + " will not be a runnable program.\n" +
- " Reason: " + msg
- // TODO: make this next claim true, if possible
- // by generating valid main methods as static in module classes
- // not sure what the jvm allows here
- // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
- )
- false
- }
- def failNoForwarder(msg: String) = {
- fail(msg + ", which means no static forwarder can be generated.\n")
- }
- val possibles = if (sym.hasModuleFlag) (sym.tpe nonPrivateMember nme.main).alternatives else Nil
- val hasApproximate = possibles exists { m =>
- m.info match {
- case MethodType(p :: Nil, _) => p.tpe.typeSymbol == ArrayClass
- case _ => false
- }
- }
- // At this point it's a module with a main-looking method, so either
- // succeed or warn that it isn't.
- hasApproximate && {
- // Before erasure so we can identify generic mains.
- enteringErasure {
- val companion = sym.linkedClassOfClass
-
- if (hasJavaMainMethod(companion))
- failNoForwarder("companion contains its own main method")
- else if (companion.tpe.member(nme.main) != NoSymbol)
- // this is only because forwarders aren't smart enough yet
- failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
- else if (companion.isTrait)
- failNoForwarder("companion is a trait")
- // Now either succeeed, or issue some additional warnings for things which look like
- // attempts to be java main methods.
- else possibles exists { m =>
- m.info match {
- case PolyType(_, _) =>
- fail("main methods cannot be generic.")
- case MethodType(params, res) =>
- if (res.typeSymbol :: params exists (_.isAbstractType))
- fail("main methods cannot refer to type parameters or abstract types.", m.pos)
- else
- isJavaMainMethod(m) || fail("main method must have exact signature (Array[String])Unit", m.pos)
- case tp =>
- fail("don't know what this is: " + tp, m.pos)
- }
- }
- }
- }
- }
-
- override def run() {
- // we reinstantiate the bytecode generator at each run, to allow the GC
- // to collect everything
- if (settings.debug.value)
- inform("[running phase " + name + " on icode]")
-
- if (settings.Xdce.value)
- for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym)) {
- log(s"Optimizer eliminated ${sym.fullNameString}")
- icodes.classes -= sym
- }
-
- // For predictably ordered error messages.
- val sortedClasses = classes.values.toList sortBy ("" + _.symbol.fullName)
- val entryPoints = sortedClasses filter isJavaEntryPoint
-
- val bytecodeWriter = settings.outputDirs.getSingleOutput match {
- case Some(f) if f hasExtension "jar" =>
- // If no main class was specified, see if there's only one
- // entry point among the classes going into the jar.
- if (settings.mainClass.isDefault) {
- entryPoints map (_.symbol fullName '.') match {
- case Nil =>
- log("No Main-Class designated or discovered.")
- case name :: Nil =>
- log("Unique entry point: setting Main-Class to " + name)
- settings.mainClass.value = name
- case names =>
- log("No Main-Class due to multiple entry points:\n " + names.mkString("\n "))
- }
- }
- else log("Main-Class was specified: " + settings.mainClass.value)
-
- new DirectToJarfileWriter(f.file)
-
- case _ =>
- if (settings.Ygenjavap.isDefault) {
- if(settings.Ydumpclasses.isDefault)
- new ClassBytecodeWriter { }
- else
- new ClassBytecodeWriter with DumpBytecodeWriter { }
- }
- else new ClassBytecodeWriter with JavapBytecodeWriter { }
- }
-
- val codeGenerator = new BytecodeGenerator(bytecodeWriter)
- debuglog("Created new bytecode generator for " + classes.size + " classes.")
-
- sortedClasses foreach { c =>
- try codeGenerator.genClass(c)
- catch {
- case e: JCode.CodeSizeTooBigException =>
- log("Skipped class %s because it has methods that are too long.".format(c))
- }
- }
-
- bytecodeWriter.close()
- classes.clear()
- }
- }
-
- var pickledBytes = 0 // statistics
-
- /**
- * Java bytecode generator.
- *
- */
- class BytecodeGenerator(bytecodeWriter: BytecodeWriter) extends BytecodeUtil {
- def this() = this(new ClassBytecodeWriter { })
- def debugLevel = settings.debuginfo.indexOfChoice
- import bytecodeWriter.writeClass
-
- val MIN_SWITCH_DENSITY = 0.7
- val INNER_CLASSES_FLAGS =
- (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_INTERFACE | ACC_ABSTRACT)
-
- val PublicStatic = ACC_PUBLIC | ACC_STATIC
- val PublicStaticFinal = ACC_PUBLIC | ACC_STATIC | ACC_FINAL
-
- val StringBuilderClassName = javaName(definitions.StringBuilderClass)
- val BoxesRunTime = "scala.runtime.BoxesRunTime"
-
- val StringBuilderType = new JObjectType(StringBuilderClassName) // TODO use ASMType.getObjectType
- val toStringType = new JMethodType(JAVA_LANG_STRING, JType.EMPTY_ARRAY) // TODO use ASMType.getMethodType
- val arrayCloneType = new JMethodType(JAVA_LANG_OBJECT, JType.EMPTY_ARRAY)
-
- // Scala attributes
- val BeanInfoAttr = rootMirror.getRequiredClass("scala.beans.BeanInfo")
-
- final val ExcludedForwarderFlags = {
- import Flags._
- // Should include DEFERRED but this breaks findMember.
- ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags )
- }
-
- // Additional interface parents based on annotations and other cues
- def newParentForAttr(attr: Symbol): Option[Symbol] = attr match {
- case CloneableAttr => Some(JavaCloneableClass)
- case RemoteAttr => Some(RemoteInterfaceClass)
- case _ => None
- }
-
- val versionPickle = {
- val vp = new PickleBuffer(new Array[Byte](16), -1, 0)
- assert(vp.writeIndex == 0, vp)
- vp writeNat PickleFormat.MajorVersion
- vp writeNat PickleFormat.MinorVersion
- vp writeNat 0
- vp
- }
-
- private def helperBoxTo(kind: ValueTypeKind): Tuple2[String, JMethodType] = {
- val boxedType = definitions.boxedClass(kind.toType.typeSymbol)
- val mtype = new JMethodType(javaType(boxedType), Array(javaType(kind)))
-
- Pair("boxTo" + boxedType.decodedName, mtype)
- }
-
- private val jBoxTo: Map[TypeKind, Tuple2[String, JMethodType]] = Map(
- BOOL -> helperBoxTo(BOOL) ,
- BYTE -> helperBoxTo(BYTE) ,
- CHAR -> helperBoxTo(CHAR) ,
- SHORT -> helperBoxTo(SHORT) ,
- INT -> helperBoxTo(INT) ,
- LONG -> helperBoxTo(LONG) ,
- FLOAT -> helperBoxTo(FLOAT) ,
- DOUBLE -> helperBoxTo(DOUBLE)
- )
-
- private def helperUnboxTo(kind: ValueTypeKind): Tuple2[String, JMethodType] = {
- val mtype = new JMethodType(javaType(kind), Array(JAVA_LANG_OBJECT))
- val mname = "unboxTo" + kind.toType.typeSymbol.decodedName
-
- Pair(mname, mtype)
- }
-
- private val jUnboxTo: Map[TypeKind, Tuple2[String, JMethodType]] = Map(
- BOOL -> helperUnboxTo(BOOL) ,
- BYTE -> helperUnboxTo(BYTE) ,
- CHAR -> helperUnboxTo(CHAR) ,
- SHORT -> helperUnboxTo(SHORT) ,
- INT -> helperUnboxTo(INT) ,
- LONG -> helperUnboxTo(LONG) ,
- FLOAT -> helperUnboxTo(FLOAT) ,
- DOUBLE -> helperUnboxTo(DOUBLE)
- )
-
- var clasz: IClass = _
- var method: IMethod = _
- var jclass: JClass = _
- var jmethod: JMethod = _
-
- def isParcelableClass = isAndroidParcelableClass(clasz.symbol)
- def isRemoteClass = clasz.symbol hasAnnotation RemoteAttr
- def serialVUID = clasz.symbol getAnnotation SerialVersionUIDAttr collect {
- case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
- }
-
- val fjbgContext = new FJBGContext(49, 0)
- val emitVars = debugLevel >= 3
-
- // bug had phase with wrong name; leaving enabled for brief pseudo deprecation
- private val checkSignatures = (
- (settings.check containsName phaseName)
- || (settings.check.value contains "genjvm") && {
- global.warning("This option will be removed: please use -Ycheck:%s, not -Ycheck:genjvm." format phaseName)
- true
- }
- )
-
- /** For given symbol return a symbol corresponding to a class that should be declared as inner class.
- *
- * For example:
- * class A {
- * class B
- * object C
- * }
- *
- * then method will return NoSymbol for A, the same symbol for A.B (corresponding to A$B class) and A$C$ symbol
- * for A.C.
- */
- private def innerClassSymbolFor(s: Symbol): Symbol =
- if (s.isClass) s else if (s.isModule) s.moduleClass else NoSymbol
-
- override def javaName(sym: Symbol): String = { // TODO Miguel says: check whether a single pass over `icodes.classes` can populate `innerClassBuffer` faster.
- /**
- * Checks if given symbol corresponds to inner class/object and add it to innerClassBuffer
- *
- * Note: This method is called recursively thus making sure that we add complete chain
- * of inner class all until root class.
- */
- def collectInnerClass(s: Symbol): Unit = {
- // TODO: some enteringFlatten { ... } which accounts for
- // being nested in parameterized classes (if we're going to selectively flatten.)
- val x = innerClassSymbolFor(s)
- if(x ne NoSymbol) {
- assert(x.isClass, "not an inner-class symbol")
- val isInner = !x.rawowner.isPackageClass
- if (isInner) {
- innerClassBuffer += x
- collectInnerClass(x.rawowner)
- }
- }
- }
- collectInnerClass(sym)
-
- super.javaName(sym)
- }
-
- /** Write a class to disk, adding the Scala signature (pickled type
- * information) and inner classes.
- *
- * @param jclass The FJBG class, where code was emitted
- * @param sym The corresponding symbol, used for looking up pickled information
- */
- def emitClass(jclass: JClass, sym: Symbol) {
- addInnerClasses(jclass)
- writeClass("" + sym.name, jclass.getName(), toByteArray(jclass), sym)
- }
-
- /** Returns the ScalaSignature annotation if it must be added to this class,
- * none otherwise; furthermore, it adds to `jclass` the ScalaSig marker
- * attribute (marking that a scala signature annotation is present) or the
- * Scala marker attribute (marking that the signature for this class is in
- * another file). The annotation that is returned by this method must be
- * added to the class' annotations list when generating them.
- *
- * @param jclass The class file that is being readied.
- * @param sym The symbol for which the signature has been entered in
- * the symData map. This is different than the symbol
- * that is being generated in the case of a mirror class.
- * @return An option that is:
- * - defined and contains an annotation info of the
- * ScalaSignature type, instantiated with the pickle
- * signature for sym (a ScalaSig marker attribute has
- * been written);
- * - undefined if the jclass/sym couple must not contain a
- * signature (a Scala marker attribute has been written).
- */
- def scalaSignatureAddingMarker(jclass: JClass, sym: Symbol): Option[AnnotationInfo] =
- currentRun.symData get sym match {
- case Some(pickle) if !nme.isModuleName(newTermName(jclass.getName)) =>
- val scalaAttr =
- fjbgContext.JOtherAttribute(jclass, jclass, tpnme.ScalaSignatureATTR.toString,
- versionPickle.bytes, versionPickle.writeIndex)
- jclass addAttribute scalaAttr
- val scalaAnnot = {
- val sigBytes = ScalaSigBytes(pickle.bytes.take(pickle.writeIndex))
- AnnotationInfo(sigBytes.sigAnnot, Nil, List((nme.bytes, sigBytes)))
- }
- pickledBytes += pickle.writeIndex
- currentRun.symData -= sym
- currentRun.symData -= sym.companionSymbol
- Some(scalaAnnot)
- case _ =>
- val markerAttr =
- fjbgContext.JOtherAttribute(jclass, jclass, tpnme.ScalaATTR.toString, new Array[Byte](0), 0)
- jclass addAttribute markerAttr
- None
- }
-
- private var innerClassBuffer = mutable.LinkedHashSet[Symbol]()
-
- /** Drop redundant interfaces (ones which are implemented by some other parent) from the immediate parents.
- * This is important on Android because there is otherwise an interface explosion.
- */
- private def minimizeInterfaces(interfaces: List[Symbol]): List[Symbol] = {
- var rest = interfaces
- var leaves = List.empty[Symbol]
- while(!rest.isEmpty) {
- val candidate = rest.head
- val nonLeaf = leaves exists { lsym => lsym isSubClass candidate }
- if(!nonLeaf) {
- leaves = candidate :: (leaves filterNot { lsym => candidate isSubClass lsym })
- }
- rest = rest.tail
- }
-
- leaves
- }
-
- def genClass(c: IClass) {
- clasz = c
- innerClassBuffer.clear()
-
- val name = javaName(c.symbol)
-
- val ps = c.symbol.info.parents
-
- val superClass: Symbol = if(ps.isEmpty) ObjectClass else ps.head.typeSymbol;
-
- val superInterfaces0: List[Symbol] = if(ps.isEmpty) Nil else c.symbol.mixinClasses;
- val superInterfaces = superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol)) distinct
-
- val ifaces =
- if(superInterfaces.isEmpty) JClass.NO_INTERFACES
- else mkArray(minimizeInterfaces(superInterfaces) map javaName)
-
- jclass = fjbgContext.JClass(javaFlags(c.symbol),
- name,
- javaName(superClass),
- ifaces,
- c.cunit.source.toString)
-
- if (isStaticModule(c.symbol) || serialVUID != None || isParcelableClass) {
- if (isStaticModule(c.symbol))
- addModuleInstanceField
- addStaticInit(jclass, c.lookupStaticCtor)
-
- if (isTopLevelModule(c.symbol)) {
- if (c.symbol.companionClass == NoSymbol)
- generateMirrorClass(c.symbol, c.cunit.source)
- else
- log("No mirror class for module with linked class: " +
- c.symbol.fullName)
- }
- }
- else {
- c.lookupStaticCtor foreach (constructor => addStaticInit(jclass, Some(constructor)))
-
- // it must be a top level class (name contains no $s)
- def isCandidateForForwarders(sym: Symbol): Boolean =
- exitingPickler {
- !(sym.name.toString contains '$') && sym.hasModuleFlag && !sym.isImplClass && !sym.isNestedClass
- }
-
- // At some point this started throwing lots of exceptions as a compile was finishing.
- // error: java.lang.AssertionError:
- // assertion failed: List(object package$CompositeThrowable, object package$CompositeThrowable)
- // ...is the one I've seen repeatedly. Suppressing.
- val lmoc = (
- try c.symbol.companionModule
- catch { case x: AssertionError =>
- Console.println("Suppressing failed assert: " + x)
- NoSymbol
- }
- )
- // add static forwarders if there are no name conflicts; see bugs #363 and #1735
- if (lmoc != NoSymbol && !c.symbol.isInterface) {
- if (isCandidateForForwarders(lmoc) && !settings.noForwarders.value) {
- log("Adding static forwarders from '%s' to implementations in '%s'".format(c.symbol, lmoc))
- addForwarders(jclass, lmoc.moduleClass)
- }
- }
- }
-
- clasz.fields foreach genField
- clasz.methods foreach genMethod
-
- val ssa = scalaSignatureAddingMarker(jclass, c.symbol)
- addGenericSignature(jclass, c.symbol, c.symbol.owner)
- addAnnotations(jclass, c.symbol.annotations ++ ssa)
- addEnclosingMethodAttribute(jclass, c.symbol)
- emitClass(jclass, c.symbol)
-
- if (c.symbol hasAnnotation BeanInfoAttr)
- genBeanInfoClass(c)
- }
-
- private def addEnclosingMethodAttribute(jclass: JClass, clazz: Symbol) {
- val sym = clazz.originalEnclosingMethod
- if (sym.isMethod) {
- debuglog("enclosing method for %s is %s (in %s)".format(clazz, sym, sym.enclClass))
- jclass addAttribute fjbgContext.JEnclosingMethodAttribute(
- jclass,
- javaName(sym.enclClass),
- javaName(sym),
- javaType(sym)
- )
- } else if (clazz.isAnonymousClass) {
- val enclClass = clazz.rawowner
- assert(enclClass.isClass, enclClass)
- val sym = enclClass.primaryConstructor
- if (sym == NoSymbol)
- log("Ran out of room looking for an enclosing method for %s: no constructor here.".format(
- enclClass, clazz)
- )
- else {
- debuglog("enclosing method for %s is %s (in %s)".format(clazz, sym, enclClass))
- jclass addAttribute fjbgContext.JEnclosingMethodAttribute(
- jclass,
- javaName(enclClass),
- javaName(sym),
- javaType(sym).asInstanceOf[JMethodType]
- )
- }
- }
- }
-
- private def toByteArray(jc: JClass): Array[Byte] = {
- val bos = new java.io.ByteArrayOutputStream()
- val dos = new java.io.DataOutputStream(bos)
- jc.writeTo(dos)
- dos.close()
- bos.toByteArray
- }
-
- /**
- * Generate a bean info class that describes the given class.
- *
- * @author Ross Judson (ross.judson@soletta.com)
- */
- def genBeanInfoClass(c: IClass) {
- val beanInfoClass = fjbgContext.JClass(javaFlags(c.symbol),
- javaName(c.symbol) + "BeanInfo",
- "scala/beans/ScalaBeanInfo",
- JClass.NO_INTERFACES,
- c.cunit.source.toString)
-
- var fieldList = List[String]()
- for (f <- clasz.fields if f.symbol.hasGetter;
- g = f.symbol.getter(c.symbol);
- s = f.symbol.setter(c.symbol);
- if g.isPublic && !(f.symbol.name startsWith "$")) // inserting $outer breaks the bean
- fieldList = javaName(f.symbol) :: javaName(g) :: (if (s != NoSymbol) javaName(s) else null) :: fieldList
- val methodList =
- for (m <- clasz.methods
- if !m.symbol.isConstructor &&
- m.symbol.isPublic &&
- !(m.symbol.name startsWith "$") &&
- !m.symbol.isGetter &&
- !m.symbol.isSetter) yield javaName(m.symbol)
-
- val constructor = beanInfoClass.addNewMethod(ACC_PUBLIC, "<init>", JType.VOID, new Array[JType](0), new Array[String](0))
- val jcode = constructor.getCode().asInstanceOf[JExtendedCode]
- val strKind = new JObjectType(javaName(StringClass))
- val stringArrayKind = new JArrayType(strKind)
- val conType = new JMethodType(JType.VOID, Array(javaType(ClassClass), stringArrayKind, stringArrayKind))
-
- def push(lst:Seq[String]) {
- var fi = 0
- for (f <- lst) {
- jcode.emitDUP()
- jcode emitPUSH fi
- if (f != null)
- jcode emitPUSH f
- else
- jcode.emitACONST_NULL()
- jcode emitASTORE strKind
- fi += 1
- }
- }
-
- jcode.emitALOAD_0()
- // push the class
- jcode emitPUSH javaType(c.symbol).asInstanceOf[JReferenceType]
-
- // push the string array of field information
- jcode emitPUSH fieldList.length
- jcode emitANEWARRAY strKind
- push(fieldList)
-
- // push the string array of method information
- jcode emitPUSH methodList.length
- jcode emitANEWARRAY strKind
- push(methodList)
-
- // invoke the superclass constructor, which will do the
- // necessary java reflection and create Method objects.
- jcode.emitINVOKESPECIAL("scala/beans/ScalaBeanInfo", "<init>", conType)
- jcode.emitRETURN()
-
- // write the bean information class file.
- writeClass("BeanInfo ", beanInfoClass.getName(), toByteArray(beanInfoClass), c.symbol)
- }
-
- /** Add the given 'throws' attributes to jmethod */
- def addExceptionsAttribute(jmethod: JMethod, excs: List[AnnotationInfo]) {
- if (excs.isEmpty) return
-
- val cpool = jmethod.getConstantPool
- val buf: ByteBuffer = ByteBuffer.allocate(512)
- var nattr = 0
-
- // put some random value; the actual number is determined at the end
- buf putShort 0xbaba.toShort
-
- for (ThrownException(exc) <- excs.distinct) {
- buf.putShort(
- cpool.addClass(
- javaName(exc)).shortValue)
- nattr += 1
- }
-
- assert(nattr > 0, nattr)
- buf.putShort(0, nattr.toShort)
- addAttribute(jmethod, tpnme.ExceptionsATTR, buf)
- }
-
- /** Whether an annotation should be emitted as a Java annotation
- * .initialize: if 'annot' is read from pickle, atp might be un-initialized
- */
- private def shouldEmitAnnotation(annot: AnnotationInfo) =
- annot.symbol.initialize.isJavaDefined &&
- annot.matches(ClassfileAnnotationClass) &&
- annot.args.isEmpty
-
- private def emitJavaAnnotations(cpool: JConstantPool, buf: ByteBuffer, annotations: List[AnnotationInfo]): Int = {
- def emitArgument(arg: ClassfileAnnotArg): Unit = arg match {
- case LiteralAnnotArg(const) =>
- const.tag match {
- case BooleanTag =>
- buf put 'Z'.toByte
- buf putShort cpool.addInteger(if(const.booleanValue) 1 else 0).toShort
- case ByteTag =>
- buf put 'B'.toByte
- buf putShort cpool.addInteger(const.byteValue).toShort
- case ShortTag =>
- buf put 'S'.toByte
- buf putShort cpool.addInteger(const.shortValue).toShort
- case CharTag =>
- buf put 'C'.toByte
- buf putShort cpool.addInteger(const.charValue).toShort
- case IntTag =>
- buf put 'I'.toByte
- buf putShort cpool.addInteger(const.intValue).toShort
- case LongTag =>
- buf put 'J'.toByte
- buf putShort cpool.addLong(const.longValue).toShort
- case FloatTag =>
- buf put 'F'.toByte
- buf putShort cpool.addFloat(const.floatValue).toShort
- case DoubleTag =>
- buf put 'D'.toByte
- buf putShort cpool.addDouble(const.doubleValue).toShort
- case StringTag =>
- buf put 's'.toByte
- buf putShort cpool.addUtf8(const.stringValue).toShort
- case ClazzTag =>
- buf put 'c'.toByte
- buf putShort cpool.addUtf8(javaType(const.typeValue).getSignature()).toShort
- case EnumTag =>
- buf put 'e'.toByte
- buf putShort cpool.addUtf8(javaType(const.tpe).getSignature()).toShort
- buf putShort cpool.addUtf8(const.symbolValue.name.toString).toShort
- }
-
- case sb@ScalaSigBytes(bytes) if !sb.isLong =>
- buf put 's'.toByte
- buf putShort cpool.addUtf8(sb.encodedBytes).toShort
-
- case sb@ScalaSigBytes(bytes) if sb.isLong =>
- buf put '['.toByte
- val stringCount = (sb.encodedBytes.length / 65534) + 1
- buf putShort stringCount.toShort
- for (i <- 0 until stringCount) {
- buf put 's'.toByte
- val j = i * 65535
- val string = sb.encodedBytes.slice(j, j + 65535)
- buf putShort cpool.addUtf8(string).toShort
- }
-
- case ArrayAnnotArg(args) =>
- buf put '['.toByte
- buf putShort args.length.toShort
- args foreach emitArgument
-
- case NestedAnnotArg(annInfo) =>
- buf put '@'.toByte
- emitAnnotation(annInfo)
- }
-
- def emitAnnotation(annotInfo: AnnotationInfo) {
- val AnnotationInfo(typ, args, assocs) = annotInfo
- val jtype = javaType(typ)
- buf putShort cpool.addUtf8(jtype.getSignature()).toShort
- assert(args.isEmpty, args)
- buf putShort assocs.length.toShort
- for ((name, value) <- assocs) {
- buf putShort cpool.addUtf8(name.toString).toShort
- emitArgument(value)
- }
- }
-
- var nannots = 0
- val pos = buf.position()
-
- // put some random value; the actual number of annotations is determined at the end
- buf putShort 0xbaba.toShort
-
- for (annot <- annotations if shouldEmitAnnotation(annot)) {
- nannots += 1
- emitAnnotation(annot)
- }
-
- // save the number of annotations
- buf.putShort(pos, nannots.toShort)
- nannots
- }
-
- // @M don't generate java generics sigs for (members of) implementation
- // classes, as they are monomorphic (TODO: ok?)
- private def needsGenericSignature(sym: Symbol) = !(
- // PP: This condition used to include sym.hasExpandedName, but this leads
- // to the total loss of generic information if a private member is
- // accessed from a closure: both the field and the accessor were generated
- // without it. This is particularly bad because the availability of
- // generic information could disappear as a consequence of a seemingly
- // unrelated change.
- settings.Ynogenericsig.value
- || sym.isArtifact
- || sym.isLiftedMethod
- || sym.isBridge
- || (sym.ownerChain exists (_.isImplClass))
- )
- def addGenericSignature(jmember: JMember, sym: Symbol, owner: Symbol) {
- if (needsGenericSignature(sym)) {
- val memberTpe = enteringErasure(owner.thisType.memberInfo(sym))
-
- erasure.javaSig(sym, memberTpe) foreach { sig =>
- // This seems useful enough in the general case.
- log(sig)
- if (checkSignatures) {
- val normalizedTpe = enteringErasure(erasure.prepareSigMap(memberTpe))
- val bytecodeTpe = owner.thisType.memberInfo(sym)
- if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) {
- clasz.cunit.warning(sym.pos,
- """|compiler bug: created generic signature for %s in %s that does not conform to its erasure
- |signature: %s
- |original type: %s
- |normalized type: %s
- |erasure type: %s
- |if this is reproducible, please report bug at https://issues.scala-lang.org/
- """.trim.stripMargin.format(sym, sym.owner.skipPackageObject.fullName, sig, memberTpe, normalizedTpe, bytecodeTpe))
- return
- }
- }
- val index = jmember.getConstantPool.addUtf8(sig).toShort
- if (settings.verbose.value && settings.debug.value)
- enteringErasure(println("add generic sig "+sym+":"+sym.info+" ==> "+sig+" @ "+index))
-
- val buf = ByteBuffer.allocate(2)
- buf putShort index
- addAttribute(jmember, tpnme.SignatureATTR, buf)
- }
- }
- }
-
- def addAnnotations(jmember: JMember, annotations: List[AnnotationInfo]) {
- if (annotations exists (_ matches definitions.DeprecatedAttr)) {
- val attr = jmember.getContext().JOtherAttribute(
- jmember.getJClass(), jmember, tpnme.DeprecatedATTR.toString,
- new Array[Byte](0), 0)
- jmember addAttribute attr
- }
-
- val toEmit = annotations filter shouldEmitAnnotation
- if (toEmit.isEmpty) return
-
- val buf: ByteBuffer = ByteBuffer.allocate(2048)
- emitJavaAnnotations(jmember.getConstantPool, buf, toEmit)
- addAttribute(jmember, tpnme.RuntimeAnnotationATTR, buf)
- }
-
- def addParamAnnotations(jmethod: JMethod, pannotss: List[List[AnnotationInfo]]) {
- val annotations = pannotss map (_ filter shouldEmitAnnotation)
- if (annotations forall (_.isEmpty)) return
-
- val buf: ByteBuffer = ByteBuffer.allocate(2048)
-
- // number of parameters
- buf.put(annotations.length.toByte)
- for (annots <- annotations)
- emitJavaAnnotations(jmethod.getConstantPool, buf, annots)
-
- addAttribute(jmethod, tpnme.RuntimeParamAnnotationATTR, buf)
- }
-
- def addAttribute(jmember: JMember, name: Name, buf: ByteBuffer) {
- if (buf.position() < 2)
- return
-
- val length = buf.position()
- val arr = buf.array().slice(0, length)
-
- val attr = jmember.getContext().JOtherAttribute(jmember.getJClass(),
- jmember,
- name.toString,
- arr,
- length)
- jmember addAttribute attr
- }
-
- def addInnerClasses(jclass: JClass) {
- /** The outer name for this inner class. Note that it returns null
- * when the inner class should not get an index in the constant pool.
- * That means non-member classes (anonymous). See Section 4.7.5 in the JVMS.
- */
- def outerName(innerSym: Symbol): String = {
- if (innerSym.originalEnclosingMethod != NoSymbol)
- null
- else {
- val outerName = javaName(innerSym.rawowner)
- if (isTopLevelModule(innerSym.rawowner)) "" + nme.stripModuleSuffix(newTermName(outerName))
- else outerName
- }
- }
-
- def innerName(innerSym: Symbol): String =
- if (innerSym.isAnonymousClass || innerSym.isAnonymousFunction)
- null
- else
- innerSym.rawname + innerSym.moduleSuffix
-
- // add inner classes which might not have been referenced yet
- exitingErasure {
- for (sym <- List(clasz.symbol, clasz.symbol.linkedClassOfClass); m <- sym.info.decls.map(innerClassSymbolFor) if m.isClass)
- innerClassBuffer += m
- }
-
- val allInners = innerClassBuffer.toList
- if (allInners.nonEmpty) {
- debuglog(clasz.symbol.fullName('.') + " contains " + allInners.size + " inner classes.")
- val innerClassesAttr = jclass.getInnerClasses()
- // sort them so inner classes succeed their enclosing class
- // to satisfy the Eclipse Java compiler
- for (innerSym <- allInners sortBy (_.name.length)) {
- val flags = {
- val staticFlag = if (innerSym.rawowner.hasModuleFlag) ACC_STATIC else 0
- (javaFlags(innerSym) | staticFlag) & INNER_CLASSES_FLAGS
- }
- val jname = javaName(innerSym)
- val oname = outerName(innerSym)
- val iname = innerName(innerSym)
-
- // Mimicking javap inner class output
- debuglog(
- if (oname == null || iname == null) "//class " + jname
- else "//%s=class %s of class %s".format(iname, jname, oname)
- )
-
- innerClassesAttr.addEntry(jname, oname, iname, flags)
- }
- }
- }
-
- def genField(f: IField) {
- debuglog("Adding field: " + f.symbol.fullName)
-
- val jfield = jclass.addNewField(
- javaFieldFlags(f.symbol),
- javaName(f.symbol),
- javaType(f.symbol.tpe)
- )
-
- addGenericSignature(jfield, f.symbol, clasz.symbol)
- addAnnotations(jfield, f.symbol.annotations)
- }
-
- def genMethod(m: IMethod) {
- if (m.symbol.isStaticConstructor || definitions.isGetClass(m.symbol)) return
-
- debuglog("Generating method " + m.symbol.fullName)
- method = m
- endPC.clear
- computeLocalVarsIndex(m)
-
- var resTpe = javaType(m.symbol.tpe.resultType)
- if (m.symbol.isClassConstructor)
- resTpe = JType.VOID
-
- var flags = javaFlags(m.symbol)
- if (jclass.isInterface)
- flags |= ACC_ABSTRACT
-
- if (m.symbol.isStrictFP)
- flags |= ACC_STRICT
-
- // native methods of objects are generated in mirror classes
- if (method.native)
- flags |= ACC_NATIVE
-
- jmethod = jclass.addNewMethod(flags,
- javaName(m.symbol),
- resTpe,
- mkArray(m.params map (p => javaType(p.kind))),
- mkArray(m.params map (p => javaName(p.sym))))
-
- addRemoteException(jmethod, m.symbol)
-
- if (!jmethod.isAbstract() && !method.native) {
- val jcode = jmethod.getCode().asInstanceOf[JExtendedCode]
-
- // add a fake local for debugging purposes
- if (emitVars && isClosureApply(method.symbol)) {
- val outerField = clasz.symbol.info.decl(nme.OUTER_LOCAL)
- if (outerField != NoSymbol) {
- log("Adding fake local to represent outer 'this' for closure " + clasz)
- val _this = new Local(
- method.symbol.newVariable(nme.FAKE_LOCAL_THIS), toTypeKind(outerField.tpe), false)
- m.locals = m.locals ::: List(_this)
- computeLocalVarsIndex(m) // since we added a new local, we need to recompute indexes
-
- jcode.emitALOAD_0()
- jcode.emitGETFIELD(javaName(clasz.symbol),
- javaName(outerField),
- javaType(outerField))
- jcode.emitSTORE(indexOf(_this), javaType(_this.kind))
- }
- }
-
- for (local <- m.locals if ! m.params.contains(local)) {
- debuglog("add local var: " + local)
- jmethod.addNewLocalVariable(javaType(local.kind), javaName(local.sym))
- }
-
- genCode(m)
- if (emitVars)
- genLocalVariableTable(m, jcode)
- }
-
- addGenericSignature(jmethod, m.symbol, clasz.symbol)
- val (excs, others) = m.symbol.annotations partition (_.symbol == ThrowsClass)
- addExceptionsAttribute(jmethod, excs)
- addAnnotations(jmethod, others)
- addParamAnnotations(jmethod, m.params.map(_.sym.annotations))
-
- // check for code size
- try jmethod.freeze()
- catch {
- case e: JCode.CodeSizeTooBigException =>
- clasz.cunit.error(m.symbol.pos, "Code size exceeds JVM limits: %d".format(e.codeSize))
- throw e
- }
- }
-
- /** Adds a @remote annotation, actual use unknown.
- */
- private def addRemoteException(jmethod: JMethod, meth: Symbol) {
- val needsAnnotation = (
- (isRemoteClass || (meth hasAnnotation RemoteAttr) && jmethod.isPublic)
- && !(meth.throwsAnnotations contains RemoteExceptionClass)
- )
- if (needsAnnotation) {
- val c = Constant(RemoteExceptionClass.tpe)
- val arg = Literal(c) setType c.tpe
- meth.addAnnotation(ThrowsClass, arg)
- }
- }
-
- private def isClosureApply(sym: Symbol): Boolean = {
- (sym.name == nme.apply) &&
- sym.owner.isSynthetic &&
- sym.owner.tpe.parents.exists { t =>
- val TypeRef(_, sym, _) = t
- FunctionClass contains sym
- }
- }
-
- def addModuleInstanceField() {
- jclass.addNewField(PublicStaticFinal,
- nme.MODULE_INSTANCE_FIELD.toString,
- jclass.getType())
- }
-
- def addStaticInit(cls: JClass, mopt: Option[IMethod]) {
- val clinitMethod = cls.addNewMethod(PublicStatic,
- "<clinit>",
- JType.VOID,
- JType.EMPTY_ARRAY,
- new Array[String](0))
- val clinit = clinitMethod.getCode().asInstanceOf[JExtendedCode]
-
- mopt match {
- case Some(m) =>
- val oldLastBlock = m.lastBlock
- val lastBlock = m.newBlock()
- oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock))
-
- if (isStaticModule(clasz.symbol)) {
- // call object's private ctor from static ctor
- lastBlock emit NEW(REFERENCE(m.symbol.enclClass))
- lastBlock emit CALL_METHOD(m.symbol.enclClass.primaryConstructor, Static(true))
- }
-
- // add serialVUID code
- serialVUID foreach { value =>
- import Flags._, definitions._
- val fieldName = "serialVersionUID"
- val fieldSymbol = clasz.symbol.newValue(newTermName(fieldName), NoPosition, STATIC | FINAL) setInfo LongClass.tpe
- clasz addField new IField(fieldSymbol)
- lastBlock emit CONSTANT(Constant(value))
- lastBlock emit STORE_FIELD(fieldSymbol, true)
- }
-
- if (isParcelableClass)
- addCreatorCode(BytecodeGenerator.this, lastBlock)
-
- lastBlock emit RETURN(UNIT)
- lastBlock.close
-
- method = m
- jmethod = clinitMethod
- genCode(m)
- case None =>
- legacyStaticInitializer(cls, clinit)
- }
- }
-
- private def legacyStaticInitializer(cls: JClass, clinit: JExtendedCode) {
- if (isStaticModule(clasz.symbol)) {
- clinit emitNEW cls.getName()
- clinit.emitINVOKESPECIAL(cls.getName(),
- JMethod.INSTANCE_CONSTRUCTOR_NAME,
- JMethodType.ARGLESS_VOID_FUNCTION)
- }
-
- serialVUID foreach { value =>
- val fieldName = "serialVersionUID"
- jclass.addNewField(PublicStaticFinal, fieldName, JType.LONG)
- clinit emitPUSH value
- clinit.emitPUSH(value)
- clinit.emitPUTSTATIC(jclass.getName(), fieldName, JType.LONG)
- }
-
- if (isParcelableClass)
- legacyAddCreatorCode(BytecodeGenerator.this, clinit)
-
- clinit.emitRETURN()
- }
-
- /** Add a forwarder for method m */
- def addForwarder(jclass: JClass, module: Symbol, m: Symbol) {
- val moduleName = javaName(module)
- val methodInfo = module.thisType.memberInfo(m)
- val paramJavaTypes = methodInfo.paramTypes map javaType
- val paramNames = 0 until paramJavaTypes.length map ("x_" + _)
- // TODO: evaluate the other flags we might be dropping on the floor here.
- val flags = PublicStatic | (
- if (m.isVarargsMethod) ACC_VARARGS else 0
- )
-
- /** Forwarders must not be marked final, as the JVM will not allow
- * redefinition of a final static method, and we don't know what classes
- * might be subclassing the companion class. See SI-4827.
- */
- val mirrorMethod = jclass.addNewMethod(
- flags,
- javaName(m),
- javaType(methodInfo.resultType),
- mkArray(paramJavaTypes),
- mkArray(paramNames))
- val mirrorCode = mirrorMethod.getCode().asInstanceOf[JExtendedCode]
- mirrorCode.emitGETSTATIC(moduleName,
- nme.MODULE_INSTANCE_FIELD.toString,
- new JObjectType(moduleName))
-
- var i = 0
- var index = 0
- val argTypes = mirrorMethod.getArgumentTypes()
- while (i < argTypes.length) {
- mirrorCode.emitLOAD(index, argTypes(i))
- index += argTypes(i).getSize()
- i += 1
- }
-
- mirrorCode.emitINVOKEVIRTUAL(moduleName, mirrorMethod.getName, javaType(m).asInstanceOf[JMethodType])
- mirrorCode emitRETURN mirrorMethod.getReturnType()
-
- addRemoteException(mirrorMethod, m)
- // only add generic signature if the method is concrete; bug #1745
- if (!m.isDeferred)
- addGenericSignature(mirrorMethod, m, module)
-
- val (throws, others) = m.annotations partition (_.symbol == ThrowsClass)
- addExceptionsAttribute(mirrorMethod, throws)
- addAnnotations(mirrorMethod, others)
- addParamAnnotations(mirrorMethod, m.info.params.map(_.annotations))
- }
-
- /** Add forwarders for all methods defined in `module` that don't conflict
- * with methods in the companion class of `module`. A conflict arises when
- * a method with the same name is defined both in a class and its companion
- * object: method signature is not taken into account.
- */
- def addForwarders(jclass: JClass, moduleClass: Symbol) {
- assert(moduleClass.isModuleClass, moduleClass)
- debuglog("Dumping mirror class for object: " + moduleClass)
-
- val className = jclass.getName
- val linkedClass = moduleClass.companionClass
- lazy val conflictingNames: Set[Name] = {
- linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name } toSet
- }
- debuglog("Potentially conflicting names for forwarders: " + conflictingNames)
-
- for (m <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flags.METHOD)) {
- if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor)
- debuglog("No forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
- else if (conflictingNames(m.name))
- log("No forwarder for " + m + " due to conflict with " + linkedClass.info.member(m.name))
- else {
- log("Adding static forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
- addForwarder(jclass, moduleClass, m)
- }
- }
- }
-
- /** Generate a mirror class for a top-level module. A mirror class is a class
- * containing only static methods that forward to the corresponding method
- * on the MODULE instance of the given Scala object. It will only be
- * generated if there is no companion class: if there is, an attempt will
- * instead be made to add the forwarder methods to the companion class.
- */
- def generateMirrorClass(clasz: Symbol, sourceFile: SourceFile) {
- import JAccessFlags._
- /* We need to save inner classes buffer and create a new one to make sure
- * that we do confuse inner classes of the class we mirror with inner
- * classes of the class we are mirroring. These two sets can be different
- * as seen in this case:
- *
- * class A {
- * class B
- * def b: B = new B
- * }
- * object C extends A
- *
- * Here mirror class of C has a static forwarder for (inherited) method `b`
- * therefore it refers to class `B` and needs InnerClasses entry. However,
- * the real class for `C` (named `C$`) is empty and does not refer to `B`
- * thus does not need InnerClasses entry it.
- *
- * NOTE: This logic has been refactored in GenASM and everything is
- * implemented in a much cleaner way by having two separate buffers.
- */
- val savedInnerClasses = innerClassBuffer
- innerClassBuffer = mutable.LinkedHashSet[Symbol]()
- val moduleName = javaName(clasz) // + "$"
- val mirrorName = moduleName.substring(0, moduleName.length() - 1)
- val mirrorClass = fjbgContext.JClass(ACC_SUPER | ACC_PUBLIC | ACC_FINAL,
- mirrorName,
- JAVA_LANG_OBJECT.getName,
- JClass.NO_INTERFACES,
- "" + sourceFile)
-
- log("Dumping mirror class for '%s'".format(mirrorClass.getName))
- addForwarders(mirrorClass, clasz)
- val ssa = scalaSignatureAddingMarker(mirrorClass, clasz.companionSymbol)
- addAnnotations(mirrorClass, clasz.annotations ++ ssa)
- emitClass(mirrorClass, clasz)
- innerClassBuffer = savedInnerClasses
- }
-
- var linearization: List[BasicBlock] = Nil
- var isModuleInitialized = false
-
- def genCode(m: IMethod) {
- val jcode = jmethod.getCode.asInstanceOf[JExtendedCode]
-
- def makeLabels(bs: List[BasicBlock]) = {
- debuglog("Making labels for: " + method)
-
- mutable.HashMap(bs map (_ -> jcode.newLabel) : _*)
- }
-
- isModuleInitialized = false
-
- linearization = linearizer.linearize(m)
- val labels = makeLabels(linearization)
-
- var nextBlock: BasicBlock = linearization.head
-
- def genBlocks(l: List[BasicBlock]): Unit = l match {
- case Nil => ()
- case x :: Nil => nextBlock = null; genBlock(x)
- case x :: y :: ys => nextBlock = y; genBlock(x); genBlocks(y :: ys)
- }
-
- /** Generate exception handlers for the current method. */
- def genExceptionHandlers() {
-
- /** Return a list of pairs of intervals where the handler is active.
- * The intervals in the list have to be inclusive in the beginning and
- * exclusive in the end: [start, end).
- */
- def ranges(e: ExceptionHandler): List[(Int, Int)] = {
- var covered = e.covered
- var ranges: List[(Int, Int)] = Nil
- var start = -1
- var end = -1
-
- linearization foreach { b =>
- if (! (covered contains b) ) {
- if (start >= 0) { // we're inside a handler range
- end = labels(b).getAnchor()
- ranges ::= ((start, end))
- start = -1
- }
- } else {
- if (start < 0) // we're not inside a handler range
- start = labels(b).getAnchor()
-
- end = endPC(b)
- covered -= b
- }
- }
-
- /* Add the last interval. Note that since the intervals are
- * open-ended to the right, we have to give a number past the actual
- * code!
- */
- if (start >= 0) {
- ranges ::= ((start, jcode.getPC()))
- }
-
- if (!covered.isEmpty)
- debuglog("Some covered blocks were not found in method: " + method +
- " covered: " + covered + " not in " + linearization)
- ranges
- }
-
- for (e <- this.method.exh ; p <- ranges(e).sortBy(_._1)) {
- if (p._1 < p._2) {
- debuglog("Adding exception handler " + e + "at block: " + e.startBlock + " for " + method +
- " from: " + p._1 + " to: " + p._2 + " catching: " + e.cls);
- val cls = if (e.cls == NoSymbol || e.cls == ThrowableClass) null
- else javaName(e.cls)
- jcode.addExceptionHandler(p._1, p._2,
- labels(e.startBlock).getAnchor(),
- cls)
- } else
- log("Empty exception range: " + p)
- }
- }
-
- def isAccessibleFrom(target: Symbol, site: Symbol): Boolean = {
- target.isPublic || target.isProtected && {
- (site.enclClass isSubClass target.enclClass) ||
- (site.enclosingPackage == target.privateWithin)
- }
- }
-
- def genCallMethod(call: CALL_METHOD) {
- val CALL_METHOD(method, style) = call
- val siteSymbol = clasz.symbol
- val hostSymbol = call.hostClass
- val methodOwner = method.owner
- // info calls so that types are up to date; erasure may add lateINTERFACE to traits
- hostSymbol.info ; methodOwner.info
-
- def isInterfaceCall(sym: Symbol) = (
- sym.isInterface && methodOwner != ObjectClass
- || sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass)
- )
- // whether to reference the type of the receiver or
- // the type of the method owner (if not an interface!)
- val useMethodOwner = (
- style != Dynamic
- || !isInterfaceCall(hostSymbol) && isAccessibleFrom(methodOwner, siteSymbol)
- || hostSymbol.isBottomClass
- )
- val receiver = if (useMethodOwner) methodOwner else hostSymbol
- val jowner = javaName(receiver)
- val jname = javaName(method)
- val jtype = javaType(method).asInstanceOf[JMethodType]
-
- def dbg(invoke: String) {
- debuglog("%s %s %s.%s:%s".format(invoke, receiver.accessString, jowner, jname, jtype))
- }
-
- def initModule() {
- // we initialize the MODULE$ field immediately after the super ctor
- if (isStaticModule(siteSymbol) && !isModuleInitialized &&
- jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME &&
- jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) {
- isModuleInitialized = true
- jcode.emitALOAD_0()
- jcode.emitPUTSTATIC(jclass.getName(),
- nme.MODULE_INSTANCE_FIELD.toString,
- jclass.getType())
- }
- }
-
- style match {
- case Static(true) => dbg("invokespecial"); jcode.emitINVOKESPECIAL(jowner, jname, jtype)
- case Static(false) => dbg("invokestatic"); jcode.emitINVOKESTATIC(jowner, jname, jtype)
- case Dynamic if isInterfaceCall(receiver) => dbg("invokinterface"); jcode.emitINVOKEINTERFACE(jowner, jname, jtype)
- case Dynamic => dbg("invokevirtual"); jcode.emitINVOKEVIRTUAL(jowner, jname, jtype)
- case SuperCall(_) =>
- dbg("invokespecial")
- jcode.emitINVOKESPECIAL(jowner, jname, jtype)
- initModule()
- }
- }
-
- def genBlock(b: BasicBlock) {
- labels(b).anchorToNext()
-
- debuglog("Generating code for block: " + b + " at pc: " + labels(b).getAnchor())
- var lastMappedPC = 0
- var lastLineNr = 0
- var crtPC = 0
-
- /** local variables whose scope appears in this block. */
- val varsInBlock: mutable.Set[Local] = new mutable.HashSet
- val lastInstr = b.lastInstruction
-
- for (instr <- b) {
- instr match {
- case THIS(clasz) => jcode.emitALOAD_0()
-
- case CONSTANT(const) => genConstant(jcode, const)
-
- case LOAD_ARRAY_ITEM(kind) =>
- if(kind.isRefOrArrayType) { jcode.emitAALOAD() }
- else {
- (kind: @unchecked) match {
- case UNIT => throw new IllegalArgumentException("invalid type for aload " + kind)
- case BOOL | BYTE => jcode.emitBALOAD()
- case SHORT => jcode.emitSALOAD()
- case CHAR => jcode.emitCALOAD()
- case INT => jcode.emitIALOAD()
- case LONG => jcode.emitLALOAD()
- case FLOAT => jcode.emitFALOAD()
- case DOUBLE => jcode.emitDALOAD()
- }
- }
-
- case LOAD_LOCAL(local) => jcode.emitLOAD(indexOf(local), javaType(local.kind))
-
- case lf @ LOAD_FIELD(field, isStatic) =>
- val owner = javaName(lf.hostClass)
- debuglog("LOAD_FIELD with owner: " + owner +
- " flags: " + field.owner.flagString)
- val fieldJName = javaName(field)
- val fieldJType = javaType(field)
- if (isStatic) jcode.emitGETSTATIC(owner, fieldJName, fieldJType)
- else jcode.emitGETFIELD( owner, fieldJName, fieldJType)
-
- case LOAD_MODULE(module) =>
- // assert(module.isModule, "Expected module: " + module)
- debuglog("generating LOAD_MODULE for: " + module + " flags: " + module.flagString);
- if (clasz.symbol == module.moduleClass && jmethod.getName() != nme.readResolve.toString)
- jcode.emitALOAD_0()
- else
- jcode.emitGETSTATIC(javaName(module) /* + "$" */ ,
- nme.MODULE_INSTANCE_FIELD.toString,
- javaType(module))
-
- case STORE_ARRAY_ITEM(kind) =>
- if(kind.isRefOrArrayType) { jcode.emitAASTORE() }
- else {
- (kind: @unchecked) match {
- case UNIT => throw new IllegalArgumentException("invalid type for astore " + kind)
- case BOOL | BYTE => jcode.emitBASTORE()
- case SHORT => jcode.emitSASTORE()
- case CHAR => jcode.emitCASTORE()
- case INT => jcode.emitIASTORE()
- case LONG => jcode.emitLASTORE()
- case FLOAT => jcode.emitFASTORE()
- case DOUBLE => jcode.emitDASTORE()
- }
- }
-
- case STORE_LOCAL(local) =>
- jcode.emitSTORE(indexOf(local), javaType(local.kind))
-
- case STORE_THIS(_) =>
- // this only works for impl classes because the self parameter comes first
- // in the method signature. If that changes, this code has to be revisited.
- jcode.emitASTORE_0()
-
- case STORE_FIELD(field, isStatic) =>
- val owner = javaName(field.owner)
- val fieldJName = javaName(field)
- val fieldJType = javaType(field)
- if (isStatic) jcode.emitPUTSTATIC(owner, fieldJName, fieldJType)
- else jcode.emitPUTFIELD( owner, fieldJName, fieldJType)
-
- case CALL_PRIMITIVE(primitive) => genPrimitive(primitive, instr.pos)
-
- /** Special handling to access native Array.clone() */
- case call @ CALL_METHOD(definitions.Array_clone, Dynamic) =>
- val target: String = javaType(call.targetTypeKind).getSignature()
- jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType)
-
- case call @ CALL_METHOD(method, style) => genCallMethod(call)
-
- case BOX(kind) =>
- val Pair(mname, mtype) = jBoxTo(kind)
- jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype)
-
- case UNBOX(kind) =>
- val Pair(mname, mtype) = jUnboxTo(kind)
- jcode.emitINVOKESTATIC(BoxesRunTime, mname, mtype)
-
- case NEW(REFERENCE(cls)) =>
- val className = javaName(cls)
- jcode emitNEW className
-
- case CREATE_ARRAY(elem, 1) =>
- if(elem.isRefOrArrayType) { jcode emitANEWARRAY javaType(elem).asInstanceOf[JReferenceType] }
- else { jcode emitNEWARRAY javaType(elem) }
-
- case CREATE_ARRAY(elem, dims) =>
- jcode.emitMULTIANEWARRAY(javaType(ArrayN(elem, dims)).asInstanceOf[JReferenceType], dims)
-
- case IS_INSTANCE(tpe) =>
- tpe match {
- case REFERENCE(cls) => jcode emitINSTANCEOF new JObjectType(javaName(cls))
- case ARRAY(elem) => jcode emitINSTANCEOF new JArrayType(javaType(elem))
- case _ => abort("Unknown reference type in IS_INSTANCE: " + tpe)
- }
-
- case CHECK_CAST(tpe) =>
- tpe match {
- case REFERENCE(cls) => if (cls != ObjectClass) { jcode emitCHECKCAST new JObjectType(javaName(cls)) } // No need to checkcast for Objects
- case ARRAY(elem) => jcode emitCHECKCAST new JArrayType(javaType(elem))
- case _ => abort("Unknown reference type in IS_INSTANCE: " + tpe)
- }
-
- case SWITCH(tags, branches) =>
- val tagArray = new Array[Array[Int]](tags.length)
- var caze = tags
- var i = 0
-
- while (i < tagArray.length) {
- tagArray(i) = new Array[Int](caze.head.length)
- caze.head.copyToArray(tagArray(i), 0)
- i += 1
- caze = caze.tail
- }
- val branchArray = jcode.newLabels(tagArray.length)
- i = 0
- while (i < branchArray.length) {
- branchArray(i) = labels(branches(i))
- i += 1
- }
- debuglog("Emitting SWITCH:\ntags: " + tags + "\nbranches: " + branches)
- jcode.emitSWITCH(tagArray,
- branchArray,
- labels(branches.last),
- MIN_SWITCH_DENSITY)
- ()
-
- case JUMP(whereto) =>
- if (nextBlock != whereto)
- jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps
-
- case CJUMP(success, failure, cond, kind) =>
- if(kind.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
- if (nextBlock == success) {
- jcode.emitIF_ICMP(conds(cond.negate()), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF_ICMP(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- } else if(kind.isRefOrArrayType) { // REFERENCE(_) | ARRAY(_)
- if (nextBlock == success) {
- jcode.emitIF_ACMP(conds(cond.negate()), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF_ACMP(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- } else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLCMP()
- case FLOAT =>
- if (cond == LT || cond == LE) jcode.emitFCMPG()
- else jcode.emitFCMPL()
- case DOUBLE =>
- if (cond == LT || cond == LE) jcode.emitDCMPG()
- else jcode.emitDCMPL()
- }
- if (nextBlock == success) {
- jcode.emitIF(conds(cond.negate()), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF(conds(cond), labels(success));
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- }
-
- case CZJUMP(success, failure, cond, kind) =>
- if(kind.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
- if (nextBlock == success) {
- jcode.emitIF(conds(cond.negate()), labels(failure))
- } else {
- jcode.emitIF(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- } else if(kind.isRefOrArrayType) { // REFERENCE(_) | ARRAY(_)
- val Success = success
- val Failure = failure
- (cond, nextBlock) match {
- case (EQ, Success) => jcode emitIFNONNULL labels(failure)
- case (NE, Failure) => jcode emitIFNONNULL labels(success)
- case (EQ, Failure) => jcode emitIFNULL labels(success)
- case (NE, Success) => jcode emitIFNULL labels(failure)
- case (EQ, _) =>
- jcode emitIFNULL labels(success)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- case (NE, _) =>
- jcode emitIFNONNULL labels(success)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- case _ =>
- }
- } else {
- (kind: @unchecked) match {
- case LONG =>
- jcode.emitLCONST_0()
- jcode.emitLCMP()
- case FLOAT =>
- jcode.emitFCONST_0()
- if (cond == LT || cond == LE) jcode.emitFCMPG()
- else jcode.emitFCMPL()
- case DOUBLE =>
- jcode.emitDCONST_0()
- if (cond == LT || cond == LE) jcode.emitDCMPG()
- else jcode.emitDCMPL()
- }
- if (nextBlock == success) {
- jcode.emitIF(conds(cond.negate()), labels(failure))
- } else {
- jcode.emitIF(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- }
-
- case RETURN(kind) => jcode emitRETURN javaType(kind)
-
- case THROW(_) => jcode.emitATHROW()
-
- case DROP(kind) =>
- if(kind.isWideType) jcode.emitPOP2()
- else jcode.emitPOP()
-
- case DUP(kind) =>
- if(kind.isWideType) jcode.emitDUP2()
- else jcode.emitDUP()
-
- case MONITOR_ENTER() => jcode.emitMONITORENTER()
-
- case MONITOR_EXIT() => jcode.emitMONITOREXIT()
-
- case SCOPE_ENTER(lv) =>
- varsInBlock += lv
- lv.start = jcode.getPC()
-
- case SCOPE_EXIT(lv) =>
- if (varsInBlock(lv)) {
- lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
- varsInBlock -= lv
- }
- else if (b.varsInScope(lv)) {
- lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
- b.varsInScope -= lv
- }
- else dumpMethodAndAbort(method, "Illegal local var nesting")
-
- case LOAD_EXCEPTION(_) =>
- ()
- }
-
- crtPC = jcode.getPC()
-
- // assert(instr.pos.source.isEmpty || instr.pos.source.get == (clasz.cunit.source), "sources don't match")
- // val crtLine = instr.pos.line.get(lastLineNr);
-
- val crtLine = try {
- if (instr.pos == NoPosition) lastLineNr else (instr.pos).line // check NoPosition to avoid costly exception
- } catch {
- case _: UnsupportedOperationException =>
- log("Warning: wrong position in: " + method)
- lastLineNr
- }
-
- if (instr eq lastInstr) { endPC(b) = jcode.getPC() }
-
- //System.err.println("CRTLINE: " + instr.pos + " " +
- // /* (if (instr.pos < clasz.cunit.source.content.length) clasz.cunit.source.content(instr.pos) else '*') + */ " " + crtLine);
-
- if (crtPC > lastMappedPC) {
- jcode.completeLineNumber(lastMappedPC, crtPC, crtLine)
- lastMappedPC = crtPC
- lastLineNr = crtLine
- }
- }
-
- // local vars that survived this basic block
- for (lv <- varsInBlock) {
- lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
- }
- for (lv <- b.varsInScope) {
- lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
- }
- }
-
- def genPrimitive(primitive: Primitive, pos: Position) {
- primitive match {
- case Negation(kind) =>
- if(kind.isIntSizedType) { jcode.emitINEG() }
- else {
- kind match {
- case LONG => jcode.emitLNEG()
- case FLOAT => jcode.emitFNEG()
- case DOUBLE => jcode.emitDNEG()
- case _ => abort("Impossible to negate a " + kind)
- }
- }
-
- case Arithmetic(op, kind) =>
- op match {
- case ADD =>
- if(kind.isIntSizedType) { jcode.emitIADD() }
- else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLADD()
- case FLOAT => jcode.emitFADD()
- case DOUBLE => jcode.emitDADD()
- }
- }
-
- case SUB =>
- if(kind.isIntSizedType) { jcode.emitISUB() }
- else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLSUB()
- case FLOAT => jcode.emitFSUB()
- case DOUBLE => jcode.emitDSUB()
- }
- }
-
- case MUL =>
- if(kind.isIntSizedType) { jcode.emitIMUL() }
- else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLMUL()
- case FLOAT => jcode.emitFMUL()
- case DOUBLE => jcode.emitDMUL()
- }
- }
-
- case DIV =>
- if(kind.isIntSizedType) { jcode.emitIDIV() }
- else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLDIV()
- case FLOAT => jcode.emitFDIV()
- case DOUBLE => jcode.emitDDIV()
- }
- }
-
- case REM =>
- if(kind.isIntSizedType) { jcode.emitIREM() }
- else {
- (kind: @unchecked) match {
- case LONG => jcode.emitLREM()
- case FLOAT => jcode.emitFREM()
- case DOUBLE => jcode.emitDREM()
- }
- }
-
- case NOT =>
- if(kind.isIntSizedType) {
- jcode.emitPUSH(-1)
- jcode.emitIXOR()
- } else if(kind == LONG) {
- jcode.emitPUSH(-1l)
- jcode.emitLXOR()
- } else {
- abort("Impossible to negate an " + kind)
- }
-
- case _ =>
- abort("Unknown arithmetic primitive " + primitive)
- }
-
- case Logical(op, kind) => ((op, kind): @unchecked) match {
- case (AND, LONG) => jcode.emitLAND()
- case (AND, INT) => jcode.emitIAND()
- case (AND, _) =>
- jcode.emitIAND()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
-
- case (OR, LONG) => jcode.emitLOR()
- case (OR, INT) => jcode.emitIOR()
- case (OR, _) =>
- jcode.emitIOR()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
-
- case (XOR, LONG) => jcode.emitLXOR()
- case (XOR, INT) => jcode.emitIXOR()
- case (XOR, _) =>
- jcode.emitIXOR()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
- }
-
- case Shift(op, kind) => ((op, kind): @unchecked) match {
- case (LSL, LONG) => jcode.emitLSHL()
- case (LSL, INT) => jcode.emitISHL()
- case (LSL, _) =>
- jcode.emitISHL()
- jcode.emitT2T(javaType(INT), javaType(kind))
-
- case (ASR, LONG) => jcode.emitLSHR()
- case (ASR, INT) => jcode.emitISHR()
- case (ASR, _) =>
- jcode.emitISHR()
- jcode.emitT2T(javaType(INT), javaType(kind))
-
- case (LSR, LONG) => jcode.emitLUSHR()
- case (LSR, INT) => jcode.emitIUSHR()
- case (LSR, _) =>
- jcode.emitIUSHR()
- jcode.emitT2T(javaType(INT), javaType(kind))
- }
-
- case Comparison(op, kind) => ((op, kind): @unchecked) match {
- case (CMP, LONG) => jcode.emitLCMP()
- case (CMPL, FLOAT) => jcode.emitFCMPL()
- case (CMPG, FLOAT) => jcode.emitFCMPG()
- case (CMPL, DOUBLE) => jcode.emitDCMPL()
- case (CMPG, DOUBLE) => jcode.emitDCMPL()
- }
-
- case Conversion(src, dst) =>
- debuglog("Converting from: " + src + " to: " + dst)
- if (dst == BOOL) {
- println("Illegal conversion at: " + clasz + " at: " + pos.source + ":" + pos.line)
- } else
- jcode.emitT2T(javaType(src), javaType(dst))
-
- case ArrayLength(_) =>
- jcode.emitARRAYLENGTH()
-
- case StartConcat =>
- jcode emitNEW StringBuilderClassName
- jcode.emitDUP()
- jcode.emitINVOKESPECIAL(StringBuilderClassName,
- JMethod.INSTANCE_CONSTRUCTOR_NAME,
- JMethodType.ARGLESS_VOID_FUNCTION)
-
- case StringConcat(el) =>
- val jtype = el match {
- case REFERENCE(_) | ARRAY(_) => JAVA_LANG_OBJECT
- case _ => javaType(el)
- }
- jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
- "append",
- new JMethodType(StringBuilderType,
- Array(jtype)))
- case EndConcat =>
- jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
- "toString",
- toStringType)
-
- case _ =>
- abort("Unimplemented primitive " + primitive)
- }
- }
-
- // genCode starts here
- genBlocks(linearization)
-
- if (this.method.exh != Nil)
- genExceptionHandlers;
- }
-
-
- /** Emit a Local variable table for debugging purposes.
- * Synthetic locals are skipped. All variables are method-scoped.
- */
- private def genLocalVariableTable(m: IMethod, jcode: JCode) {
- val vars = m.locals filterNot (_.sym.isArtifact)
- if (vars.isEmpty) return
-
- val pool = jclass.getConstantPool
- val pc = jcode.getPC()
- var anonCounter = 0
- var entries = 0
- vars.foreach { lv =>
- lv.ranges = mergeEntries(lv.ranges.reverse);
- entries += lv.ranges.length
- }
- if (!jmethod.isStatic()) entries += 1
-
- val lvTab = ByteBuffer.allocate(2 + 10 * entries)
- def emitEntry(name: String, signature: String, idx: Short, start: Short, end: Short) {
- lvTab putShort start
- lvTab putShort end
- lvTab putShort pool.addUtf8(name).toShort
- lvTab putShort pool.addUtf8(signature).toShort
- lvTab putShort idx
- }
-
- lvTab.putShort(entries.toShort)
-
- if (!jmethod.isStatic()) {
- emitEntry("this", jclass.getType().getSignature(), 0, 0.toShort, pc.toShort)
- }
-
- for (lv <- vars) {
- val name = if (javaName(lv.sym) eq null) {
- anonCounter += 1
- "<anon" + anonCounter + ">"
- } else javaName(lv.sym)
-
- val index = indexOf(lv).toShort
- val tpe = javaType(lv.kind).getSignature()
- for ((start, end) <- lv.ranges) {
- emitEntry(name, tpe, index, start.toShort, (end - start).toShort)
- }
- }
- val attr =
- fjbgContext.JOtherAttribute(jclass,
- jcode,
- tpnme.LocalVariableTableATTR.toString,
- lvTab.array())
- jcode addAttribute attr
- }
-
-
- /** For each basic block, the first PC address following it. */
- val endPC = new mutable.HashMap[BasicBlock, Int]
-
- ////////////////////// local vars ///////////////////////
-
- def sizeOf(k: TypeKind): Int = if(k.isWideType) 2 else 1
-
- def indexOf(local: Local): Int = {
- assert(local.index >= 0, "Invalid index for: " + local + "{" + local.## + "}: ")
- local.index
- }
-
- /**
- * Compute the indexes of each local variable of the given
- * method. *Does not assume the parameters come first!*
- */
- def computeLocalVarsIndex(m: IMethod) {
- var idx = if (m.symbol.isStaticMember) 0 else 1;
-
- for (l <- m.params) {
- debuglog("Index value for " + l + "{" + l.## + "}: " + idx)
- l.index = idx
- idx += sizeOf(l.kind)
- }
-
- for (l <- m.locals if !(m.params contains l)) {
- debuglog("Index value for " + l + "{" + l.## + "}: " + idx)
- l.index = idx
- idx += sizeOf(l.kind)
- }
- }
-
- ////////////////////// Utilities ////////////////////////
-
- /** Merge adjacent ranges. */
- private def mergeEntries(ranges: List[(Int, Int)]): List[(Int, Int)] =
- (ranges.foldLeft(Nil: List[(Int, Int)]) { (collapsed: List[(Int, Int)], p: (Int, Int)) => (collapsed, p) match {
- case (Nil, _) => List(p)
- case ((s1, e1) :: rest, (s2, e2)) if (e1 == s2) => (s1, e2) :: rest
- case _ => p :: collapsed
- }}).reverse
- }
-
- private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
-
- /**
- * Return the Java modifiers for the given symbol.
- * Java modifiers for classes:
- * - public, abstract, final, strictfp (not used)
- * for interfaces:
- * - the same as for classes, without 'final'
- * for fields:
- * - public, private (*)
- * - static, final
- * for methods:
- * - the same as for fields, plus:
- * - abstract, synchronized (not used), strictfp (not used), native (not used)
- *
- * (*) protected cannot be used, since inner classes 'see' protected members,
- * and they would fail verification after lifted.
- */
- def javaFlags(sym: Symbol): Int = {
- // constructors of module classes should be private
- // PP: why are they only being marked private at this stage and not earlier?
- val privateFlag =
- sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
-
- // Final: the only fields which can receive ACC_FINAL are eager vals.
- // Neither vars nor lazy vals can, because:
- //
- // Source: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
- // "Another problem is that the specification allows aggressive
- // optimization of final fields. Within a thread, it is permissible to
- // reorder reads of a final field with those modifications of a final
- // field that do not take place in the constructor."
- //
- // A var or lazy val which is marked final still has meaning to the
- // scala compiler. The word final is heavily overloaded unfortunately;
- // for us it means "not overridable". At present you can't override
- // vars regardless; this may change.
- //
- // The logic does not check .isFinal (which checks flags for the FINAL flag,
- // and includes symbols marked lateFINAL) instead inspecting rawflags so
- // we can exclude lateFINAL. Such symbols are eligible for inlining, but to
- // avoid breaking proxy software which depends on subclassing, we do not
- // emit ACC_FINAL.
- // Nested objects won't receive ACC_FINAL in order to allow for their overriding.
-
- val finalFlag = (
- (((sym.rawflags & Flags.FINAL) != 0) || isTopLevelModule(sym))
- && !sym.enclClass.isInterface
- && !sym.isClassConstructor
- && !sym.isMutable // lazy vals and vars both
- )
-
- // Primitives are "abstract final" to prohibit instantiation
- // without having to provide any implementations, but that is an
- // illegal combination of modifiers at the bytecode level so
- // suppress final if abstract if present.
- mkFlags(
- if (privateFlag) ACC_PRIVATE else ACC_PUBLIC,
- if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0,
- if (sym.isInterface) ACC_INTERFACE else 0,
- if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0,
- if (sym.isStaticMember) ACC_STATIC else 0,
- if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
- if (sym.isArtifact) ACC_SYNTHETIC else 0,
- if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
- if (sym.isVarargsMethod) ACC_VARARGS else 0,
- if (sym.hasFlag(Flags.SYNCHRONIZED)) JAVA_ACC_SYNCHRONIZED else 0
- )
- }
- def javaFieldFlags(sym: Symbol) = (
- javaFlags(sym) | mkFlags(
- if (sym hasAnnotation TransientAttr) ACC_TRANSIENT else 0,
- if (sym hasAnnotation VolatileAttr) ACC_VOLATILE else 0,
- if (sym.isMutable) 0 else ACC_FINAL
- )
- )
-
- def isTopLevelModule(sym: Symbol): Boolean =
- exitingPickler { sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass }
-
- def isStaticModule(sym: Symbol): Boolean = {
- sym.isModuleClass && !sym.isImplClass && !sym.isLifted
- }
-
-}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
new file mode 100644
index 0000000000..f0f91e7d1a
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMASM.scala
@@ -0,0 +1,97 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2013 LAMP/EPFL
+ * @author Jason Zaugg
+ */
+
+package scala.tools.nsc
+package backend.jvm
+import scala.tools.nsc.io.AbstractFile
+import scala.tools.nsc.symtab._
+
+/** Code shared between the legagy backend [[scala.tools.nsc.backend.jvm.GenJVM]]
+ * and the new backend [[scala.tools.nsc.backend.jvm.GenASM]]. There should be
+ * more here, but for now I'm starting with the refactorings that are either
+ * straightforward to review or necessary for maintenance.
+ */
+trait GenJVMASM {
+ val global: Global
+ import global._
+ import icodes._
+ import definitions._
+
+ protected def outputDirectory(sym: Symbol): AbstractFile =
+ settings.outputDirs outputDirFor enteringFlatten(sym.sourceFile)
+
+ protected def getFile(base: AbstractFile, clsName: String, suffix: String): AbstractFile = {
+ var dir = base
+ val pathParts = clsName.split("[./]").toList
+ for (part <- pathParts.init) {
+ dir = dir.subdirectoryNamed(part)
+ }
+ dir.fileNamed(pathParts.last + suffix)
+ }
+ protected def getFile(sym: Symbol, clsName: String, suffix: String): AbstractFile =
+ getFile(outputDirectory(sym), clsName, suffix)
+
+ protected val ExcludedForwarderFlags = {
+ import Flags._
+ // Should include DEFERRED but this breaks findMember.
+ ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | BridgeAndPrivateFlags | MACRO )
+ }
+
+ protected def isJavaEntryPoint(icls: IClass) = {
+ val sym = icls.symbol
+ def fail(msg: String, pos: Position = sym.pos) = {
+ icls.cunit.warning(sym.pos,
+ sym.name + " has a main method with parameter type Array[String], but " + sym.fullName('.') + " will not be a runnable program.\n" +
+ " Reason: " + msg
+ // TODO: make this next claim true, if possible
+ // by generating valid main methods as static in module classes
+ // not sure what the jvm allows here
+ // + " You can still run the program by calling it as " + sym.javaSimpleName + " instead."
+ )
+ false
+ }
+ def failNoForwarder(msg: String) = {
+ fail(msg + ", which means no static forwarder can be generated.\n")
+ }
+ val possibles = if (sym.hasModuleFlag) (sym.tpe nonPrivateMember nme.main).alternatives else Nil
+ val hasApproximate = possibles exists { m =>
+ m.info match {
+ case MethodType(p :: Nil, _) => p.tpe.typeSymbol == ArrayClass
+ case _ => false
+ }
+ }
+ // At this point it's a module with a main-looking method, so either succeed or warn that it isn't.
+ hasApproximate && {
+ // Before erasure so we can identify generic mains.
+ enteringErasure {
+ val companion = sym.linkedClassOfClass
+ val companionMain = companion.tpe.member(nme.main)
+
+ if (hasJavaMainMethod(companion))
+ failNoForwarder("companion contains its own main method")
+ else if (companion.tpe.member(nme.main) != NoSymbol)
+ // this is only because forwarders aren't smart enough yet
+ failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
+ else if (companion.isTrait)
+ failNoForwarder("companion is a trait")
+ // Now either succeeed, or issue some additional warnings for things which look like
+ // attempts to be java main methods.
+ else possibles exists { m =>
+ m.info match {
+ case PolyType(_, _) =>
+ fail("main methods cannot be generic.")
+ case MethodType(params, res) =>
+ if (res.typeSymbol :: params exists (_.isAbstractType))
+ fail("main methods cannot refer to type parameters or abstract types.", m.pos)
+ else
+ isJavaMainMethod(m) || fail("main method must have exact signature (Array[String])Unit", m.pos)
+ case tp =>
+ fail("don't know what this is: " + tp, m.pos)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
deleted file mode 100644
index 613f8f893e..0000000000
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ /dev/null
@@ -1,141 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Iulian Dragos
- */
-
-package scala.tools.nsc
-package backend.jvm
-
-import scala.collection.{ mutable, immutable }
-import ch.epfl.lamp.fjbg._
-
-trait GenJVMUtil {
- self: GenJVM =>
-
- import global._
- import icodes._
- import definitions._
-
- /** Map from type kinds to the Java reference types. It is used for
- * loading class constants. @see Predef.classOf.
- */
- val classLiteral = immutable.Map[TypeKind, JObjectType](
- UNIT -> new JObjectType("java.lang.Void"),
- BOOL -> new JObjectType("java.lang.Boolean"),
- BYTE -> new JObjectType("java.lang.Byte"),
- SHORT -> new JObjectType("java.lang.Short"),
- CHAR -> new JObjectType("java.lang.Character"),
- INT -> new JObjectType("java.lang.Integer"),
- LONG -> new JObjectType("java.lang.Long"),
- FLOAT -> new JObjectType("java.lang.Float"),
- DOUBLE -> new JObjectType("java.lang.Double")
- )
-
- // Don't put this in per run caches.
- private val javaNameCache = new mutable.WeakHashMap[Symbol, Name]() ++= List(
- NothingClass -> binarynme.RuntimeNothing,
- RuntimeNothingClass -> binarynme.RuntimeNothing,
- NullClass -> binarynme.RuntimeNull,
- RuntimeNullClass -> binarynme.RuntimeNull
- )
-
- /** This trait may be used by tools who need access to
- * utility methods like javaName and javaType. (for instance,
- * the Eclipse plugin uses it).
- */
- trait BytecodeUtil {
-
- val conds = immutable.Map[TestOp, Int](
- EQ -> JExtendedCode.COND_EQ,
- NE -> JExtendedCode.COND_NE,
- LT -> JExtendedCode.COND_LT,
- GT -> JExtendedCode.COND_GT,
- LE -> JExtendedCode.COND_LE,
- GE -> JExtendedCode.COND_GE
- )
-
- /** Specialized array conversion to prevent calling
- * java.lang.reflect.Array.newInstance via TraversableOnce.toArray
- */
-
- def mkArray(xs: Traversable[JType]): Array[JType] = { val a = new Array[JType](xs.size); xs.copyToArray(a); a }
- def mkArray(xs: Traversable[String]): Array[String] = { val a = new Array[String](xs.size); xs.copyToArray(a); a }
-
- /** Return the a name of this symbol that can be used on the Java
- * platform. It removes spaces from names.
- *
- * Special handling:
- * scala.Nothing erases to scala.runtime.Nothing$
- * scala.Null erases to scala.runtime.Null$
- *
- * This is needed because they are not real classes, and they mean
- * 'abrupt termination upon evaluation of that expression' or null respectively.
- * This handling is done already in GenICode, but here we need to remove
- * references from method signatures to these types, because such classes can
- * not exist in the classpath: the type checker will be very confused.
- */
- def javaName(sym: Symbol): String =
- javaNameCache.getOrElseUpdate(sym, {
- if (sym.isClass || (sym.isModule && !sym.isMethod))
- sym.javaBinaryName
- else
- sym.javaSimpleName
- }).toString
-
- def javaType(t: TypeKind): JType = (t: @unchecked) match {
- case UNIT => JType.VOID
- case BOOL => JType.BOOLEAN
- case BYTE => JType.BYTE
- case SHORT => JType.SHORT
- case CHAR => JType.CHAR
- case INT => JType.INT
- case LONG => JType.LONG
- case FLOAT => JType.FLOAT
- case DOUBLE => JType.DOUBLE
- case REFERENCE(cls) => new JObjectType(javaName(cls))
- case ARRAY(elem) => new JArrayType(javaType(elem))
- }
-
- def javaType(t: Type): JType = javaType(toTypeKind(t))
-
- def javaType(s: Symbol): JType =
- if (s.isMethod)
- new JMethodType(
- if (s.isClassConstructor) JType.VOID else javaType(s.tpe.resultType),
- mkArray(s.tpe.paramTypes map javaType)
- )
- else
- javaType(s.tpe)
-
- protected def genConstant(jcode: JExtendedCode, const: Constant) {
- const.tag match {
- case UnitTag => ()
- case BooleanTag => jcode emitPUSH const.booleanValue
- case ByteTag => jcode emitPUSH const.byteValue
- case ShortTag => jcode emitPUSH const.shortValue
- case CharTag => jcode emitPUSH const.charValue
- case IntTag => jcode emitPUSH const.intValue
- case LongTag => jcode emitPUSH const.longValue
- case FloatTag => jcode emitPUSH const.floatValue
- case DoubleTag => jcode emitPUSH const.doubleValue
- case StringTag => jcode emitPUSH const.stringValue
- case NullTag => jcode.emitACONST_NULL()
- case ClazzTag =>
- val kind = toTypeKind(const.typeValue)
- val toPush =
- if (kind.isValueType) classLiteral(kind)
- else javaType(kind).asInstanceOf[JReferenceType]
-
- jcode emitPUSH toPush
-
- case EnumTag =>
- val sym = const.symbolValue
- jcode.emitGETSTATIC(javaName(sym.owner),
- javaName(sym),
- javaType(sym.tpe.underlying))
- case _ =>
- abort("Unknown constant value: " + const)
- }
- }
- }
-}
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
deleted file mode 100644
index 2fb6550239..0000000000
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ /dev/null
@@ -1,2244 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Nikolay Mihaylov
- */
-
-
-package scala.tools.nsc
-package backend.msil
-
-import java.io.{File, IOException}
-import scala.collection.{ mutable, immutable }
-import scala.tools.nsc.symtab._
-
-import ch.epfl.lamp.compiler.msil.{Type => MsilType, _}
-import ch.epfl.lamp.compiler.msil.emit._
-import ch.epfl.lamp.compiler.msil.util.PECustomMod
-import scala.language.postfixOps
-
-abstract class GenMSIL extends SubComponent {
- import global._
- import loaders.clrTypes
- import clrTypes.{types, constructors, methods, fields}
- import icodes._
- import icodes.opcodes._
-
- /** Create a new phase */
- override def newPhase(p: Phase) = new MsilPhase(p)
-
- val phaseName = "msil"
- /** MSIL code generation phase
- */
- class MsilPhase(prev: Phase) extends GlobalPhase(prev) {
- def name = phaseName
- override def newFlags = phaseNewFlags
-
- override def erasedTypes = true
-
- override def run() {
- if (settings.debug.value) inform("[running phase " + name + " on icode]")
-
- val codeGenerator = new BytecodeGenerator
-
- //classes is ICodes.classes, a HashMap[Symbol, IClass]
- classes.values foreach codeGenerator.findEntryPoint
- if( settings.Xshowcls.isSetByUser && (codeGenerator.entryPoint == null) ) { // TODO introduce dedicated setting instead
- val entryclass = settings.Xshowcls.value.toString
- warning("Couldn't find entry class " + entryclass)
- }
-
- codeGenerator.initAssembly
-
- val classesSorted = classes.values.toList.sortBy(c => c.symbol.id) // simplifies comparing cross-compiler vs. .exe output
- classesSorted foreach codeGenerator.createTypeBuilder
- classesSorted foreach codeGenerator.createClassMembers
-
- try {
- classesSorted foreach codeGenerator.genClass
- } finally {
- codeGenerator.writeAssembly
- }
- }
-
- override def apply(unit: CompilationUnit) {
- abort("MSIL works on icode classes, not on compilation units!")
- }
- }
-
- /**
- * MSIL bytecode generator.
- *
- */
- class BytecodeGenerator {
-
- val MODULE_INSTANCE_NAME = "MODULE$"
-
- import clrTypes.{VOID => MVOID, BOOLEAN => MBOOL, BYTE => MBYTE, SHORT => MSHORT,
- CHAR => MCHAR, INT => MINT, LONG => MLONG, FLOAT => MFLOAT,
- DOUBLE => MDOUBLE, OBJECT => MOBJECT, STRING => MSTRING,
- STRING_ARRAY => MSTRING_ARRAY,
- SYMTAB_CONSTR => SYMTAB_ATTRIBUTE_CONSTRUCTOR,
- SYMTAB_DEFAULT_CONSTR => SYMTAB_ATTRIBUTE_EMPTY_CONSTRUCTOR}
-
- val EXCEPTION = clrTypes.getType("System.Exception")
- val MEMBERWISE_CLONE = MOBJECT.GetMethod("MemberwiseClone", MsilType.EmptyTypes)
-
- val MMONITOR = clrTypes.getType("System.Threading.Monitor")
- val MMONITOR_ENTER = MMONITOR.GetMethod("Enter", Array(MOBJECT))
- val MMONITOR_EXIT = MMONITOR.GetMethod("Exit", Array(MOBJECT))
-
- val MSTRING_BUILDER = clrTypes.getType("System.Text.StringBuilder")
- val MSTRING_BUILDER_CONSTR = MSTRING_BUILDER.GetConstructor(MsilType.EmptyTypes)
- val MSTRING_BUILDER_TOSTRING = MSTRING_BUILDER.GetMethod("ToString",
- MsilType.EmptyTypes)
-
- val TYPE_FROM_HANDLE =
- clrTypes.getType("System.Type").GetMethod("GetTypeFromHandle", Array(clrTypes.getType("System.RuntimeTypeHandle")))
-
- val INT_PTR = clrTypes.getType("System.IntPtr")
-
- val SystemConvert = clrTypes.getType("System.Convert")
-
- val objParam = Array(MOBJECT)
-
- val toBool: MethodInfo = SystemConvert.GetMethod("ToBoolean", objParam) // see comment in emitUnbox
- val toSByte: MethodInfo = SystemConvert.GetMethod("ToSByte", objParam)
- val toShort: MethodInfo = SystemConvert.GetMethod("ToInt16", objParam)
- val toChar: MethodInfo = SystemConvert.GetMethod("ToChar", objParam)
- val toInt: MethodInfo = SystemConvert.GetMethod("ToInt32", objParam)
- val toLong: MethodInfo = SystemConvert.GetMethod("ToInt64", objParam)
- val toFloat: MethodInfo = SystemConvert.GetMethod("ToSingle", objParam)
- val toDouble: MethodInfo = SystemConvert.GetMethod("ToDouble", objParam)
-
- //val boxedUnit: FieldInfo = msilType(definitions.BoxedUnitModule.info).GetField("UNIT")
- val boxedUnit: FieldInfo = fields(definitions.BoxedUnit_UNIT)
-
- // Scala attributes
- // symtab.Definitions -> object (singleton..)
- val CloneableAttr = definitions.CloneableAttr.tpe
- val TransientAtt = definitions.TransientAttr.tpe
- // remoting: the architectures are too different, no mapping (no portable code
- // possible)
-
- // java instance methods that are mapped to static methods in .net
- // these will need to be called with OpCodes.Call (not Callvirt)
- val dynToStatMapped = mutable.HashSet[Symbol]()
-
- initMappings()
-
- /** Create the mappings between java and .net classes and methods */
- private def initMappings() {
- mapType(definitions.AnyClass, MOBJECT)
- mapType(definitions.AnyRefClass, MOBJECT)
- //mapType(definitions.NullClass, clrTypes.getType("scala.AllRef$"))
- //mapType(definitions.NothingClass, clrTypes.getType("scala.All$"))
- // FIXME: for some reason the upper two lines map to null
- mapType(definitions.NullClass, EXCEPTION)
- mapType(definitions.NothingClass, EXCEPTION)
-
- mapType(definitions.BooleanClass, MBOOL)
- mapType(definitions.ByteClass, MBYTE)
- mapType(definitions.ShortClass, MSHORT)
- mapType(definitions.CharClass, MCHAR)
- mapType(definitions.IntClass, MINT)
- mapType(definitions.LongClass, MLONG)
- mapType(definitions.FloatClass, MFLOAT)
- mapType(definitions.DoubleClass, MDOUBLE)
- }
-
- var clasz: IClass = _
- var method: IMethod = _
-
- var massembly: AssemblyBuilder = _
- var mmodule: ModuleBuilder = _
- var mcode: ILGenerator = _
-
- var assemName: String = _
- var firstSourceName = ""
- var outDir: File = _
- var srcPath: File = _
- var moduleName: String = _
-
- def initAssembly() {
-
- assemName = settings.assemname.value
-
- if (assemName == "") {
- if (entryPoint != null) {
- assemName = msilName(entryPoint.enclClass)
- // remove the $ at the end (from module-name)
- assemName = assemName.substring(0, assemName.length() - 1)
- } else {
- // assuming filename of first source file
- assert(firstSourceName.endsWith(".scala"), firstSourceName)
- assemName = firstSourceName.substring(0, firstSourceName.length() - 6)
- }
- } else {
- if (assemName.endsWith(".msil"))
- assemName = assemName.substring(0, assemName.length()-5)
- if (assemName.endsWith(".il"))
- assemName = assemName.substring(0, assemName.length()-3)
- val f: File = new File(assemName)
- assemName = f.getName()
- }
-
- outDir = new File(settings.outdir.value)
-
- srcPath = new File(settings.sourcedir.value)
-
- val assemblyName = new AssemblyName()
- assemblyName.Name = assemName
- massembly = AssemblyBuilderFactory.DefineDynamicAssembly(assemblyName)
-
- moduleName = assemName // + (if (entryPoint == null) ".dll" else ".exe")
- // filename here: .dll or .exe (in both parameters), second: give absolute-path
- mmodule = massembly.DefineDynamicModule(moduleName,
- new File(outDir, moduleName).getAbsolutePath())
- assert (mmodule != null)
- }
-
-
- /**
- * Form of the custom Attribute parameter (Ecma-335.pdf)
- * - p. 163 for CustomAttrib Form,
- * - p. 164 for FixedArg Form (Array and Element) (if array or not is known!)
- * !! least significant byte first if values longer than one byte !!
- *
- * 1: Prolog (unsigned int16, value 0x0001) -> symtab[0] = 0x01, symtab[1] = 0x00
- * 2: FixedArgs (directly the data, get number and types from related constructor)
- * 2.1: length of the array (unsigned int32, 4 bytes, least significant first)
- * 2.2: the byte array data
- * 3: NumNamed (unsigned int16, number of named fields and properties, 0x0000)
- */
- def addSymtabAttribute(sym: Symbol, tBuilder: TypeBuilder) {
- def addMarker() {
- val markerSymtab = new Array[Byte](4)
- markerSymtab(0) = 1.toByte
- tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_EMPTY_CONSTRUCTOR, markerSymtab)
- }
-
- // both conditions are needed (why exactly..?)
- if (tBuilder.Name.endsWith("$") || sym.isModuleClass) {
- addMarker()
- } else {
- currentRun.symData.get(sym) match {
- case Some(pickle) =>
- var size = pickle.writeIndex
- val symtab = new Array[Byte](size + 8)
- symtab(0) = 1.toByte
- for (i <- 2 until 6) {
- symtab(i) = (size & 0xff).toByte
- size = size >> 8
- }
- java.lang.System.arraycopy(pickle.bytes, 0, symtab, 6, pickle.writeIndex)
-
- tBuilder.SetCustomAttribute(SYMTAB_ATTRIBUTE_CONSTRUCTOR, symtab)
-
- currentRun.symData -= sym
- currentRun.symData -= sym.companionSymbol
-
- case _ =>
- addMarker()
- }
- }
- }
-
- /**
- * Mutates `member` adding CLR attributes (if any) based on sym.annotations.
- * Please notice that CLR custom modifiers are a different beast (see customModifiers below)
- * and thus shouldn't be added by this method.
- */
- def addAttributes(member: ICustomAttributeSetter, annotations: List[AnnotationInfo]) {
- // val attributes = annotations.map(_.atp.typeSymbol).collect {
- // case definitions.TransientAttr => null // TODO this is just an example
- // }
- return // TODO: implement at some point
- }
-
- /**
- * What's a CLR custom modifier? Intro available as source comments in compiler.msil.CustomModifier.
- * It's basically a marker associated with a location (think of FieldInfo, ParameterInfo, and PropertyInfo)
- * and thus that marker (be it optional or required) becomes part of the signature of that location.
- * Some annotations will become CLR attributes (see addAttributes above), others custom modifiers (this method).
- */
- def customModifiers(annotations: List[AnnotationInfo]): Array[CustomModifier] = {
- annotations.map(_.atp.typeSymbol).collect {
- case definitions.VolatileAttr => new CustomModifier(true, CustomModifier.VolatileMarker)
- } toArray
- }
-
-
-
- /*
- debuglog("creating annotations: " + annotations + " for member : " + member)
- for (annot@ AnnotationInfo(typ, annArgs, nvPairs) <- annotations ;
- if annot.isConstant)
- //!typ.typeSymbol.isJavaDefined
- {
-// assert(consts.length <= 1,
-// "too many constant arguments for annotations; "+consts.toString())
-
- // Problem / TODO having the symbol of the annotations type would be nicer
- // (i hope that type.typeSymbol is the same as the one in types2create)
- // AND: this will crash if the annotations Type is already compiled (-> not a typeBuilder)
- // when this is solved, types2create will be the same as icodes.classes, thus superfluous
- val annType: TypeBuilder = getType(typ.typeSymbol).asInstanceOf[TypeBuilder]
-// val annType: MsilType = getType(typ.typeSymbol)
-
- // Problem / TODO: i have no idea which constructor is used. This
- // information should be available in AnnotationInfo.
- annType.CreateType() // else, GetConstructors can't be used
- val constr: ConstructorInfo = annType.GetConstructors()(0)
- // prevent a second call of CreateType, only needed because there's no
- // other way than GetConstructors()(0) to get the constructor, if there's
- // no constructor symbol available.
-
- val args: Array[Byte] =
- getAttributeArgs(
- annArgs map (_.constant.get),
- (for((n,v) <- nvPairs) yield (n, v.constant.get)))
- member.SetCustomAttribute(constr, args)
- }
- } */
-
-/* def getAttributeArgs(consts: List[Constant], nvPairs: List[(Name, Constant)]): Array[Byte] = {
- val buf = ByteBuffer.allocate(2048) // FIXME: this may be not enough!
- buf.order(java.nio.ByteOrder.LITTLE_ENDIAN)
- buf.putShort(1.toShort) // signature
-
- def emitSerString(str: String) = {
- // this is wrong, it has to be the length of the UTF-8 byte array, which
- // may be longer (see clr-book on page 302)
-// val length: Int = str.length
- val strBytes: Array[Byte] = try {
- str.getBytes("UTF-8")
- } catch {
- case _: Error => abort("could not get byte-array for string: " + str)
- }
- val length: Int = strBytes.length //this length is stored big-endian
- if (length < 128)
- buf.put(length.toByte)
- else if (length < (1<<14)) {
- buf.put(((length >> 8) | 0x80).toByte) // the bits 14 and 15 of length are '0'
- buf.put((length | 0xff).toByte)
- } else if (length < (1 << 29)) {
- buf.put(((length >> 24) | 0xc0).toByte)
- buf.put(((length >> 16) & 0xff).toByte)
- buf.put(((length >> 8) & 0xff).toByte)
- buf.put(((length ) & 0xff).toByte)
- } else
- abort("string too long for attribute parameter: " + length)
- buf.put(strBytes)
- }
-
- def emitConst(const: Constant): Unit = const.tag match {
- case BooleanTag => buf.put((if (const.booleanValue) 1 else 0).toByte)
- case ByteTag => buf.put(const.byteValue)
- case ShortTag => buf.putShort(const.shortValue)
- case CharTag => buf.putChar(const.charValue)
- case IntTag => buf.putInt(const.intValue)
- case LongTag => buf.putLong(const.longValue)
- case FloatTag => buf.putFloat(const.floatValue)
- case DoubleTag => buf.putDouble(const.doubleValue)
- case StringTag =>
- val str: String = const.stringValue
- if (str == null) {
- buf.put(0xff.toByte)
- } else {
- emitSerString(str)
- }
- case ArrayTag =>
- val arr: Array[Constant] = const.arrayValue
- if (arr == null) {
- buf.putInt(0xffffffff)
- } else {
- buf.putInt(arr.length)
- arr.foreach(emitConst)
- }
-
- // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag, ArrayTag ???
-
- case _ => abort("could not handle attribute argument: " + const)
- }
-
- consts foreach emitConst
- buf.putShort(nvPairs.length.toShort)
- def emitNamedArg(nvPair: (Name, Constant)) {
- // the named argument is a property of the attribute (it can't be a field, since
- // all fields in scala are private)
- buf.put(0x54.toByte)
-
- def emitType(c: Constant) = c.tag match { // type of the constant, Ecma-335.pdf, page 151
- case BooleanTag => buf.put(0x02.toByte)
- case ByteTag => buf.put(0x05.toByte)
- case ShortTag => buf.put(0x06.toByte)
- case CharTag => buf.put(0x07.toByte)
- case IntTag => buf.put(0x08.toByte)
- case LongTag => buf.put(0x0a.toByte)
- case FloatTag => buf.put(0x0c.toByte)
- case DoubleTag => buf.put(0x0d.toByte)
- case StringTag => buf.put(0x0e.toByte)
-
- // TODO: other Tags: NoTag, UnitTag, ClazzTag, EnumTag ???
-
- // ArrayTag falls in here
- case _ => abort("could not handle attribute argument: " + c)
- }
-
- val cnst: Constant = nvPair._2
- if (cnst.tag == ArrayTag) {
- buf.put(0x1d.toByte)
- emitType(cnst.arrayValue(0)) // FIXME: will crash if array length = 0
- } else if (cnst.tag == EnumTag) {
- buf.put(0x55.toByte)
- // TODO: put a SerString (don't know what exactly, names of the enums somehow..)
- } else {
- buf.put(0x51.toByte)
- emitType(cnst)
- }
-
- emitSerString(nvPair._1.toString)
- emitConst(nvPair._2)
- }
-
- val length = buf.position()
- buf.array().slice(0, length)
- } */
-
- def writeAssembly() {
- if (entryPoint != null) {
- assert(entryPoint.enclClass.isModuleClass, entryPoint.enclClass)
- val mainMethod = methods(entryPoint)
- val stringArrayTypes: Array[MsilType] = Array(MSTRING_ARRAY)
- val globalMain = mmodule.DefineGlobalMethod(
- "Main", MethodAttributes.Public | MethodAttributes.Static,
- MVOID, stringArrayTypes)
- globalMain.DefineParameter(0, ParameterAttributes.None, "args")
- massembly.SetEntryPoint(globalMain)
- val code = globalMain.GetILGenerator()
- val moduleField = getModuleInstanceField(entryPoint.enclClass)
- code.Emit(OpCodes.Ldsfld, moduleField)
- code.Emit(OpCodes.Ldarg_0)
- code.Emit(OpCodes.Callvirt, mainMethod)
- code.Emit(OpCodes.Ret)
- }
- createTypes()
- var outDirName: String = null
- try {
- if (settings.Ygenjavap.isDefault) { // we reuse the JVM-sounding setting because it's conceptually similar
- outDirName = outDir.getPath()
- massembly.Save(outDirName + "\\" + assemName + ".msil") /* use SingleFileILPrinterVisitor */
- } else {
- outDirName = srcPath.getPath()
- massembly.Save(settings.Ygenjavap.value, outDirName) /* use MultipleFilesILPrinterVisitor */
- }
- } catch {
- case e:IOException => abort("Could not write to " + outDirName + ": " + e.getMessage())
- }
- }
-
- private def createTypes() {
- for (sym <- classes.keys) {
- val iclass = classes(sym)
- val tBuilder = types(sym).asInstanceOf[TypeBuilder]
-
- debuglog("Calling CreatType for " + sym + ", " + tBuilder.toString)
-
- tBuilder.CreateType()
- tBuilder.setSourceFilepath(iclass.cunit.source.file.path)
- }
- }
-
- private[GenMSIL] def ilasmFileName(iclass: IClass) : String = {
- // method.sourceFile contains just the filename
- iclass.cunit.source.file.toString.replace("\\", "\\\\")
- }
-
- private[GenMSIL] def genClass(iclass: IClass) {
- val sym = iclass.symbol
- debuglog("Generating class " + sym + " flags: " + sym.flagString)
- clasz = iclass
-
- val tBuilder = getType(sym).asInstanceOf[TypeBuilder]
- if (isCloneable(sym)) {
- // FIXME: why there's no nme.clone_ ?
- // "Clone": if the code is non-portable, "Clone" is defined, not "clone"
- // TODO: improve condition (should override AnyRef.clone)
- if (iclass.methods.forall(m => {
- !((m.symbol.name.toString != "clone" || m.symbol.name.toString != "Clone") &&
- m.symbol.tpe.paramTypes.length != 0)
- })) {
- debuglog("auto-generating cloneable method for " + sym)
- val attrs: Short = (MethodAttributes.Public | MethodAttributes.Virtual |
- MethodAttributes.HideBySig).toShort
- val cloneMethod = tBuilder.DefineMethod("Clone", attrs, MOBJECT,
- MsilType.EmptyTypes)
- val clCode = cloneMethod.GetILGenerator()
- clCode.Emit(OpCodes.Ldarg_0)
- clCode.Emit(OpCodes.Call, MEMBERWISE_CLONE)
- clCode.Emit(OpCodes.Ret)
- }
- }
-
- val line = sym.pos.line
- tBuilder.setPosition(line, ilasmFileName(iclass))
-
- if (isTopLevelModule(sym)) {
- if (sym.companionClass == NoSymbol)
- generateMirrorClass(sym)
- else
- log("No mirror class for module with linked class: " +
- sym.fullName)
- }
-
- addSymtabAttribute(sym, tBuilder)
- addAttributes(tBuilder, sym.annotations)
-
- if (iclass.symbol != definitions.ArrayClass)
- iclass.methods foreach genMethod
-
- } //genClass
-
-
- private def genMethod(m: IMethod) {
- debuglog("Generating method " + m.symbol + " flags: " + m.symbol.flagString +
- " owner: " + m.symbol.owner)
- method = m
- localBuilders.clear
- computeLocalVarsIndex(m)
-
- if (m.symbol.isClassConstructor) {
- mcode = constructors(m.symbol).asInstanceOf[ConstructorBuilder].GetILGenerator()
- } else {
- val mBuilder = methods(m.symbol).asInstanceOf[MethodBuilder]
- if (!mBuilder.IsAbstract())
- try {
- mcode = mBuilder.GetILGenerator()
- } catch {
- case e: Exception =>
- java.lang.System.out.println("m.symbol = " + m.symbol.flagString + " " + m.symbol)
- java.lang.System.out.println("m.symbol.owner = " + m.symbol.owner.flagString + " " + m.symbol.owner)
- java.lang.System.out.println("mBuilder = " + mBuilder)
- java.lang.System.out.println("mBuilder.DeclaringType = " +
- TypeAttributes.toString(mBuilder.DeclaringType.Attributes) +
- "::" + mBuilder.DeclaringType)
- throw e
- }
- else
- mcode = null
- }
-
- if (mcode != null) {
- for (local <- m.locals ; if !(m.params contains local)) {
- debuglog("add local var: " + local + ", of kind " + local.kind)
- val t: MsilType = msilType(local.kind)
- val localBuilder = mcode.DeclareLocal(t)
- localBuilder.SetLocalSymInfo(msilName(local.sym))
- localBuilders(local) = localBuilder
- }
- genCode(m)
- }
-
- }
-
- /** Special linearizer for methods with at least one exception handler. This
- * linearizer brings all basic blocks in the right order so that nested
- * try-catch and try-finally blocks can be emitted.
- */
- val msilLinearizer = new MSILLinearizer()
-
- val labels = mutable.HashMap[BasicBlock, Label]()
-
- /* when emitting .line, it's enough to include the full filename just once per method, thus reducing filesize.
- * this scheme relies on the fact that the entry block is emitted first. */
- var dbFilenameSeen = false
-
- def genCode(m: IMethod) {
-
- def makeLabels(blocks: List[BasicBlock]) = {
- debuglog("Making labels for: " + method)
- for (bb <- blocks) labels(bb) = mcode.DefineLabel()
- }
-
- labels.clear
-
- var linearization = if(!m.exh.isEmpty) msilLinearizer.linearize(m)
- else linearizer.linearize(m)
-
- if (!m.exh.isEmpty)
- linearization = computeExceptionMaps(linearization, m)
-
- makeLabels(linearization)
-
- // debug val blocksInM = m.code.blocks.toList.sortBy(bb => bb.label)
- // debug val blocksInL = linearization.sortBy(bb => bb.label)
- // debug val MButNotL = (blocksInM.toSet) diff (blocksInL.toSet) // if non-empty, a jump to B fails to find a label for B (case CJUMP, case CZJUMP)
- // debug if(!MButNotL.isEmpty) { }
-
- dbFilenameSeen = false
- genBlocks(linearization)
-
- // RETURN inside exception blocks are replaced by Leave. The target of the
- // leave is a `Ret` outside any exception block (generated here).
- if (handlerReturnMethod == m) {
- mcode.MarkLabel(handlerReturnLabel)
- if (handlerReturnKind != UNIT)
- mcode.Emit(OpCodes.Ldloc, handlerReturnLocal)
- mcode.Emit(OpCodes.Ret)
- }
-
- beginExBlock.clear()
- beginCatchBlock.clear()
- endExBlock.clear()
- endFinallyLabels.clear()
- }
-
- def genBlocks(blocks: List[BasicBlock], previous: BasicBlock = null) {
- blocks match {
- case Nil => ()
- case x :: Nil => genBlock(x, prev = previous, next = null)
- case x :: y :: ys => genBlock(x, prev = previous, next = y); genBlocks(y :: ys, previous = x)
- }
- }
-
- // the try blocks starting at a certain BasicBlock
- val beginExBlock = mutable.HashMap[BasicBlock, List[ExceptionHandler]]()
-
- // the catch blocks starting / endling at a certain BasicBlock
- val beginCatchBlock = mutable.HashMap[BasicBlock, ExceptionHandler]()
- val endExBlock = mutable.HashMap[BasicBlock, List[ExceptionHandler]]()
-
- /** When emitting the code (genBlock), the number of currently active try / catch
- * blocks. When seeing a `RETURN` inside a try / catch, we need to
- * - store the result in a local (if it's not UNIT)
- * - emit `Leave handlerReturnLabel` instead of the Return
- * - emit code at the end: load the local and return its value
- */
- val currentHandlers = new mutable.Stack[ExceptionHandler]
- // The IMethod the Local/Label/Kind below belong to
- var handlerReturnMethod: IMethod = _
- // Stores the result when returning inside an exception block
- var handlerReturnLocal: LocalBuilder = _
- // Label for a return instruction outside any exception block
- var handlerReturnLabel: Label = _
- // The result kind.
- var handlerReturnKind: TypeKind = _
- def returnFromHandler(kind: TypeKind): (LocalBuilder, Label) = {
- if (handlerReturnMethod != method) {
- handlerReturnMethod = method
- if (kind != UNIT) {
- handlerReturnLocal = mcode.DeclareLocal(msilType(kind))
- handlerReturnLocal.SetLocalSymInfo("$handlerReturn")
- }
- handlerReturnLabel = mcode.DefineLabel()
- handlerReturnKind = kind
- }
- (handlerReturnLocal, handlerReturnLabel)
- }
-
- /** For try/catch nested inside a finally, we can't use `Leave OutsideFinally`, the
- * Leave target has to be inside the finally (and it has to be the `endfinally` instruction).
- * So for every finalizer, we have a label which marks the place of the `endfinally`,
- * nested try/catch blocks will leave there.
- */
- val endFinallyLabels = mutable.HashMap[ExceptionHandler, Label]()
-
- /** Computes which blocks are the beginning / end of a try or catch block */
- private def computeExceptionMaps(blocks: List[BasicBlock], m: IMethod): List[BasicBlock] = {
- val visitedBlocks = new mutable.HashSet[BasicBlock]()
-
- // handlers which have not been introduced so far
- var openHandlers = m.exh
-
-
- /** Example
- * try {
- * try {
- * // *1*
- * } catch {
- * case h1 =>
- * }
- * } catch {
- * case h2 =>
- * case h3 =>
- * try {
- *
- * } catch {
- * case h4 => // *2*
- * case h5 =>
- * }
- * }
- */
-
- // Stack of nested try blocks. Each bloc has a List of ExceptionHandler (multiple
- // catch statements). Example *1*: Stack(List(h2, h3), List(h1))
- val currentTryHandlers = new mutable.Stack[List[ExceptionHandler]]()
-
- // Stack of nested catch blocks. The head of the list is the current catch block. The
- // tail is all following catch blocks. Example *2*: Stack(List(h3), List(h4, h5))
- val currentCatchHandlers = new mutable.Stack[List[ExceptionHandler]]()
-
- for (b <- blocks) {
-
- // are we past the current catch blocks?
- def endHandlers(): List[ExceptionHandler] = {
- var res: List[ExceptionHandler] = Nil
- if (!currentCatchHandlers.isEmpty) {
- val handler = currentCatchHandlers.top.head
- if (!handler.blocks.contains(b)) {
- // all blocks of the handler are either visited, or not part of the linearization (i.e. dead)
- assert(handler.blocks.forall(b => visitedBlocks.contains(b) || !blocks.contains(b)),
- "Bad linearization of basic blocks inside catch. Found block not part of the handler\n"+
- b.fullString +"\nwhile in catch-part of\n"+ handler)
-
- val rest = currentCatchHandlers.pop.tail
- if (rest.isEmpty) {
- // all catch blocks of that exception handler are covered
- res = handler :: endHandlers()
- } else {
- // there are more catch blocks for that try (handlers covering the same)
- currentCatchHandlers.push(rest)
- beginCatchBlock(b) = rest.head
- }
- }
- }
- res
- }
- val end = endHandlers()
- if (!end.isEmpty) endExBlock(b) = end
-
- // are we past the current try block?
- if (!currentTryHandlers.isEmpty) {
- val handler = currentTryHandlers.top.head
- if (!handler.covers(b)) {
- // all of the covered blocks are visited, or not part of the linearization
- assert(handler.covered.forall(b => visitedBlocks.contains(b) || !blocks.contains(b)),
- "Bad linearization of basic blocks inside try. Found non-covered block\n"+
- b.fullString +"\nwhile in try-part of\n"+ handler)
-
- assert(handler.startBlock == b,
- "Bad linearization of basic blocks. The entry block of a catch does not directly follow the try\n"+
- b.fullString +"\n"+ handler)
-
- val handlers = currentTryHandlers.pop
- currentCatchHandlers.push(handlers)
- beginCatchBlock(b) = handler
- }
- }
-
- // are there try blocks starting at b?
- val (newHandlers, stillOpen) = openHandlers.partition(_.covers(b))
- openHandlers = stillOpen
-
- val newHandlersBySize = newHandlers.groupBy(_.covered.size)
- // big handlers first, smaller ones are nested inside the try of the big one
- // (checked by the assertions below)
- val sizes = newHandlersBySize.keys.toList.sortWith(_ > _)
-
- val beginHandlers = new mutable.ListBuffer[ExceptionHandler]
- for (s <- sizes) {
- val sHandlers = newHandlersBySize(s)
- for (h <- sHandlers) {
- assert(h.covered == sHandlers.head.covered,
- "bad nesting of exception handlers. same size, but not covering same blocks\n"+
- h +"\n"+ sHandlers.head)
- assert(h.resultKind == sHandlers.head.resultKind,
- "bad nesting of exception handlers. same size, but the same resultKind\n"+
- h +"\n"+ sHandlers.head)
- }
- for (bigger <- beginHandlers; h <- sHandlers) {
- assert(h.covered.subsetOf(bigger.covered),
- "bad nesting of exception handlers. try blocks of smaller handler are not nested in bigger one.\n"+
- h +"\n"+ bigger)
- assert(h.blocks.toSet.subsetOf(bigger.covered),
- "bad nesting of exception handlers. catch blocks of smaller handler are not nested in bigger one.\n"+
- h +"\n"+ bigger)
- }
- beginHandlers += sHandlers.head
- currentTryHandlers.push(sHandlers)
- }
- beginExBlock(b) = beginHandlers.toList
- visitedBlocks += b
- }
-
- // if there handlers left (i.e. handlers covering nothing, or a
- // non-existent (dead) block), remove their catch-blocks.
- val liveBlocks = if (openHandlers.isEmpty) blocks else {
- blocks.filter(b => openHandlers.forall(h => !h.blocks.contains(b)))
- }
-
- /** There might be open handlers, but no more blocks. happens when try/catch end
- * with `throw` or `return`
- * def foo() { try { .. throw } catch { _ => .. throw } }
- *
- * In this case we need some code after the catch block for the auto-generated
- * `leave` instruction. So we're adding a (dead) `throw new Exception`.
- */
- val rest = currentCatchHandlers.map(handlers => {
- assert(handlers.length == 1, handlers)
- handlers.head
- }).toList
-
- if (rest.isEmpty) {
- liveBlocks
- } else {
- val b = m.code.newBlock
- b.emit(Seq(
- NEW(REFERENCE(definitions.ThrowableClass)),
- DUP(REFERENCE(definitions.ObjectClass)),
- CALL_METHOD(definitions.ThrowableClass.primaryConstructor, Static(true)),
- THROW(definitions.ThrowableClass)
- ))
- b.close
- endExBlock(b) = rest
- liveBlocks ::: List(b)
- }
- }
-
- /**
- * @param block the BasicBlock to emit code for
- * @param next the following BasicBlock, `null` if `block` is the last one
- */
- def genBlock(block: BasicBlock, prev: BasicBlock, next: BasicBlock) {
-
- def loadLocalOrAddress(local: Local, msg : String , loadAddr : Boolean) {
- debuglog(msg + " for " + local)
- val isArg = local.arg
- val i = local.index
- if (isArg)
- loadArg(mcode, loadAddr)(i)
- else
- loadLocal(i, local, mcode, loadAddr)
- }
-
- def loadFieldOrAddress(field: Symbol, isStatic: Boolean, msg: String, loadAddr : Boolean) {
- debuglog(msg + " with owner: " + field.owner +
- " flags: " + field.owner.flagString)
- val fieldInfo = fields.get(field) match {
- case Some(fInfo) => fInfo
- case None =>
- val fInfo = getType(field.owner).GetField(msilName(field))
- fields(field) = fInfo
- fInfo
- }
- if (fieldInfo.IsVolatile) {
- mcode.Emit(OpCodes.Volatile)
- }
- if (!fieldInfo.IsLiteral) {
- if (loadAddr) {
- mcode.Emit(if (isStatic) OpCodes.Ldsflda else OpCodes.Ldflda, fieldInfo)
- } else {
- mcode.Emit(if (isStatic) OpCodes.Ldsfld else OpCodes.Ldfld, fieldInfo)
- }
- } else {
- assert(!loadAddr, "can't take AddressOf a literal field (not even with readonly. prefix) because no memory was allocated to such field ...")
- // TODO the above can be overcome by loading the value, boxing, and finally unboxing. An address to a copy of the raw value will be on the stack.
- /* We perform `field inlining' as required by CLR.
- * Emit as for a CONSTANT ICode stmt, with the twist that the constant value is available
- * as a java.lang.Object and its .NET type allows constant initialization in CLR, i.e. that type
- * is one of I1, I2, I4, I8, R4, R8, CHAR, BOOLEAN, STRING, or CLASS (in this last case,
- * only accepting nullref as value). See Table 9-1 in Lidin's book on ILAsm. */
- val value = fieldInfo.getValue()
- if (value == null) {
- mcode.Emit(OpCodes.Ldnull)
- } else {
- val typ = if (fieldInfo.FieldType.IsEnum) fieldInfo.FieldType.getUnderlyingType
- else fieldInfo.FieldType
- if (typ == clrTypes.STRING) {
- mcode.Emit(OpCodes.Ldstr, value.asInstanceOf[String])
- } else if (typ == clrTypes.BOOLEAN) {
- mcode.Emit(if (value.asInstanceOf[Boolean]) OpCodes.Ldc_I4_1
- else OpCodes.Ldc_I4_0)
- } else if (typ == clrTypes.BYTE || typ == clrTypes.UBYTE) {
- loadI4(value.asInstanceOf[Byte], mcode)
- } else if (typ == clrTypes.SHORT || typ == clrTypes.USHORT) {
- loadI4(value.asInstanceOf[Int], mcode)
- } else if (typ == clrTypes.CHAR) {
- loadI4(value.asInstanceOf[Char], mcode)
- } else if (typ == clrTypes.INT || typ == clrTypes.UINT) {
- loadI4(value.asInstanceOf[Int], mcode)
- } else if (typ == clrTypes.LONG || typ == clrTypes.ULONG) {
- mcode.Emit(OpCodes.Ldc_I8, value.asInstanceOf[Long])
- } else if (typ == clrTypes.FLOAT) {
- mcode.Emit(OpCodes.Ldc_R4, value.asInstanceOf[Float])
- } else if (typ == clrTypes.DOUBLE) {
- mcode.Emit(OpCodes.Ldc_R8, value.asInstanceOf[Double])
- } else {
- /* TODO one more case is described in Partition II, 16.2: bytearray(...) */
- abort("Unknown type for static literal field: " + fieldInfo)
- }
- }
- }
- }
-
- /** Creating objects works differently on .NET. On the JVM
- * - NEW(type) => reference on Stack
- * - DUP, load arguments, CALL_METHOD(constructor)
- *
- * On .NET, the NEW and DUP are ignored, but we emit a special method call
- * - load arguments
- * - NewObj(constructor) => reference on stack
- *
- * This variable tells whether the previous instruction was a NEW,
- * we expect a DUP which is not emitted. */
- var previousWasNEW = false
-
- var lastLineNr: Int = 0
- var lastPos: Position = NoPosition
-
-
- // EndExceptionBlock must happen before MarkLabel because it adds the
- // Leave instruction. Otherwise, labels(block) points to the Leave
- // (inside the catch) instead of the instruction afterwards.
- for (handlers <- endExBlock.get(block); exh <- handlers) {
- currentHandlers.pop()
- for (l <- endFinallyLabels.get(exh))
- mcode.MarkLabel(l)
- mcode.EndExceptionBlock()
- }
-
- mcode.MarkLabel(labels(block))
- debuglog("Generating code for block: " + block)
-
- for (handler <- beginCatchBlock.get(block)) {
- if (!currentHandlers.isEmpty && currentHandlers.top.covered == handler.covered) {
- currentHandlers.pop()
- currentHandlers.push(handler)
- }
- if (handler.cls == NoSymbol) {
- // `finally` blocks are represented the same as `catch`, but with no catch-type
- mcode.BeginFinallyBlock()
- } else {
- val t = getType(handler.cls)
- mcode.BeginCatchBlock(t)
- }
- }
- for (handlers <- beginExBlock.get(block); exh <- handlers) {
- currentHandlers.push(exh)
- mcode.BeginExceptionBlock()
- }
-
- for (instr <- block) {
- try {
- val currentLineNr = instr.pos.line
- val skip = if(instr.pos.isRange) instr.pos.sameRange(lastPos) else (currentLineNr == lastLineNr);
- if(!skip || !dbFilenameSeen) {
- val fileName = if(dbFilenameSeen) "" else {dbFilenameSeen = true; ilasmFileName(clasz)};
- if(instr.pos.isRange) {
- val startLine = instr.pos.focusStart.line
- val endLine = instr.pos.focusEnd.line
- val startCol = instr.pos.focusStart.column
- val endCol = instr.pos.focusEnd.column
- mcode.setPosition(startLine, endLine, startCol, endCol, fileName)
- } else {
- mcode.setPosition(instr.pos.line, fileName)
- }
- lastLineNr = currentLineNr
- lastPos = instr.pos
- }
- } catch { case _: UnsupportedOperationException => () }
-
- if (previousWasNEW)
- assert(instr.isInstanceOf[DUP], block)
-
- instr match {
- case THIS(clasz) =>
- mcode.Emit(OpCodes.Ldarg_0)
-
- case CONSTANT(const) =>
- const.tag match {
- case UnitTag => ()
- case BooleanTag => mcode.Emit(if (const.booleanValue) OpCodes.Ldc_I4_1
- else OpCodes.Ldc_I4_0)
- case ByteTag => loadI4(const.byteValue, mcode)
- case ShortTag => loadI4(const.shortValue, mcode)
- case CharTag => loadI4(const.charValue, mcode)
- case IntTag => loadI4(const.intValue, mcode)
- case LongTag => mcode.Emit(OpCodes.Ldc_I8, const.longValue)
- case FloatTag => mcode.Emit(OpCodes.Ldc_R4, const.floatValue)
- case DoubleTag => mcode.Emit(OpCodes.Ldc_R8, const.doubleValue)
- case StringTag => mcode.Emit(OpCodes.Ldstr, const.stringValue)
- case NullTag => mcode.Emit(OpCodes.Ldnull)
- case ClazzTag =>
- mcode.Emit(OpCodes.Ldtoken, msilType(const.typeValue))
- mcode.Emit(OpCodes.Call, TYPE_FROM_HANDLE)
- case _ => abort("Unknown constant value: " + const)
- }
-
- case LOAD_ARRAY_ITEM(kind) =>
- (kind: @unchecked) match {
- case BOOL => mcode.Emit(OpCodes.Ldelem_I1)
- case BYTE => mcode.Emit(OpCodes.Ldelem_I1) // I1 for System.SByte, i.e. a scala.Byte
- case SHORT => mcode.Emit(OpCodes.Ldelem_I2)
- case CHAR => mcode.Emit(OpCodes.Ldelem_U2)
- case INT => mcode.Emit(OpCodes.Ldelem_I4)
- case LONG => mcode.Emit(OpCodes.Ldelem_I8)
- case FLOAT => mcode.Emit(OpCodes.Ldelem_R4)
- case DOUBLE => mcode.Emit(OpCodes.Ldelem_R8)
- case REFERENCE(cls) => mcode.Emit(OpCodes.Ldelem_Ref)
- case ARRAY(elem) => mcode.Emit(OpCodes.Ldelem_Ref)
-
- // case UNIT is not possible: an Array[Unit] will be an
- // Array[scala.runtime.BoxedUnit] (-> case REFERENCE)
- }
-
- case LOAD_LOCAL(local) => loadLocalOrAddress(local, "load_local", false)
-
- case CIL_LOAD_LOCAL_ADDRESS(local) => loadLocalOrAddress(local, "cil_load_local_address", true)
-
- case LOAD_FIELD(field, isStatic) => loadFieldOrAddress(field, isStatic, "load_field", false)
-
- case CIL_LOAD_FIELD_ADDRESS(field, isStatic) => loadFieldOrAddress(field, isStatic, "cil_load_field_address", true)
-
- case CIL_LOAD_ARRAY_ITEM_ADDRESS(kind) => mcode.Emit(OpCodes.Ldelema, msilType(kind))
-
- case CIL_NEWOBJ(msym) =>
- assert(msym.isClassConstructor)
- val constructorInfo: ConstructorInfo = getConstructor(msym)
- mcode.Emit(OpCodes.Newobj, constructorInfo)
-
- case LOAD_MODULE(module) =>
- debuglog("Generating LOAD_MODULE for: " + showsym(module))
- mcode.Emit(OpCodes.Ldsfld, getModuleInstanceField(module))
-
- case STORE_ARRAY_ITEM(kind) =>
- (kind: @unchecked) match {
- case BOOL => mcode.Emit(OpCodes.Stelem_I1)
- case BYTE => mcode.Emit(OpCodes.Stelem_I1)
- case SHORT => mcode.Emit(OpCodes.Stelem_I2)
- case CHAR => mcode.Emit(OpCodes.Stelem_I2)
- case INT => mcode.Emit(OpCodes.Stelem_I4)
- case LONG => mcode.Emit(OpCodes.Stelem_I8)
- case FLOAT => mcode.Emit(OpCodes.Stelem_R4)
- case DOUBLE => mcode.Emit(OpCodes.Stelem_R8)
- case REFERENCE(cls) => mcode.Emit(OpCodes.Stelem_Ref)
- case ARRAY(elem) => mcode.Emit(OpCodes.Stelem_Ref) // @TODO: test this! (occurs when calling a Array[Object]* vararg param method)
-
- // case UNIT not possible (see comment at LOAD_ARRAY_ITEM)
- }
-
- case STORE_LOCAL(local) =>
- val isArg = local.arg
- val i = local.index
- debuglog("store_local for " + local + ", index " + i)
-
- // there are some locals defined by the compiler that
- // are isArg and are need to be stored.
- if (isArg) {
- if (i >= -128 && i <= 127)
- mcode.Emit(OpCodes.Starg_S, i)
- else
- mcode.Emit(OpCodes.Starg, i)
- } else {
- i match {
- case 0 => mcode.Emit(OpCodes.Stloc_0)
- case 1 => mcode.Emit(OpCodes.Stloc_1)
- case 2 => mcode.Emit(OpCodes.Stloc_2)
- case 3 => mcode.Emit(OpCodes.Stloc_3)
- case _ =>
- if (i >= -128 && i <= 127)
- mcode.Emit(OpCodes.Stloc_S, localBuilders(local))
- else
- mcode.Emit(OpCodes.Stloc, localBuilders(local))
- }
- }
-
- case STORE_THIS(_) =>
- // this only works for impl classes because the self parameter comes first
- // in the method signature. If that changes, this code has to be revisited.
- mcode.Emit(OpCodes.Starg_S, 0)
-
- case STORE_FIELD(field, isStatic) =>
- val fieldInfo = fields.get(field) match {
- case Some(fInfo) => fInfo
- case None =>
- val fInfo = getType(field.owner).GetField(msilName(field))
- fields(field) = fInfo
- fInfo
- }
- mcode.Emit(if (isStatic) OpCodes.Stsfld else OpCodes.Stfld, fieldInfo)
-
- case CALL_PRIMITIVE(primitive) =>
- genPrimitive(primitive, instr.pos)
-
- case CALL_METHOD(msym, style) =>
- if (msym.isClassConstructor) {
- val constructorInfo: ConstructorInfo = getConstructor(msym)
- (style: @unchecked) match {
- // normal constructor calls are Static..
- case Static(_) =>
- if (method.symbol.isClassConstructor && method.symbol.owner == msym.owner)
- // we're generating a constructor (method: IMethod is a constructor), and we're
- // calling another constructor of the same class.
-
- // @LUC TODO: this can probably break, namely when having: class A { def this() { new A() } }
- // instead, we should instruct the CALL_METHOD with additional information, know whether it's
- // an instance creation constructor call or not.
- mcode.Emit(OpCodes.Call, constructorInfo)
- else
- mcode.Emit(OpCodes.Newobj, constructorInfo)
- case SuperCall(_) =>
- mcode.Emit(OpCodes.Call, constructorInfo)
- if (isStaticModule(clasz.symbol) &&
- notInitializedModules.contains(clasz.symbol) &&
- method.symbol.isClassConstructor)
- {
- notInitializedModules -= clasz.symbol
- mcode.Emit(OpCodes.Ldarg_0)
- mcode.Emit(OpCodes.Stsfld, getModuleInstanceField(clasz.symbol))
- }
- }
-
- } else {
-
- var doEmit = true
- getTypeOpt(msym.owner) match {
- case Some(typ) if (typ.IsEnum) => {
- def negBool() = {
- mcode.Emit(OpCodes.Ldc_I4_0)
- mcode.Emit(OpCodes.Ceq)
- }
- doEmit = false
- val name = msym.name
- if (name eq nme.EQ) { mcode.Emit(OpCodes.Ceq) }
- else if (name eq nme.NE) { mcode.Emit(OpCodes.Ceq); negBool }
- else if (name eq nme.LT) { mcode.Emit(OpCodes.Clt) }
- else if (name eq nme.LE) { mcode.Emit(OpCodes.Cgt); negBool }
- else if (name eq nme.GT) { mcode.Emit(OpCodes.Cgt) }
- else if (name eq nme.GE) { mcode.Emit(OpCodes.Clt); negBool }
- else if (name eq nme.OR) { mcode.Emit(OpCodes.Or) }
- else if (name eq nme.AND) { mcode.Emit(OpCodes.And) }
- else if (name eq nme.XOR) { mcode.Emit(OpCodes.Xor) }
- else
- doEmit = true
- }
- case _ => ()
- }
-
- // method: implicit view(FunctionX[PType0, PType1, ...,PTypeN, ResType]):DelegateType
- val (isDelegateView, paramType, resType) = enteringTyper {
- msym.tpe match {
- case MethodType(params, resultType)
- if (params.length == 1 && msym.name == nme.view_) =>
- val paramType = params(0).tpe
- val isDel = definitions.isCorrespondingDelegate(resultType, paramType)
- (isDel, paramType, resultType)
- case _ => (false, null, null)
- }
- }
- if (doEmit && isDelegateView) {
- doEmit = false
- createDelegateCaller(paramType, resType)
- }
-
- if (doEmit &&
- (msym.name == nme.PLUS || msym.name == nme.MINUS)
- && clrTypes.isDelegateType(msilType(msym.owner.tpe)))
- {
- doEmit = false
- val methodInfo: MethodInfo = getMethod(msym)
- // call it as a static method, even if the compiler (symbol) thinks it's virtual
- mcode.Emit(OpCodes.Call, methodInfo)
- mcode.Emit(OpCodes.Castclass, msilType(msym.owner.tpe))
- }
-
- if (doEmit && definitions.Delegate_scalaCallers.contains(msym)) {
- doEmit = false
- val methodSym: Symbol = definitions.Delegate_scalaCallerTargets(msym)
- val delegateType: Type = msym.tpe match {
- case MethodType(_, retType) => retType
- case _ => abort("not a method type: " + msym.tpe)
- }
- val methodInfo: MethodInfo = getMethod(methodSym)
- val delegCtor = msilType(delegateType).GetConstructor(Array(MOBJECT, INT_PTR))
- if (methodSym.isStatic) {
- mcode.Emit(OpCodes.Ldftn, methodInfo)
- } else {
- mcode.Emit(OpCodes.Dup)
- mcode.Emit(OpCodes.Ldvirtftn, methodInfo)
- }
- mcode.Emit(OpCodes.Newobj, delegCtor)
- }
-
- if (doEmit) {
- val methodInfo: MethodInfo = getMethod(msym)
- (style: @unchecked) match {
- case SuperCall(_) =>
- mcode.Emit(OpCodes.Call, methodInfo)
- case Dynamic =>
- // methodInfo.DeclaringType is null for global methods
- val isValuetypeMethod = (methodInfo.DeclaringType ne null) && (methodInfo.DeclaringType.IsValueType)
- val isValuetypeVirtualMethod = isValuetypeMethod && (methodInfo.IsVirtual)
- if (dynToStatMapped(msym)) {
- mcode.Emit(OpCodes.Call, methodInfo)
- } else if (isValuetypeVirtualMethod) {
- mcode.Emit(OpCodes.Constrained, methodInfo.DeclaringType)
- mcode.Emit(OpCodes.Callvirt, methodInfo)
- } else if (isValuetypeMethod) {
- // otherwise error "Callvirt on a value type method" ensues
- mcode.Emit(OpCodes.Call, methodInfo)
- } else {
- mcode.Emit(OpCodes.Callvirt, methodInfo)
- }
- case Static(_) =>
- if(methodInfo.IsVirtual && !mcode.Ldarg0WasJustEmitted) {
- mcode.Emit(OpCodes.Callvirt, methodInfo)
- } else mcode.Emit(OpCodes.Call, methodInfo)
- }
- }
- }
-
- case BOX(boxType) =>
- emitBox(mcode, boxType)
-
- case UNBOX(boxType) =>
- emitUnbox(mcode, boxType)
-
- case CIL_UNBOX(boxType) =>
- mcode.Emit(OpCodes.Unbox, msilType(boxType))
-
- case CIL_INITOBJ(valueType) =>
- mcode.Emit(OpCodes.Initobj, msilType(valueType))
-
- case NEW(REFERENCE(cls)) =>
- // the next instruction must be a DUP, see comment on `var previousWasNEW`
- previousWasNEW = true
-
- // works also for arrays and reference-types
- case CREATE_ARRAY(elem, dims) =>
- // TODO: handle multi dimensional arrays
- assert(dims == 1, "Can't handle multi dimensional arrays")
- mcode.Emit(OpCodes.Newarr, msilType(elem))
-
- // works for arrays and reference-types
- case IS_INSTANCE(tpe) =>
- mcode.Emit(OpCodes.Isinst, msilType(tpe))
- mcode.Emit(OpCodes.Ldnull)
- mcode.Emit(OpCodes.Ceq)
- mcode.Emit(OpCodes.Ldc_I4_0)
- mcode.Emit(OpCodes.Ceq)
-
- // works for arrays and reference-types
- // part from the scala reference: "S <: T does not imply
- // Array[S] <: Array[T] in Scala. However, it is possible
- // to cast an array of S to an array of T if such a cast
- // is permitted in the host environment."
- case CHECK_CAST(tpknd) =>
- val tMSIL = msilType(tpknd)
- mcode.Emit(OpCodes.Castclass, tMSIL)
-
- // no SWITCH is generated when there's
- // - a default case ("case _ => ...") in the matching expr
- // - OR is used ("case 1 | 2 => ...")
- case SWITCH(tags, branches) =>
- // tags is List[List[Int]]; a list of integers for every label.
- // if the int on stack is 4, and 4 is in the second list => jump
- // to second label
- // branches is List[BasicBlock]
- // the labels to jump to (the last one is the default one)
-
- val switchLocal = mcode.DeclareLocal(MINT)
- // several switch variables will appear with the same name in the
- // assembly code, but this makes no truble
- switchLocal.SetLocalSymInfo("$switch_var")
-
- mcode.Emit(OpCodes.Stloc, switchLocal)
- var i = 0
- for (l <- tags) {
- val targetLabel = labels(branches(i))
- for (i <- l) {
- mcode.Emit(OpCodes.Ldloc, switchLocal)
- loadI4(i, mcode)
- mcode.Emit(OpCodes.Beq, targetLabel)
- }
- i += 1
- }
- val defaultTarget = labels(branches(i))
- if (next != branches(i))
- mcode.Emit(OpCodes.Br, defaultTarget)
-
- case JUMP(whereto) =>
- val (leaveHandler, leaveFinally, lfTarget) = leavesHandler(block, whereto)
- if (leaveHandler) {
- if (leaveFinally) {
- if (lfTarget.isDefined) mcode.Emit(OpCodes.Leave, lfTarget.get)
- else mcode.Emit(OpCodes.Endfinally)
- } else
- mcode.Emit(OpCodes.Leave, labels(whereto))
- } else if (next != whereto)
- mcode.Emit(OpCodes.Br, labels(whereto))
-
- case CJUMP(success, failure, cond, kind) =>
- // cond is TestOp (see Primitives.scala), and can take
- // values EQ, NE, LT, GE LE, GT
- // kind is TypeKind
- val isFloat = kind == FLOAT || kind == DOUBLE
- val emit = (c: TestOp, l: Label) => emitBr(c, l, isFloat)
- emitCondBr(block, cond, success, failure, next, emit)
-
- case CZJUMP(success, failure, cond, kind) =>
- emitCondBr(block, cond, success, failure, next, emitBrBool(_, _))
-
- case RETURN(kind) =>
- if (currentHandlers.isEmpty)
- mcode.Emit(OpCodes.Ret)
- else {
- val (local, label) = returnFromHandler(kind)
- if (kind != UNIT)
- mcode.Emit(OpCodes.Stloc, local)
- mcode.Emit(OpCodes.Leave, label)
- }
-
- case THROW(_) =>
- mcode.Emit(OpCodes.Throw)
-
- case DROP(kind) =>
- mcode.Emit(OpCodes.Pop)
-
- case DUP(kind) =>
- // see comment on `var previousWasNEW`
- if (!previousWasNEW)
- mcode.Emit(OpCodes.Dup)
- else
- previousWasNEW = false
-
- case MONITOR_ENTER() =>
- mcode.Emit(OpCodes.Call, MMONITOR_ENTER)
-
- case MONITOR_EXIT() =>
- mcode.Emit(OpCodes.Call, MMONITOR_EXIT)
-
- case SCOPE_ENTER(_) | SCOPE_EXIT(_) | LOAD_EXCEPTION(_) =>
- ()
- }
-
- } // end for (instr <- b) { .. }
- } // end genBlock
-
- def genPrimitive(primitive: Primitive, pos: Position) {
- primitive match {
- case Negation(kind) =>
- kind match {
- // CHECK: is ist possible to get this for BOOL? in this case, verify.
- case BOOL | BYTE | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE =>
- mcode.Emit(OpCodes.Neg)
-
- case _ => abort("Impossible to negate a " + kind)
- }
-
- case Arithmetic(op, kind) =>
- op match {
- case ADD => mcode.Emit(OpCodes.Add)
- case SUB => mcode.Emit(OpCodes.Sub)
- case MUL => mcode.Emit(OpCodes.Mul)
- case DIV => mcode.Emit(OpCodes.Div)
- case REM => mcode.Emit(OpCodes.Rem)
- case NOT => mcode.Emit(OpCodes.Not) //bitwise complement (one's complement)
- case _ => abort("Unknown arithmetic primitive " + primitive )
- }
-
- case Logical(op, kind) => op match {
- case AND => mcode.Emit(OpCodes.And)
- case OR => mcode.Emit(OpCodes.Or)
- case XOR => mcode.Emit(OpCodes.Xor)
- }
-
- case Shift(op, kind) => op match {
- case LSL => mcode.Emit(OpCodes.Shl)
- case ASR => mcode.Emit(OpCodes.Shr)
- case LSR => mcode.Emit(OpCodes.Shr_Un)
- }
-
- case Conversion(src, dst) =>
- debuglog("Converting from: " + src + " to: " + dst)
-
- dst match {
- case BYTE => mcode.Emit(OpCodes.Conv_I1) // I1 for System.SByte, i.e. a scala.Byte
- case SHORT => mcode.Emit(OpCodes.Conv_I2)
- case CHAR => mcode.Emit(OpCodes.Conv_U2)
- case INT => mcode.Emit(OpCodes.Conv_I4)
- case LONG => mcode.Emit(OpCodes.Conv_I8)
- case FLOAT => mcode.Emit(OpCodes.Conv_R4)
- case DOUBLE => mcode.Emit(OpCodes.Conv_R8)
- case _ =>
- Console.println("Illegal conversion at: " + clasz +
- " at: " + pos.source + ":" + pos.line)
- }
-
- case ArrayLength(_) =>
- mcode.Emit(OpCodes.Ldlen)
-
- case StartConcat =>
- mcode.Emit(OpCodes.Newobj, MSTRING_BUILDER_CONSTR)
-
-
- case StringConcat(el) =>
- val elemType : MsilType = el match {
- case REFERENCE(_) | ARRAY(_) => MOBJECT
- case _ => msilType(el)
- }
-
- val argTypes:Array[MsilType] = Array(elemType)
- val stringBuilderAppend = MSTRING_BUILDER.GetMethod("Append", argTypes )
- mcode.Emit(OpCodes.Callvirt, stringBuilderAppend)
-
- case EndConcat =>
- mcode.Emit(OpCodes.Callvirt, MSTRING_BUILDER_TOSTRING)
-
- case _ =>
- abort("Unimplemented primitive " + primitive)
- }
- } // end genPrimitive
-
-
- ////////////////////// loading ///////////////////////
-
- def loadI4(value: Int, code: ILGenerator): Unit = value match {
- case -1 => code.Emit(OpCodes.Ldc_I4_M1)
- case 0 => code.Emit(OpCodes.Ldc_I4_0)
- case 1 => code.Emit(OpCodes.Ldc_I4_1)
- case 2 => code.Emit(OpCodes.Ldc_I4_2)
- case 3 => code.Emit(OpCodes.Ldc_I4_3)
- case 4 => code.Emit(OpCodes.Ldc_I4_4)
- case 5 => code.Emit(OpCodes.Ldc_I4_5)
- case 6 => code.Emit(OpCodes.Ldc_I4_6)
- case 7 => code.Emit(OpCodes.Ldc_I4_7)
- case 8 => code.Emit(OpCodes.Ldc_I4_8)
- case _ =>
- if (value >= -128 && value <= 127)
- code.Emit(OpCodes.Ldc_I4_S, value)
- else
- code.Emit(OpCodes.Ldc_I4, value)
- }
-
- def loadArg(code: ILGenerator, loadAddr: Boolean)(i: Int) =
- if (loadAddr) {
- if (i >= -128 && i <= 127)
- code.Emit(OpCodes.Ldarga_S, i)
- else
- code.Emit(OpCodes.Ldarga, i)
- } else {
- i match {
- case 0 => code.Emit(OpCodes.Ldarg_0)
- case 1 => code.Emit(OpCodes.Ldarg_1)
- case 2 => code.Emit(OpCodes.Ldarg_2)
- case 3 => code.Emit(OpCodes.Ldarg_3)
- case _ =>
- if (i >= -128 && i <= 127)
- code.Emit(OpCodes.Ldarg_S, i)
- else
- code.Emit(OpCodes.Ldarg, i)
- }
- }
-
- def loadLocal(i: Int, local: Local, code: ILGenerator, loadAddr: Boolean) =
- if (loadAddr) {
- if (i >= -128 && i <= 127)
- code.Emit(OpCodes.Ldloca_S, localBuilders(local))
- else
- code.Emit(OpCodes.Ldloca, localBuilders(local))
- } else {
- i match {
- case 0 => code.Emit(OpCodes.Ldloc_0)
- case 1 => code.Emit(OpCodes.Ldloc_1)
- case 2 => code.Emit(OpCodes.Ldloc_2)
- case 3 => code.Emit(OpCodes.Ldloc_3)
- case _ =>
- if (i >= -128 && i <= 127)
- code.Emit(OpCodes.Ldloc_S, localBuilders(local))
- else
- code.Emit(OpCodes.Ldloc, localBuilders(local))
- }
- }
-
- ////////////////////// branches ///////////////////////
-
- /** Returns a Triple (Boolean, Boolean, Option[Label])
- * - whether the jump leaves some exception block (try / catch / finally)
- * - whether it leaves a finally handler (finally block, but not it's try / catch)
- * - a label where to jump for leaving the finally handler
- * . None to leave directly using `endfinally`
- * . Some(label) to emit `leave label` (for try / catch inside a finally handler)
- */
- def leavesHandler(from: BasicBlock, to: BasicBlock): (Boolean, Boolean, Option[Label]) =
- if (currentHandlers.isEmpty) (false, false, None)
- else {
- val h = currentHandlers.head
- val leaveHead = { h.covers(from) != h.covers(to) ||
- h.blocks.contains(from) != h.blocks.contains(to) }
- if (leaveHead) {
- // we leave the innermost exception block.
- // find out if we also leave som e `finally` handler
- currentHandlers.find(e => {
- e.cls == NoSymbol && e.blocks.contains(from) != e.blocks.contains(to)
- }) match {
- case Some(finallyHandler) =>
- if (h == finallyHandler) {
- // the finally handler is the innermost, so we can emit `endfinally` directly
- (true, true, None)
- } else {
- // we need to `Leave` to the `endfinally` of the next outer finally handler
- val l = endFinallyLabels.getOrElseUpdate(finallyHandler, mcode.DefineLabel())
- (true, true, Some(l))
- }
- case None =>
- (true, false, None)
- }
- } else (false, false, None)
- }
-
- def emitCondBr(block: BasicBlock, cond: TestOp, success: BasicBlock, failure: BasicBlock,
- next: BasicBlock, emitBrFun: (TestOp, Label) => Unit) {
- val (sLeaveHandler, sLeaveFinally, slfTarget) = leavesHandler(block, success)
- val (fLeaveHandler, fLeaveFinally, flfTarget) = leavesHandler(block, failure)
-
- if (sLeaveHandler || fLeaveHandler) {
- val sLabelOpt = if (sLeaveHandler) {
- val leaveSLabel = mcode.DefineLabel()
- emitBrFun(cond, leaveSLabel)
- Some(leaveSLabel)
- } else {
- emitBrFun(cond, labels(success))
- None
- }
-
- if (fLeaveHandler) {
- if (fLeaveFinally) {
- if (flfTarget.isDefined) mcode.Emit(OpCodes.Leave, flfTarget.get)
- else mcode.Emit(OpCodes.Endfinally)
- } else
- mcode.Emit(OpCodes.Leave, labels(failure))
- } else
- mcode.Emit(OpCodes.Br, labels(failure))
-
- sLabelOpt.map(l => {
- mcode.MarkLabel(l)
- if (sLeaveFinally) {
- if (slfTarget.isDefined) mcode.Emit(OpCodes.Leave, slfTarget.get)
- else mcode.Emit(OpCodes.Endfinally)
- } else
- mcode.Emit(OpCodes.Leave, labels(success))
- })
- } else {
- if (next == success) {
- emitBrFun(cond.negate, labels(failure))
- } else {
- emitBrFun(cond, labels(success))
- if (next != failure) {
- mcode.Emit(OpCodes.Br, labels(failure))
- }
- }
- }
- }
-
- def emitBr(condition: TestOp, dest: Label, isFloat: Boolean) {
- condition match {
- case EQ => mcode.Emit(OpCodes.Beq, dest)
- case NE => mcode.Emit(OpCodes.Bne_Un, dest)
- case LT => mcode.Emit(if (isFloat) OpCodes.Blt_Un else OpCodes.Blt, dest)
- case GE => mcode.Emit(if (isFloat) OpCodes.Bge_Un else OpCodes.Bge, dest)
- case LE => mcode.Emit(if (isFloat) OpCodes.Ble_Un else OpCodes.Ble, dest)
- case GT => mcode.Emit(if (isFloat) OpCodes.Bgt_Un else OpCodes.Bgt, dest)
- }
- }
-
- def emitBrBool(cond: TestOp, dest: Label) {
- (cond: @unchecked) match {
- // EQ -> Brfalse, NE -> Brtrue; this is because we come from
- // a CZJUMP. If the value on the stack is 0 (e.g. a boolean
- // method returned false), and we are in the case EQ, then
- // we need to emit Brfalse (EQ Zero means false). vice versa
- case EQ => mcode.Emit(OpCodes.Brfalse, dest)
- case NE => mcode.Emit(OpCodes.Brtrue, dest)
- }
- }
-
- ////////////////////// local vars ///////////////////////
-
- /**
- * Compute the indexes of each local variable of the given
- * method.
- */
- def computeLocalVarsIndex(m: IMethod) {
- var idx = if (m.symbol.isStaticMember) 0 else 1
-
- val params = m.params
- for (l <- params) {
- debuglog("Index value for parameter " + l + ": " + idx)
- l.index = idx
- idx += 1 // sizeOf(l.kind)
- }
-
- val locvars = m.locals filterNot (params contains)
- idx = 0
-
- for (l <- locvars) {
- debuglog("Index value for local variable " + l + ": " + idx)
- l.index = idx
- idx += 1 // sizeOf(l.kind)
- }
-
- }
-
- ////////////////////// Utilities ////////////////////////
-
- /** Return the a name of this symbol that can be used on the .NET
- * platform. It removes spaces from names.
- *
- * Special handling: scala.All and scala.AllRef are 'erased' to
- * scala.All$ and scala.AllRef$. This is needed because they are
- * not real classes, and they mean 'abrupt termination upon evaluation
- * of that expression' or 'null' respectively. This handling is
- * done already in GenICode, but here we need to remove references
- * from method signatures to these types, because such classes can
- * not exist in the classpath: the type checker will be very confused.
- */
- def msilName(sym: Symbol): String = {
- val suffix = sym.moduleSuffix
- // Flags.JAVA: "symbol was not defined by a scala-class" (java, or .net-class)
-
- if (sym == definitions.NothingClass)
- return "scala.runtime.Nothing$"
- else if (sym == definitions.NullClass)
- return "scala.runtime.Null$"
-
- (if (sym.isClass || (sym.isModule && !sym.isMethod)) {
- if (sym.isNestedClass) sym.simpleName
- else sym.fullName
- } else
- sym.simpleName.toString.trim()) + suffix
- }
-
-
- ////////////////////// flags ///////////////////////
-
- def msilTypeFlags(sym: Symbol): Int = {
- var mf: Int = TypeAttributes.AutoLayout | TypeAttributes.AnsiClass
-
- if(sym.isNestedClass) {
- mf = mf | (if (sym hasFlag Flags.PRIVATE) TypeAttributes.NestedPrivate else TypeAttributes.NestedPublic)
- } else {
- mf = mf | (if (sym hasFlag Flags.PRIVATE) TypeAttributes.NotPublic else TypeAttributes.Public)
- }
- mf = mf | (if (sym hasFlag Flags.ABSTRACT) TypeAttributes.Abstract else 0)
- mf = mf | (if (sym.isTrait && !sym.isImplClass) TypeAttributes.Interface else TypeAttributes.Class)
- mf = mf | (if (sym isFinal) TypeAttributes.Sealed else 0)
- mf
- // static: not possible (or?)
- }
-
- def msilMethodFlags(sym: Symbol): Short = {
- var mf: Int = MethodAttributes.HideBySig |
- (if (sym hasFlag Flags.PRIVATE) MethodAttributes.Private
- else MethodAttributes.Public)
-
- if (!sym.isClassConstructor) {
- if (sym.isStaticMember)
- mf = mf | FieldAttributes.Static // coincidentally, same value as for MethodAttributes.Static ...
- else {
- mf = mf | MethodAttributes.Virtual
- if (sym.isFinal && !getType(sym.owner).IsInterface)
- mf = mf | MethodAttributes.Final
- if (sym.isDeferred || getType(sym.owner).IsInterface)
- mf = mf | MethodAttributes.Abstract
- }
- }
-
- if (sym.isStaticMember) {
- mf = mf | MethodAttributes.Static
- }
-
- // constructors of module classes should be private
- if (sym.isPrimaryConstructor && isTopLevelModule(sym.owner)) {
- mf |= MethodAttributes.Private
- mf &= ~(MethodAttributes.Public)
- }
-
- mf.toShort
- }
-
- def msilFieldFlags(sym: Symbol): Short = {
- var mf: Int =
- if (sym hasFlag Flags.PRIVATE) FieldAttributes.Private
- else if (sym hasFlag Flags.PROTECTED) FieldAttributes.FamORAssem
- else FieldAttributes.Public
-
- if (sym hasFlag Flags.FINAL)
- mf = mf | FieldAttributes.InitOnly
-
- if (sym.isStaticMember)
- mf = mf | FieldAttributes.Static
-
- // TRANSIENT: "not serialized", VOLATILE: doesn't exist on .net
- // TODO: add this annotation also if the class has the custom attribute
- // System.NotSerializedAttribute
- sym.annotations.foreach( a => a match {
- case AnnotationInfo(TransientAtt, _, _) =>
- mf = mf | FieldAttributes.NotSerialized
- case _ => ()
- })
-
- mf.toShort
- }
-
- ////////////////////// builders, types ///////////////////////
-
- var entryPoint: Symbol = _
-
- val notInitializedModules = mutable.HashSet[Symbol]()
-
- // TODO: create fields also in def createType, and not in genClass,
- // add a getField method (it only works as it is because fields never
- // accessed from outside a class)
-
- val localBuilders = mutable.HashMap[Local, LocalBuilder]()
-
- private[GenMSIL] def findEntryPoint(cls: IClass) {
-
- def isEntryPoint(sym: Symbol):Boolean = {
- if (isStaticModule(sym.owner) && msilName(sym) == "main")
- if (sym.tpe.paramTypes.length == 1) {
- toTypeKind(sym.tpe.paramTypes(0)) match {
- case ARRAY(elem) =>
- if (elem.toType.typeSymbol == definitions.StringClass) {
- return true
- }
- case _ => ()
- }
- }
- false
- }
-
- if((entryPoint == null) && settings.Xshowcls.isSetByUser) { // TODO introduce dedicated setting instead
- val entryclass = settings.Xshowcls.value.toString
- val cfn = cls.symbol.fullName
- if(cfn == entryclass) {
- for (m <- cls.methods; if isEntryPoint(m.symbol)) { entryPoint = m.symbol }
- if(entryPoint == null) { warning("Couldn't find main method in class " + cfn) }
- }
- }
-
- if (firstSourceName == "")
- if (cls.symbol.sourceFile != null) // is null for nested classes
- firstSourceName = cls.symbol.sourceFile.name
- }
-
- // #####################################################################
- // get and create types
-
- private def msilType(t: TypeKind): MsilType = (t: @unchecked) match {
- case UNIT => MVOID
- case BOOL => MBOOL
- case BYTE => MBYTE
- case SHORT => MSHORT
- case CHAR => MCHAR
- case INT => MINT
- case LONG => MLONG
- case FLOAT => MFLOAT
- case DOUBLE => MDOUBLE
- case REFERENCE(cls) => getType(cls)
- case ARRAY(elem) =>
- msilType(elem) match {
- // For type builders, cannot call "clrTypes.mkArrayType" because this looks up
- // the type "tp" in the assembly (not in the HashMap "types" of the backend).
- // This can fail for nested types because the builders are not complete yet.
- case tb: TypeBuilder => tb.MakeArrayType()
- case tp: MsilType => clrTypes.mkArrayType(tp)
- }
- }
-
- private def msilType(tpe: Type): MsilType = msilType(toTypeKind(tpe))
-
- private def msilParamTypes(sym: Symbol): Array[MsilType] = {
- sym.tpe.paramTypes.map(msilType).toArray
- }
-
- def getType(sym: Symbol) = getTypeOpt(sym).getOrElse(abort(showsym(sym)))
-
- /**
- * Get an MSIL type from a symbol. First look in the clrTypes.types map, then
- * lookup the name using clrTypes.getType
- */
- def getTypeOpt(sym: Symbol): Option[MsilType] = {
- val tmp = types.get(sym)
- tmp match {
- case typ @ Some(_) => typ
- case None =>
- def typeString(sym: Symbol): String = {
- val s = if (sym.isNestedClass) typeString(sym.owner) +"+"+ sym.simpleName
- else sym.fullName
- if (sym.isModuleClass && !sym.isTrait) s + "$" else s
- }
- val name = typeString(sym)
- val typ = clrTypes.getType(name)
- if (typ == null)
- None
- else {
- types(sym) = typ
- Some(typ)
- }
- }
- }
-
- def mapType(sym: Symbol, mType: MsilType) {
- assert(mType != null, showsym(sym))
- types(sym) = mType
- }
-
- def createTypeBuilder(iclass: IClass) {
- /**
- * First look in the clrTypes.types map, if that fails check if it's a class being compiled, otherwise
- * lookup by name (clrTypes.getType calls the static method msil.Type.GetType(fullname)).
- */
- def msilTypeFromSym(sym: Symbol): MsilType = {
- types.get(sym).getOrElse {
- classes.get(sym) match {
- case Some(iclass) =>
- msilTypeBuilderFromSym(sym)
- case None =>
- getType(sym)
- }
- }
- }
-
- def msilTypeBuilderFromSym(sym: Symbol): TypeBuilder = {
- if(!(types.contains(sym) && types(sym).isInstanceOf[TypeBuilder])){
- val iclass = classes(sym)
- assert(iclass != null)
- createTypeBuilder(iclass)
- }
- types(sym).asInstanceOf[TypeBuilder]
- }
-
- val sym = iclass.symbol
- if (types.contains(sym) && types(sym).isInstanceOf[TypeBuilder])
- return
-
- def isInterface(s: Symbol) = s.isTrait && !s.isImplClass
- val parents: List[Type] =
- if (sym.info.parents.isEmpty) List(definitions.ObjectClass.tpe)
- else sym.info.parents.distinct
-
- val superType : MsilType = if (isInterface(sym)) null else msilTypeFromSym(parents.head.typeSymbol)
- debuglog("super type: " + parents(0).typeSymbol + ", msil type: " + superType)
-
- val interfaces: Array[MsilType] =
- parents.tail.map(p => msilTypeFromSym(p.typeSymbol)).toArray
- if (parents.length > 1) {
- if (settings.debug.value) {
- log("interfaces:")
- for (i <- 0.until(interfaces.length)) {
- log(" type: " + parents(i + 1).typeSymbol + ", msil type: " + interfaces(i))
- }
- }
- }
-
- val tBuilder = if (sym.isNestedClass) {
- val ownerT = msilTypeBuilderFromSym(sym.owner).asInstanceOf[TypeBuilder]
- ownerT.DefineNestedType(msilName(sym), msilTypeFlags(sym), superType, interfaces)
- } else {
- mmodule.DefineType(msilName(sym), msilTypeFlags(sym), superType, interfaces)
- }
- mapType(sym, tBuilder)
- } // createTypeBuilder
-
- def createClassMembers(iclass: IClass) {
- try {
- createClassMembers0(iclass)
- }
- catch {
- case e: Throwable =>
- java.lang.System.err.println(showsym(iclass.symbol))
- java.lang.System.err.println("with methods = " + iclass.methods)
- throw e
- }
- }
-
- def createClassMembers0(iclass: IClass) {
-
- val mtype = getType(iclass.symbol).asInstanceOf[TypeBuilder]
-
- for (ifield <- iclass.fields) {
- val sym = ifield.symbol
- debuglog("Adding field: " + sym.fullName)
-
- val attributes = msilFieldFlags(sym)
- val fieldTypeWithCustomMods =
- new PECustomMod(msilType(sym.tpe),
- customModifiers(sym.annotations))
- val fBuilder = mtype.DefineField(msilName(sym),
- fieldTypeWithCustomMods,
- attributes)
- fields(sym) = fBuilder
- addAttributes(fBuilder, sym.annotations)
- } // all iclass.fields iterated over
-
- if (isStaticModule(iclass.symbol)) {
- val sc = iclass.lookupStaticCtor
- if (sc.isDefined) {
- val m = sc.get
- val oldLastBlock = m.lastBlock
- val lastBlock = m.newBlock()
- oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock))
- // call object's private ctor from static ctor
- lastBlock.emit(CIL_NEWOBJ(iclass.symbol.primaryConstructor))
- lastBlock.emit(DROP(toTypeKind(iclass.symbol.tpe)))
- lastBlock emit RETURN(UNIT)
- lastBlock.close
- }
- }
-
- if (iclass.symbol != definitions.ArrayClass) {
- for (m: IMethod <- iclass.methods) {
- val sym = m.symbol
- debuglog("Creating MethodBuilder for " + sym.flagString + " " +
- sym.owner.fullName + "::" + sym.name)
-
- val ownerType = getType(sym.enclClass).asInstanceOf[TypeBuilder]
- assert(mtype == ownerType, "mtype = " + mtype + "; ownerType = " + ownerType)
- val paramTypes = msilParamTypes(sym)
- val attr = msilMethodFlags(sym)
-
- if (m.symbol.isClassConstructor) {
- val constr =
- ownerType.DefineConstructor(attr, CallingConventions.Standard, paramTypes)
- for (i <- 0.until(paramTypes.length)) {
- constr.DefineParameter(i, ParameterAttributes.None, msilName(m.params(i).sym))
- }
- mapConstructor(sym, constr)
- addAttributes(constr, sym.annotations)
- } else {
- val resType = msilType(m.returnType)
- val method =
- ownerType.DefineMethod(msilName(sym), attr, resType, paramTypes)
- for (i <- 0.until(paramTypes.length)) {
- method.DefineParameter(i, ParameterAttributes.None, msilName(m.params(i).sym))
- }
- if (!methods.contains(sym))
- mapMethod(sym, method)
- addAttributes(method, sym.annotations)
- debuglog("\t created MethodBuilder " + method)
- }
- }
- } // method builders created for non-array iclass
-
- if (isStaticModule(iclass.symbol)) {
- addModuleInstanceField(iclass.symbol)
- notInitializedModules += iclass.symbol
- if (iclass.lookupStaticCtor.isEmpty) {
- addStaticInit(iclass.symbol)
- }
- }
-
- } // createClassMembers0
-
- private def isTopLevelModule(sym: Symbol): Boolean =
- enteringRefchecks {
- sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass
- }
-
- // if the module is lifted it does not need to be initialized in
- // its static constructor, and the MODULE$ field is not required.
- // the outer class will care about it.
- private def isStaticModule(sym: Symbol): Boolean = {
- // .net inner classes: removed '!sym.hasFlag(Flags.LIFTED)', added
- // 'sym.isStatic'. -> no longer compatible without skipping flatten!
- sym.isModuleClass && sym.isStatic && !sym.isImplClass
- }
-
- private def isCloneable(sym: Symbol): Boolean = {
- !sym.annotations.forall( a => a match {
- case AnnotationInfo(CloneableAttr, _, _) => false
- case _ => true
- })
- }
-
- private def addModuleInstanceField(sym: Symbol) {
- debuglog("Adding Module-Instance Field for " + showsym(sym))
- val tBuilder = getType(sym).asInstanceOf[TypeBuilder]
- val fb = tBuilder.DefineField(MODULE_INSTANCE_NAME,
- tBuilder,
- (FieldAttributes.Public |
- //FieldAttributes.InitOnly |
- FieldAttributes.Static).toShort)
- fields(sym) = fb
- }
-
-
- // the symbol may be a object-symbol (module-symbol), or a module-class-symbol
- private def getModuleInstanceField(sym: Symbol): FieldInfo = {
- assert(sym.isModule || sym.isModuleClass, "Expected module: " + showsym(sym))
-
- // when called by LOAD_MODULE, the corresponding type maybe doesn't
- // exist yet -> make a getType
- val moduleClassSym = if (sym.isModule) sym.moduleClass else sym
-
- // TODO: get module field for modules not defined in the
- // source currently compiling (e.g. Console)
-
- fields get moduleClassSym match {
- case Some(sym) => sym
- case None =>
- //val mclass = types(moduleClassSym)
- val nameInMetadata = nestingAwareFullClassname(moduleClassSym)
- val mClass = clrTypes.getType(nameInMetadata)
- val mfield = mClass.GetField("MODULE$")
- assert(mfield ne null, "module not found " + showsym(moduleClassSym))
- fields(moduleClassSym) = mfield
- mfield
- }
-
- //fields(moduleClassSym)
- }
-
- def nestingAwareFullClassname(csym: Symbol) : String = {
- val suffix = csym.moduleSuffix
- val res = if (csym.isNestedClass)
- nestingAwareFullClassname(csym.owner) + "+" + csym.encodedName
- else
- csym.fullName
- res + suffix
- }
-
- /** Adds a static initializer which creates an instance of the module
- * class (calls the primary constructor). A special primary constructor
- * will be generated (notInitializedModules) which stores the new instance
- * in the MODULE$ field right after the super call.
- */
- private def addStaticInit(sym: Symbol) {
- val tBuilder = getType(sym).asInstanceOf[TypeBuilder]
-
- val staticInit = tBuilder.DefineConstructor(
- (MethodAttributes.Static | MethodAttributes.Public).toShort,
- CallingConventions.Standard,
- MsilType.EmptyTypes)
-
- val sicode = staticInit.GetILGenerator()
-
- val instanceConstructor = constructors(sym.primaryConstructor)
-
- // there are no constructor parameters. assuming the constructor takes no parameter
- // is fine: we call (in the static constructor) the constructor of the module class,
- // which takes no arguments - an object definition cannot take constructor arguments.
- sicode.Emit(OpCodes.Newobj, instanceConstructor)
- // the stsfld is done in the instance constructor, just after the super call.
- sicode.Emit(OpCodes.Pop)
-
- sicode.Emit(OpCodes.Ret)
- }
-
- private def generateMirrorClass(sym: Symbol) {
- assert(sym.isModuleClass, "Can't generate Mirror-Class for the Non-Module class " + sym)
- debuglog("Dumping mirror class for object: " + sym)
- val moduleName = msilName(sym)
- val mirrorName = moduleName.substring(0, moduleName.length() - 1)
- val mirrorTypeBuilder = mmodule.DefineType(mirrorName,
- TypeAttributes.Class |
- TypeAttributes.Public |
- TypeAttributes.Sealed,
- MOBJECT,
- MsilType.EmptyTypes)
-
- val iclass = classes(sym)
-
- for (m <- sym.tpe.nonPrivateMembers
- if m.owner != definitions.ObjectClass && !m.isProtected &&
- m.isMethod && !m.isClassConstructor && !m.isStaticMember && !m.isCase &&
- !m.isDeferred)
- {
- debuglog(" Mirroring method: " + m)
- val paramTypes = msilParamTypes(m)
- val paramNames: Array[String] = new Array[String](paramTypes.length)
- for (i <- 0 until paramTypes.length)
- paramNames(i) = "x_" + i
-
- // CHECK: verify if getMethodName is better than msilName
- val mirrorMethod = mirrorTypeBuilder.DefineMethod(msilName(m),
- (MethodAttributes.Public |
- MethodAttributes.Static).toShort,
- msilType(m.tpe.resultType),
- paramTypes)
-
- var i = 0
- while (i < paramTypes.length) {
- mirrorMethod.DefineParameter(i, ParameterAttributes.None, paramNames(i))
- i += 1
- }
-
- val mirrorCode = mirrorMethod.GetILGenerator()
- mirrorCode.Emit(OpCodes.Ldsfld, getModuleInstanceField(sym))
- val mInfo = getMethod(m)
- for (paramidx <- 0.until(paramTypes.length)) {
- val mInfoParams = mInfo.GetParameters
- val loadAddr = mInfoParams(paramidx).ParameterType.IsByRef
- loadArg(mirrorCode, loadAddr)(paramidx)
- }
-
- mirrorCode.Emit(OpCodes.Callvirt, getMethod(m))
- mirrorCode.Emit(OpCodes.Ret)
- }
-
- addSymtabAttribute(sym.sourceModule, mirrorTypeBuilder)
-
- mirrorTypeBuilder.CreateType()
- mirrorTypeBuilder.setSourceFilepath(iclass.cunit.source.file.path)
- }
-
-
- // #####################################################################
- // delegate callers
-
- var delegateCallers: TypeBuilder = _
- var nbDelegateCallers: Int = 0
-
- private def initDelegateCallers() = {
- delegateCallers = mmodule.DefineType("$DelegateCallers", TypeAttributes.Public |
- TypeAttributes.Sealed)
- }
-
- private def createDelegateCaller(functionType: Type, delegateType: Type) = {
- if (delegateCallers == null)
- initDelegateCallers()
- // create a field an store the function-object
- val mFunctionType: MsilType = msilType(functionType)
- val anonfunField: FieldBuilder = delegateCallers.DefineField(
- "$anonfunField$$" + nbDelegateCallers, mFunctionType,
- (FieldAttributes.InitOnly | FieldAttributes.Public | FieldAttributes.Static).toShort)
- mcode.Emit(OpCodes.Stsfld, anonfunField)
-
-
- // create the static caller method and the delegate object
- val (params, returnType) = delegateType.member(nme.apply).tpe match {
- case MethodType(delParams, delReturn) => (delParams, delReturn)
- case _ => abort("not a delegate type: " + delegateType)
- }
- val caller: MethodBuilder = delegateCallers.DefineMethod(
- "$delegateCaller$$" + nbDelegateCallers,
- (MethodAttributes.Final | MethodAttributes.Public | MethodAttributes.Static).toShort,
- msilType(returnType), (params map (_.tpe)).map(msilType).toArray)
- for (i <- 0 until params.length)
- caller.DefineParameter(i, ParameterAttributes.None, "arg" + i) // FIXME: use name of parameter symbol
- val delegCtor = msilType(delegateType).GetConstructor(Array(MOBJECT, INT_PTR))
- mcode.Emit(OpCodes.Ldnull)
- mcode.Emit(OpCodes.Ldftn, caller)
- mcode.Emit(OpCodes.Newobj, delegCtor)
-
-
- // create the static caller method body
- val functionApply: MethodInfo = getMethod(functionType.member(nme.apply))
- val dcode: ILGenerator = caller.GetILGenerator()
- dcode.Emit(OpCodes.Ldsfld, anonfunField)
- for (i <- 0 until params.length) {
- loadArg(dcode, false /* TODO confirm whether passing actual as-is to formal is correct wrt the ByRef attribute of the param */)(i)
- emitBox(dcode, toTypeKind(params(i).tpe))
- }
- dcode.Emit(OpCodes.Callvirt, functionApply)
- emitUnbox(dcode, toTypeKind(returnType))
- dcode.Emit(OpCodes.Ret)
-
- nbDelegateCallers = nbDelegateCallers + 1
-
- } //def createDelegateCaller
-
- def emitBox(code: ILGenerator, boxType: TypeKind) = (boxType: @unchecked) match {
- // doesn't make sense, unit as parameter..
- case UNIT => code.Emit(OpCodes.Ldsfld, boxedUnit)
- case BOOL | BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE =>
- code.Emit(OpCodes.Box, msilType(boxType))
- case REFERENCE(cls) if clrTypes.isValueType(cls) =>
- code.Emit(OpCodes.Box, (msilType(boxType)))
- case REFERENCE(_) | ARRAY(_) =>
- warning("Tried to BOX a non-valuetype.")
- ()
- }
-
- def emitUnbox(code: ILGenerator, boxType: TypeKind) = (boxType: @unchecked) match {
- case UNIT => code.Emit(OpCodes.Pop)
- /* (1) it's essential to keep the code emitted here (as of now plain calls to System.Convert.ToBlaBla methods)
- behaviorally.equiv.wrt. BoxesRunTime.unboxToBlaBla methods
- (case null: that's easy, case boxed: track changes to unboxBlaBla)
- (2) See also: asInstanceOf to cast from Any to number,
- tracked in http://lampsvn.epfl.ch/trac/scala/ticket/4437 */
- case BOOL => code.Emit(OpCodes.Call, toBool)
- case BYTE => code.Emit(OpCodes.Call, toSByte)
- case SHORT => code.Emit(OpCodes.Call, toShort)
- case CHAR => code.Emit(OpCodes.Call, toChar)
- case INT => code.Emit(OpCodes.Call, toInt)
- case LONG => code.Emit(OpCodes.Call, toLong)
- case FLOAT => code.Emit(OpCodes.Call, toFloat)
- case DOUBLE => code.Emit(OpCodes.Call, toDouble)
- case REFERENCE(cls) if clrTypes.isValueType(cls) =>
- code.Emit(OpCodes.Unbox, msilType(boxType))
- code.Emit(OpCodes.Ldobj, msilType(boxType))
- case REFERENCE(_) | ARRAY(_) =>
- warning("Tried to UNBOX a non-valuetype.")
- ()
- }
-
- // #####################################################################
- // get and create methods / constructors
-
- def getConstructor(sym: Symbol): ConstructorInfo = constructors.get(sym) match {
- case Some(constr) => constr
- case None =>
- val mClass = getType(sym.owner)
- val constr = mClass.GetConstructor(msilParamTypes(sym))
- if (constr eq null) {
- java.lang.System.out.println("Cannot find constructor " + sym.owner + "::" + sym.name)
- java.lang.System.out.println("scope = " + sym.owner.tpe.decls)
- abort(sym.fullName)
- }
- else {
- mapConstructor(sym, constr)
- constr
- }
- }
-
- def mapConstructor(sym: Symbol, cInfo: ConstructorInfo) = {
- constructors(sym) = cInfo
- }
-
- private def getMethod(sym: Symbol): MethodInfo = {
-
- methods.get(sym) match {
- case Some(method) => method
- case None =>
- val mClass = getType(sym.owner)
- try {
- val method = mClass.GetMethod(msilName(sym), msilParamTypes(sym),
- msilType(sym.tpe.resultType))
- if (method eq null) {
- java.lang.System.out.println("Cannot find method " + sym.owner + "::" + msilName(sym))
- java.lang.System.out.println("scope = " + sym.owner.tpe.decls)
- abort(sym.fullName)
- }
- else {
- mapMethod(sym, method)
- method
- }
- }
- catch {
- case e: Exception =>
- Console.println("While looking up " + mClass + "::" + sym.nameString)
- Console.println("\t" + showsym(sym))
- throw e
- }
- }
- }
-
- /*
- * add a mapping between sym and mInfo
- */
- private def mapMethod(sym: Symbol, mInfo: MethodInfo) {
- assert (mInfo != null, mInfo)
- methods(sym) = mInfo
- }
-
- private def showsym(sym: Symbol): String = (sym.toString +
- "\n symbol = " + sym.flagString + " " + sym +
- "\n owner = " + sym.owner.flagString + " " + sym.owner
- )
-
- } // class BytecodeGenerator
-
-} // class GenMSIL
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index 650775b259..5dd20a6919 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -146,18 +146,18 @@ abstract class ClosureElimination extends SubComponent {
case _ =>
}
- case UNBOX(_) =>
+ case UNBOX(boxType) =>
info.stack match {
case Deref(LocalVar(loc1)) :: _ if info.bindings isDefinedAt LocalVar(loc1) =>
val value = info.getBinding(loc1)
value match {
- case Boxed(LocalVar(loc2)) =>
+ case Boxed(LocalVar(loc2)) if loc2.kind == boxType =>
bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(info.getBinding(loc2)) :: Nil)
debuglog("replaced " + i + " with " + info.getBinding(loc2))
case _ =>
()
}
- case Boxed(LocalVar(loc1)) :: _ =>
+ case Boxed(LocalVar(loc1)) :: _ if loc1.kind == boxType =>
val loc2 = info.getAlias(loc1)
bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(Deref(LocalVar(loc2))) :: Nil)
debuglog("replaced " + i + " with " + LocalVar(loc2))
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 04f95455a5..4dac5b7d90 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -233,8 +233,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
* exists, but should not be documented (either it's not included in the source or it's not visible)
*/
class NoDocTemplateImpl(sym: Symbol, inTpl: TemplateImpl) extends EntityImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with NoDocTemplate {
- assert(modelFinished)
- assert(!(noDocTemplatesCache isDefinedAt sym))
+ assert(modelFinished, this)
+ assert(!(noDocTemplatesCache isDefinedAt sym), (sym, noDocTemplatesCache(sym)))
noDocTemplatesCache += (sym -> this)
def isDocTemplate = false
}
@@ -269,7 +269,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
* All ancestors of the template and all non-package members.
*/
abstract class DocTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberTemplateImpl(sym, inTpl) with DocTemplateEntity {
- assert(!modelFinished)
+ assert(!modelFinished, (sym, inTpl))
assert(!(docTemplatesCache isDefinedAt sym), sym)
docTemplatesCache += (sym -> this)
@@ -620,7 +620,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
*/
def createTemplate(aSym: Symbol, inTpl: DocTemplateImpl): Option[MemberImpl] = {
// don't call this after the model finished!
- assert(!modelFinished)
+ assert(!modelFinished, (aSym, inTpl))
def createRootPackageComment: Option[Comment] =
if(settings.docRootContent.isDefault) None
@@ -636,7 +636,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
def createDocTemplate(bSym: Symbol, inTpl: DocTemplateImpl): DocTemplateImpl = {
- assert(!modelFinished) // only created BEFORE the model is finished
+ assert(!modelFinished, (bSym, inTpl)) // only created BEFORE the model is finished
if (bSym.isAliasType && bSym != AnyRefClass)
new DocTemplateImpl(bSym, inTpl) with AliasImpl with AliasType { override def isAliasType = true }
else if (bSym.isAbstractType)
@@ -842,24 +842,28 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
lazy val annotationClass =
makeTemplate(annot.symbol)
val arguments = { // lazy
- def noParams = annot.args map { _ => None }
+ def annotArgs = annot.args match {
+ case Nil => annot.assocs collect { case (_, LiteralAnnotArg(const)) => Literal(const) }
+ case xs => xs
+ }
+ def noParams = annotArgs map (_ => None)
+
val params: List[Option[ValueParam]] = annotationClass match {
case aClass: DocTemplateEntity with Class =>
(aClass.primaryConstructor map { _.valueParams.head }) match {
case Some(vps) => vps map { Some(_) }
- case None => noParams
+ case _ => noParams
}
case _ => noParams
}
- assert(params.length == annot.args.length)
- (params zip annot.args) flatMap { case (param, arg) =>
- makeTree(arg) match {
- case Some(tree) =>
- Some(new ValueArgument {
- def parameter = param
- def value = tree
- })
- case None => None
+ assert(params.length == annotArgs.length, (params, annotArgs))
+
+ params zip annotArgs flatMap { case (param, arg) =>
+ makeTree(arg) map { tree =>
+ new ValueArgument {
+ def parameter = param
+ def value = tree
+ }
}
}
}
@@ -891,7 +895,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
// units.filter should return only one element
(currentRun.units filter (_.source.file == aSym.sourceFile)).toList match {
case List(unit) =>
- (unit.body find (_.symbol == aSym)) match {
+ // SI-4922 `sym == aSym` is insufficent if `aSym` is a clone of symbol
+ // of the parameter in the tree, as can happen with type parametric methods.
+ def isCorrespondingParam(sym: Symbol) = (
+ sym != null &&
+ sym != NoSymbol &&
+ sym.owner == aSym.owner &&
+ sym.name == aSym.name &&
+ sym.isParamWithDefault
+ )
+ (unit.body find (t => isCorrespondingParam(t.symbol))) match {
case Some(ValDef(_,_,_,rhs)) => makeTree(rhs)
case _ => None
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index e4bff1e192..9716c75215 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -810,8 +810,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
respond(response) { scopeMembers(pos) }
}
- private val Dollar = newTermName("$")
-
private class Members[M <: Member] extends LinkedHashMap[Name, Set[M]] {
override def default(key: Name) = Set()
@@ -827,7 +825,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def add(sym: Symbol, pre: Type, implicitlyAdded: Boolean)(toMember: (Symbol, Type) => M) {
if ((sym.isGetter || sym.isSetter) && sym.accessed != NoSymbol) {
add(sym.accessed, pre, implicitlyAdded)(toMember)
- } else if (!sym.name.decodedName.containsName(Dollar) && !sym.isSynthetic && sym.hasRawInfo) {
+ } else if (!sym.name.decodedName.containsName("$") && !sym.isSynthetic && sym.hasRawInfo) {
val symtpe = pre.memberType(sym) onTypeError ErrorType
matching(sym, symtpe, this(sym.name)) match {
case Some(m) =>
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index ecaa793da7..5a1a4cbdeb 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -143,7 +143,7 @@ self: scala.tools.nsc.Global =>
*/
private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try {
for (tree <- trees) {
- if (!tree.isEmpty && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
val children = tree.children
if (children.isEmpty) {
tree setPos pos.focus
@@ -164,7 +164,7 @@ self: scala.tools.nsc.Global =>
*/
override def atPos[T <: Tree](pos: Position)(tree: T): T = {
if (pos.isOpaqueRange) {
- if (!tree.isEmpty && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
tree.setPos(pos)
val children = tree.children
if (children.nonEmpty) {
@@ -202,7 +202,7 @@ self: scala.tools.nsc.Global =>
def validate(tree: Tree, encltree: Tree): Unit = {
- if (!tree.isEmpty) {
+ if (!tree.isEmpty && tree.canHaveAttrs) {
if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value))
println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
diff --git a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
index fcb485defd..9fbd337b9d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala
@@ -7,7 +7,7 @@ package interpreter
import scala.tools.nsc.io.AbstractFile
import util.ScalaClassLoader
-import java.net.URL
+import java.net.{ URL, URLConnection, URLStreamHandler }
import scala.collection.{ mutable, immutable }
/**
@@ -25,7 +25,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader)
protected def findAbstractFile(name: String): AbstractFile = {
var file: AbstractFile = root
- val pathParts = classNameToPath(name) split '/'
+ val pathParts = name split '/'
for (dirPart <- pathParts.init) {
file = file.lookupName(dirPart, true)
@@ -55,11 +55,26 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader)
return file
}
+ // parent delegation in JCL uses getResource; so either add parent.getResAsStream
+ // or implement findResource, which we do here as a study in scarlet (my complexion
+ // after looking at CLs and URLs)
+ override def findResource(name: String): URL = findAbstractFile(name) match {
+ case null => null
+ case file => new URL(null, "repldir:" + file.path, new URLStreamHandler {
+ override def openConnection(url: URL): URLConnection = new URLConnection(url) {
+ override def connect() { }
+ override def getInputStream = file.input
+ }
+ })
+ }
+
+ // this inverts delegation order: super.getResAsStr calls parent.getRes if we fail
override def getResourceAsStream(name: String) = findAbstractFile(name) match {
case null => super.getResourceAsStream(name)
case file => file.input
}
- override def classBytes(name: String): Array[Byte] = findAbstractFile(name) match {
+ // ScalaClassLoader.classBytes uses getResAsStream, so we'll try again before delegating
+ override def classBytes(name: String): Array[Byte] = findAbstractFile(classNameToPath(name)) match {
case null => super.classBytes(name)
case file => file.toByteArray
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 612a90f3ea..b2af53574f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -279,14 +279,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
- protected def newJavap() = {
- val intp = ILoop.this.intp
- import intp._
+ protected def newJavap() =
+ JavapClass(addToolsJarToLoader(), new IMain.ReplStrippingWriter(intp), Some(intp))
- new JavapClass(addToolsJarToLoader(), new IMain.ReplStrippingWriter(intp)) {
- override def tryClass(path: String) = super.tryClass(translatePath(path) getOrElse path)
- }
- }
private lazy val javap = substituteAndLog[Javap]("javap", NoJavap)(newJavap())
// Still todo: modules.
@@ -308,8 +303,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private def javapCommand(line: String): Result = {
if (javap == null)
":javap unavailable, no tools.jar at %s. Set JDK_HOME.".format(jdkHome)
- else if (javaVersion startsWith "1.7")
- ":javap not yet working with java 1.7"
else if (line == "")
":javap [-lcsvp] [path1 path2 ...]"
else
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 3f49e782b0..91e909b1f1 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -312,6 +312,14 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
case _ => Some(flatPath(sym))
}
}
+ def translateEnclosingClass(n: String) = {
+ def enclosingClass(s: Symbol): Symbol =
+ if (s == NoSymbol || s.isClass) s else enclosingClass(s.owner)
+ enclosingClass(symbolOfTerm(n)) match {
+ case NoSymbol => None
+ case c => Some(flatPath(c))
+ }
+ }
private class TranslatingClassLoader(parent: ClassLoader) extends AbstractFileClassLoader(replOutput.dir, parent) {
/** Overridden here to try translating a simple name to the generated
diff --git a/src/compiler/scala/tools/nsc/interpreter/ISettings.scala b/src/compiler/scala/tools/nsc/interpreter/ISettings.scala
index d114ca2359..9541d08db1 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ISettings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ISettings.scala
@@ -25,7 +25,7 @@ class ISettings(intp: IMain) {
var maxAutoprintCompletion = 250
/** String unwrapping can be disabled if it is causing issues.
- * Settings this to false means you will see Strings like "$iw.$iw.".
+ * Setting this to false means you will see Strings like "$iw.$iw.".
*/
var unwrapStrings = true
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index 381dfeb261..cb091ac9a7 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -116,7 +116,7 @@ trait MemberHandlers {
if (replProps.vids) s"""" + " @ " + "%%8x".format(System.identityHashCode($path)) + " """.trim
else ""
- """ + "%s%s: %s = " + %s""".format(prettyName, vidString, string2code(req typeOf name), resultString)
+ """ + "%s%s: %s = " + %s""".format(string2code(prettyName), vidString, string2code(req typeOf name), resultString)
}
}
}
@@ -143,13 +143,12 @@ trait MemberHandlers {
override def resultExtractionCode(req: Request) = {
val lhsType = string2code(req lookupTypeOf name)
val res = string2code(req fullPath name)
-
- """ + "%s: %s = " + %s + "\n" """.format(lhs, lhsType, res) + "\n"
+ """ + "%s: %s = " + %s + "\n" """.format(string2code(lhs.toString), lhsType, res) + "\n"
}
}
class ModuleHandler(module: ModuleDef) extends MemberDefHandler(module) {
- override def definesTerm = Some(name)
+ override def definesTerm = Some(name.toTermName)
override def definesValue = true
override def resultExtractionCode(req: Request) = codegenln("defined module ", name)
diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
index 41ddf23de4..57f3675ada 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
@@ -6,6 +6,8 @@
package scala.tools.nsc
package interpreter
+import scala.util.Properties.lineSeparator
+
/** This is for name logic which is independent of the compiler (notice there's no Global.)
* That includes at least generating, metaquoting, mangling, and unmangling.
*/
@@ -18,8 +20,14 @@ trait Naming {
// <ESC> for ansi codes.
val binaryChars = cleaned count (ch => ch < 32 && !ch.isWhitespace && ch != ESC)
// Lots of binary chars - translate all supposed whitespace into spaces
- if (binaryChars > 5)
- cleaned map (ch => if (ch.isWhitespace) ' ' else if (ch < 32) '?' else ch)
+ // except supposed line endings, otherwise scrubbed lines run together
+ if (binaryChars > 5) // more than one can count while holding a hamburger
+ cleaned map {
+ case c if lineSeparator contains c => c
+ case c if c.isWhitespace => ' '
+ case c if c < 32 => '?'
+ case c => c
+ }
// Not lots - preserve whitespace and ESC
else
cleaned map (ch => if (ch.isWhitespace || ch == ESC) ch else if (ch < 32) '?' else ch)
diff --git a/src/compiler/scala/tools/nsc/io/MsilFile.scala b/src/compiler/scala/tools/nsc/io/MsilFile.scala
deleted file mode 100644
index bda13a5ed0..0000000000
--- a/src/compiler/scala/tools/nsc/io/MsilFile.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2013 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.tools.nsc
-package io
-
-import ch.epfl.lamp.compiler.msil.{ Type => MsilType }
-
-/** This class wraps an MsilType. It exists only so
- * ClassPath can treat all of JVM/MSIL/bin/src files
- * uniformly, as AbstractFiles.
- */
-class MsilFile(val msilType: MsilType) extends VirtualFile(msilType.FullName, msilType.Namespace) { }
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 73cbeaa6c4..bb82cfb827 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -125,7 +125,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def makeSyntheticParam(count: Int, tpt: Tree): ValDef =
makeParam(nme.syntheticParamName(count), tpt)
def makeParam(name: String, tpt: Tree): ValDef =
- makeParam(newTypeName(name), tpt)
+ makeParam(name: TermName, tpt)
def makeParam(name: TermName, tpt: Tree): ValDef =
ValDef(Modifiers(Flags.JAVA | Flags.PARAM), name, tpt, EmptyTree)
@@ -448,7 +448,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
AppliedTypeTree(scalaDot(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME), List(t))
}
}
- varDecl(in.currentPos, Modifiers(Flags.JAVA | Flags.PARAM), t, ident())
+ varDecl(in.currentPos, Modifiers(Flags.JAVA | Flags.PARAM), t, ident().toTermName)
}
def optThrows() {
@@ -506,7 +506,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
atPos(pos) {
- New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), ListOfNil)
+ New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), Nil)
}
mods1 = mods1 withAnnotations List(annot)
skipTo(SEMI)
@@ -542,7 +542,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
* these potential definitions are real or not.
*/
def fieldDecls(pos: Position, mods: Modifiers, tpt: Tree, name: Name): List[Tree] = {
- val buf = ListBuffer[Tree](varDecl(pos, mods, tpt, name))
+ val buf = ListBuffer[Tree](varDecl(pos, mods, tpt, name.toTermName))
val maybe = new ListBuffer[Tree] // potential variable definitions.
while (in.token == COMMA) {
in.nextToken
@@ -550,10 +550,10 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val name = ident()
if (in.token == ASSIGN || in.token == SEMI) { // ... followed by a `=` or `;`, we know it's a real variable definition
buf ++= maybe
- buf += varDecl(in.currentPos, mods, tpt.duplicate, name)
+ buf += varDecl(in.currentPos, mods, tpt.duplicate, name.toTermName)
maybe.clear()
} else if (in.token == COMMA) { // ... if there's a comma after the ident, it could be a real vardef or not.
- maybe += varDecl(in.currentPos, mods, tpt.duplicate, name)
+ maybe += varDecl(in.currentPos, mods, tpt.duplicate, name.toTermName)
} else { // ... if there's something else we were still in the initializer of the
// previous var def; skip to next comma or semicolon.
skipTo(COMMA, SEMI)
@@ -830,7 +830,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
// The STABLE flag is to signal to namer that this was read from a
// java enum, and so should be given a Constant type (thereby making
// it usable in annotations.)
- ValDef(Modifiers(Flags.STABLE | Flags.JAVA | Flags.STATIC), name, enumType, blankExpr)
+ ValDef(Modifiers(Flags.STABLE | Flags.JAVA | Flags.STATIC), name.toTermName, enumType, blankExpr)
}
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index cf6579a696..8f964cf9e1 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -69,10 +69,6 @@ trait ScalaSettings extends AbsScalaSettings
* -X "Advanced" settings
*/
val Xhelp = BooleanSetting ("-X", "Print a synopsis of advanced options.")
- val assemname = StringSetting ("-Xassem-name", "file", "(Requires -target:msil) Name of the output assembly.", "").dependsOn(target, "msil")
- val assemrefs = StringSetting ("-Xassem-path", "path", "(Requires -target:msil) List of assemblies referenced by the program.", ".").dependsOn(target, "msil")
- val assemextdirs = StringSetting ("-Xassem-extdirs", "dirs", "(Requires -target:msil) List of directories containing assemblies. default:lib", Defaults.scalaLibDir.path).dependsOn(target, "msil")
- val sourcedir = StringSetting ("-Xsourcedir", "directory", "(Requires -target:msil) Mirror source folder structure in output directory.", ".").dependsOn(target, "msil")
val checkInit = BooleanSetting ("-Xcheckinit", "Wrap field accessors to throw an exception on uninitialized access.")
val developer = BooleanSetting ("-Xdev", "Indicates user is a developer - issue warnings about anything which seems amiss")
val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions or assumptions.")
diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
index 98ef74aee3..9338d9e5b5 100644
--- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
@@ -41,8 +41,7 @@ trait StandardScalaSettings {
val optimise: BooleanSetting // depends on post hook which mutates other settings
val print = BooleanSetting ("-print", "Print program with Scala-specific features removed.")
val target = ChoiceSetting ("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
- List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "msil"),
- "jvm-1.6")
+ List("jvm-1.5", "jvm-1.6", "jvm-1.7"), "jvm-1.6")
val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
val uniqid = BooleanSetting ("-uniqid", "Uniquely tag all identifiers in debugging output.")
val usejavacp = BooleanSetting ("-usejavacp", "Utilize the java.class.path in classpath resolution.")
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 19502f0d7e..bbff03f67f 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -12,7 +12,7 @@ import scala.tools.nsc.util.{ ClassPath }
import classfile.ClassfileParser
import scala.reflect.internal.MissingRequirementError
import scala.reflect.internal.util.Statistics
-import scala.tools.nsc.io.{ AbstractFile, MsilFile }
+import scala.tools.nsc.io.{ AbstractFile }
/** This class ...
*
@@ -152,7 +152,7 @@ abstract class SymbolLoaders {
def sourcefile: Option[AbstractFile] = None
/**
- * Description of the resource (ClassPath, AbstractFile, MsilFile)
+ * Description of the resource (ClassPath, AbstractFile)
* being processed by this loader
*/
protected def description: String
@@ -265,16 +265,6 @@ abstract class SymbolLoaders {
override def sourcefile: Option[AbstractFile] = classfileParser.srcfile
}
- class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader with FlagAssigningCompleter {
- private def typ = msilFile.msilType
- private object typeParser extends clr.TypeParser {
- val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
- }
-
- protected def description = "MsilFile "+ typ.FullName + ", assembly "+ typ.Assembly.FullName
- protected def doComplete(root: Symbol) { typeParser.parse(typ, root) }
- }
-
class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter {
protected def description = "source file "+ srcfile.toString
override def fromSource = true
@@ -287,11 +277,6 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) { root.sourceModule.initialize }
}
- object clrTypes extends clr.CLRTypes {
- val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
- if (global.forMSIL) init()
- }
-
/** used from classfile parser to avoid cyclies */
var parentsLevel = 0
var pendingLoadActions: List[() => Unit] = Nil
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 6d213af2b6..cb58111b51 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -252,8 +252,8 @@ abstract class ClassfileParser {
} else {
log("Couldn't find " + name + ": " + tpe + " inside: \n" + ownerTpe)
f = tpe match {
- case MethodType(_, _) => owner.newMethod(name, owner.pos)
- case _ => owner.newVariable(name, owner.pos)
+ case MethodType(_, _) => owner.newMethod(name.toTermName, owner.pos)
+ case _ => owner.newVariable(name.toTermName, owner.pos)
}
f setInfo tpe
log("created fake member " + f.fullName)
@@ -282,7 +282,7 @@ abstract class ClassfileParser {
if (in.buf(start).toInt != CONSTANT_NAMEANDTYPE) errorBadTag(start)
val name = getName(in.getChar(start + 1).toInt)
// create a dummy symbol for method types
- val dummySym = ownerTpe.typeSymbol.newMethod(name, ownerTpe.typeSymbol.pos)
+ val dummySym = ownerTpe.typeSymbol.newMethod(name.toTermName, ownerTpe.typeSymbol.pos)
var tpe = getType(dummySym, in.getChar(start + 3).toInt)
// fix the return type, which is blindly set to the class currently parsed
@@ -457,7 +457,7 @@ abstract class ClassfileParser {
ss = name.subName(start, end)
sym = owner.info.decls lookup ss
if (sym == NoSymbol) {
- sym = owner.newPackage(ss) setInfo completer
+ sym = owner.newPackage(ss.toTermName) setInfo completer
sym.moduleClass setInfo completer
owner.info.decls enter sym
}
@@ -604,7 +604,7 @@ abstract class ClassfileParser {
} else {
val name = pool.getName(in.nextChar)
val info = pool.getType(in.nextChar)
- val sym = getOwner(jflags).newValue(name, NoPosition, sflags)
+ val sym = getOwner(jflags).newValue(name.toTermName, NoPosition, sflags)
val isEnum = (jflags & JAVA_ACC_ENUM) != 0
sym setInfo {
@@ -639,7 +639,7 @@ abstract class ClassfileParser {
in.skip(4); skipAttributes()
} else {
val name = pool.getName(in.nextChar)
- val sym = getOwner(jflags).newMethod(name, NoPosition, sflags)
+ val sym = getOwner(jflags).newMethod(name.toTermName, NoPosition, sflags)
var info = pool.getType(sym, (in.nextChar))
if (name == nme.CONSTRUCTOR)
info match {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index b5459ec773..79b08bcabf 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -80,7 +80,7 @@ abstract class ICodeReader extends ClassfileParser {
val jflags = in.nextChar
val name = pool getName in.nextChar
val owner = getOwner(jflags)
- val dummySym = owner.newMethod(name, owner.pos, toScalaMethodFlags(jflags))
+ val dummySym = owner.newMethod(name.toTermName, owner.pos, toScalaMethodFlags(jflags))
try {
val ch = in.nextChar
@@ -94,7 +94,7 @@ abstract class ICodeReader extends ClassfileParser {
if (sym == NoSymbol)
sym = owner.info.findMember(newTermName(name + nme.LOCAL_SUFFIX_STRING), 0, 0, false).suchThat(_.tpe =:= tpe)
if (sym == NoSymbol) {
- sym = if (field) owner.newValue(name, owner.pos, toScalaFieldFlags(jflags)) else dummySym
+ sym = if (field) owner.newValue(name.toTermName, owner.pos, toScalaFieldFlags(jflags)) else dummySym
sym setInfoAndEnter tpe
log(s"ICodeReader could not locate ${name.decode} in $owner. Created ${sym.defString}.")
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 42ea7e61f0..caa45ea6db 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -206,7 +206,7 @@ abstract class Pickler extends SubComponent {
case RefinedType(parents, decls) =>
val rclazz = tp.typeSymbol
for (m <- decls.iterator)
- if (m.owner != rclazz) assert(false, "bad refinement member "+m+" of "+tp+", owner = "+m.owner)
+ if (m.owner != rclazz) abort("bad refinement member "+m+" of "+tp+", owner = "+m.owner)
putSymbol(rclazz); putTypes(parents); putSymbols(decls.toList)
case ClassInfoType(parents, decls, clazz) =>
putSymbol(clazz); putTypes(parents); putSymbols(decls.toList)
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
deleted file mode 100644
index 624db027f1..0000000000
--- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
+++ /dev/null
@@ -1,132 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2004-2013 LAMP/EPFL
- */
-
-
-package scala.tools.nsc
-package symtab
-package clr
-
-import ch.epfl.lamp.compiler.msil._
-import scala.collection.{ mutable, immutable }
-
-/**
- * Collects all types from all reference assemblies.
- */
-abstract class CLRTypes {
-
- val global: Global
- import global.Symbol
-
- //##########################################################################
-
- var BYTE: Type = _
- var UBYTE: Type = _
- var SHORT: Type = _
- var USHORT: Type = _
- var CHAR: Type = _
- var INT: Type = _
- var UINT: Type = _
- var LONG: Type = _
- var ULONG: Type = _
- var FLOAT: Type = _
- var DOUBLE: Type = _
- var BOOLEAN: Type = _
- var VOID: Type = _
- var ENUM: Type = _
- var DELEGATE: Type = _
-
- var OBJECT: Type = _
- var STRING: Type = _
- var STRING_ARRAY: Type = _
-
- var VALUE_TYPE: Type = _
-
- var SCALA_SYMTAB_ATTR: Type = _
- var SYMTAB_CONSTR: ConstructorInfo = _
- var SYMTAB_DEFAULT_CONSTR: ConstructorInfo = _
-
- var DELEGATE_COMBINE: MethodInfo = _
- var DELEGATE_REMOVE: MethodInfo = _
-
- val types: mutable.Map[Symbol,Type] = new mutable.HashMap
- val constructors: mutable.Map[Symbol,ConstructorInfo] = new mutable.HashMap
- val methods: mutable.Map[Symbol,MethodInfo] = new mutable.HashMap
- val fields: mutable.Map[Symbol, FieldInfo] = new mutable.HashMap
- val sym2type: mutable.Map[Type,Symbol] = new mutable.HashMap
- val addressOfViews = new mutable.HashSet[Symbol]
- val mdgptrcls4clssym: mutable.Map[ /*cls*/ Symbol, /*cls*/ Symbol] = new mutable.HashMap
-
- def isAddressOf(msym : Symbol) = addressOfViews.contains(msym)
-
- def isNonEnumValuetype(cls: Symbol) = {
- val msilTOpt = types.get(cls)
- val res = msilTOpt.isDefined && {
- val msilT = msilTOpt.get
- msilT.IsValueType && !msilT.IsEnum
- }
- res
- }
-
- def isValueType(cls: Symbol): Boolean = {
- val opt = types.get(cls)
- opt.isDefined && opt.get.IsValueType
- }
-
- def init() = try { // initialize
- // the MsilClasspath (nsc/util/Classpath.scala) initializes the msil-library by calling
- // Assembly.LoadFrom("mscorlib.dll"), so this type should be found
- Type.initMSCORLIB(getTypeSafe("System.String").Assembly)
-
- BYTE = getTypeSafe("System.SByte")
- UBYTE = getTypeSafe("System.Byte")
- CHAR = getTypeSafe("System.Char")
- SHORT = getTypeSafe("System.Int16")
- USHORT = getTypeSafe("System.UInt16")
- INT = getTypeSafe("System.Int32")
- UINT = getTypeSafe("System.UInt32")
- LONG = getTypeSafe("System.Int64")
- ULONG = getTypeSafe("System.UInt64")
- FLOAT = getTypeSafe("System.Single")
- DOUBLE = getTypeSafe("System.Double")
- BOOLEAN = getTypeSafe("System.Boolean")
- VOID = getTypeSafe("System.Void")
- ENUM = getTypeSafe("System.Enum")
- DELEGATE = getTypeSafe("System.MulticastDelegate")
-
- OBJECT = getTypeSafe("System.Object")
- STRING = getTypeSafe("System.String")
- STRING_ARRAY = getTypeSafe("System.String[]")
- VALUE_TYPE = getTypeSafe("System.ValueType")
-
- SCALA_SYMTAB_ATTR = getTypeSafe("scala.runtime.SymtabAttribute")
- val bytearray: Array[Type] = Array(Type.GetType("System.Byte[]"))
- SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray)
- SYMTAB_DEFAULT_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes)
-
- val delegate: Type = getTypeSafe("System.Delegate")
- val dargs: Array[Type] = Array(delegate, delegate)
- DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs)
- DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs)
- }
- catch {
- case e: RuntimeException =>
- Console.println(e.getMessage)
- throw e
- }
-
- //##########################################################################
- // type mapping and lookup
-
- def getType(name: String): Type = Type.GetType(name)
-
- def getTypeSafe(name: String): Type = {
- val t = Type.GetType(name)
- assert(t != null, name)
- t
- }
-
- def mkArrayType(elemType: Type): Type = getType(elemType.FullName + "[]")
-
- def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE }
-} // CLRTypes
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
deleted file mode 100644
index f0e49ce500..0000000000
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ /dev/null
@@ -1,849 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2004-2013 LAMP/EPFL
- */
-
-package scala.tools.nsc
-package symtab
-package clr
-
-import java.io.IOException
-import io.MsilFile
-import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _}
-import scala.collection.{ mutable, immutable }
-import scala.reflect.internal.pickling.UnPickler
-import ch.epfl.lamp.compiler.msil.Type.TMVarUsage
-
-/**
- * @author Nikolay Mihaylov
- */
-abstract class TypeParser {
-
- val global: Global
-
- import global._
- import loaders.clrTypes
-
- //##########################################################################
-
- private var clazz: Symbol = _
- private var instanceDefs: Scope = _ // was members
- private var staticModule: Symbol = _ // was staticsClass
- private var staticDefs: Scope = _ // was statics
-
- protected def statics: Symbol = staticModule.moduleClass
-
- protected var busy: Boolean = false // lock to detect recursive reads
-
- private object unpickler extends UnPickler {
- val global: TypeParser.this.global.type = TypeParser.this.global
- }
-
- def parse(typ: MSILType, root: Symbol) {
-
- def handleError(e: Throwable) = {
- if (settings.debug.value) e.printStackTrace() //debug
- throw new IOException("type '" + typ.FullName + "' is broken\n(" + e.getMessage() + ")")
- }
- assert(!busy)
- busy = true
-
- if (root.isModule) {
- this.clazz = root.companionClass
- this.staticModule = root
- } else {
- this.clazz = root
- this.staticModule = root.companionModule
- }
- try {
- parseClass(typ)
- } catch {
- case e: FatalError => handleError(e)
- case e: RuntimeException => handleError(e)
- }
- busy = false
- }
-
- class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType with FlagAgnosticCompleter {
- override def complete(sym: Symbol) { throw new AssertionError("cyclic type dereferencing") }
- }
-
- /* the names `classTParams` and `newTParams` stem from the forJVM version (ClassfileParser.sigToType())
- * but there are differences that should be kept in mind.
- * forMSIL, a nested class knows nothing about any type-params in the nesting class,
- * therefore newTParams is redundant (other than for recording lexical order),
- * it always contains the same elements as classTParams.value */
- val classTParams = scala.collection.mutable.Map[Int,Symbol]() // TODO should this be a stack? (i.e., is it possible for >1 invocation to getCLRType on the same TypeParser instance be active )
- val newTParams = new scala.collection.mutable.ListBuffer[Symbol]()
- val methodTParams = scala.collection.mutable.Map[Int,Symbol]()
-
- private def sig2typeBounds(tvarCILDef: GenericParamAndConstraints): Type = {
- val ts = new scala.collection.mutable.ListBuffer[Type]
- for (cnstrnt <- tvarCILDef.Constraints) {
- ts += getCLRType(cnstrnt) // TODO we're definitely not at or after erasure, no need to call objToAny, right?
- }
- TypeBounds.upper(intersectionType(ts.toList, clazz))
- // TODO variance???
- }
-
- private def createViewFromTo(viewSuffix : String, fromTpe : Type, toTpe : Type,
- addToboxMethodMap : Boolean, isAddressOf : Boolean) : Symbol = {
- val flags = Flags.JAVA | Flags.STATIC | Flags.IMPLICIT; // todo: static? shouldn't be final instead?
- val viewMethodType = (msym: Symbol) => JavaMethodType(msym.newSyntheticValueParams(List(fromTpe)), toTpe)
- val vmsym = createMethod(nme.view_ + viewSuffix, flags, viewMethodType, null, true);
- // !!! this used to mutate a mutable map in definitions, but that map became
- // immutable and this kept "working" with a no-op. So now it's commented out
- // since I retired the deprecated code which allowed for that bug.
- //
- // if (addToboxMethodMap) definitions.boxMethod(clazz) = vmsym
-
- if (isAddressOf) clrTypes.addressOfViews += vmsym
- vmsym
- }
-
- private def createDefaultConstructor(typ: MSILType) {
- val attrs = MethodAttributes.Public | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName // TODO instance
- val declType= typ
- val method = new ConstructorInfo(declType, attrs, Array[MSILType]())
- val flags = Flags.JAVA
- val owner = clazz
- val methodSym = owner.newMethod(nme.CONSTRUCTOR, NoPosition, flags)
- val rettype = clazz.tpe
- val mtype = methodType(Array[MSILType](), rettype);
- val mInfo = mtype(methodSym)
- methodSym.setInfo(mInfo)
- instanceDefs.enter(methodSym);
- clrTypes.constructors(methodSym) = method
- }
-
- private def parseClass(typ: MSILType) {
-
- {
- val t4c = clrTypes.types.get(clazz)
- assert(t4c == None || t4c == Some(typ))
- }
- clrTypes.types(clazz) = typ
-
- {
- val c4t = clrTypes.sym2type.get(typ)
- assert(c4t == None || c4t == Some(clazz))
- }
- clrTypes.sym2type(typ) = clazz
-
- if (typ.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) {
- val attrs = typ.GetCustomAttributes(clrTypes.SCALA_SYMTAB_ATTR, false);
- assert (attrs.length == 1, attrs.length);
- val a = attrs(0).asInstanceOf[MSILAttribute];
- assert (a.getConstructor() == clrTypes.SYMTAB_CONSTR);
- val symtab = a.getConstructorArguments()(0).asInstanceOf[Array[Byte]]
- unpickler.unpickle(symtab, 0, clazz, staticModule, typ.FullName);
- val mClass = clrTypes.getType(typ.FullName + "$");
- if (mClass != null) {
- clrTypes.types(statics) = mClass;
- val moduleInstance = mClass.GetField("MODULE$");
- assert (moduleInstance != null, mClass);
- clrTypes.fields(statics) = moduleInstance;
- }
- return
- }
- val flags = translateAttributes(typ)
-
- var clazzBoxed : Symbol = NoSymbol
- var clazzMgdPtr : Symbol = NoSymbol
-
- val canBeTakenAddressOf = (typ.IsValueType || typ.IsEnum) && (typ.FullName != "System.Enum")
-
- if(canBeTakenAddressOf) {
- clazzBoxed = clazz.owner.newClass(clazz.name.toTypeName append newTypeName("Boxed"))
- clazzMgdPtr = clazz.owner.newClass(clazz.name.toTypeName append newTypeName("MgdPtr"))
- clrTypes.mdgptrcls4clssym(clazz) = clazzMgdPtr
- /* adding typMgdPtr to clrTypes.sym2type should happen early (before metadata for supertypes is parsed,
- before metadata for members are parsed) so that clazzMgdPtr can be found by getClRType. */
- val typMgdPtr = MSILType.mkByRef(typ)
- clrTypes.types(clazzMgdPtr) = typMgdPtr
- clrTypes.sym2type(typMgdPtr) = clazzMgdPtr
- /* clazzMgdPtr but not clazzBoxed is mapped by clrTypes.types into an msil.Type instance,
- because there's no metadata-level representation for a "boxed valuetype" */
- val instanceDefsMgdPtr = newScope
- val classInfoMgdPtr = ClassInfoType(definitions.anyvalparam, instanceDefsMgdPtr, clazzMgdPtr)
- clazzMgdPtr.setFlag(flags)
- clazzMgdPtr.setInfo(classInfoMgdPtr)
- }
-
-/* START CLR generics (snippet 1) */
- // first pass
- for (tvarCILDef <- typ.getSortedTVars() ) {
- val tpname = newTypeName(tvarCILDef.Name.replaceAll("!", "")) // TODO are really all type-params named in all assemblies out there? (NO)
- val tpsym = clazz.newTypeParameter(tpname)
- classTParams.put(tvarCILDef.Number, tpsym)
- newTParams += tpsym
- // TODO wouldn't the following also be needed later, i.e. during getCLRType
- tpsym.setInfo(definitions.AnyClass.tpe)
- }
- // second pass
- for (tvarCILDef <- typ.getSortedTVars() ) {
- val tpsym = classTParams(tvarCILDef.Number)
- tpsym.setInfo(sig2typeBounds(tvarCILDef)) // we never skip bounds unlike in forJVM
- }
-/* END CLR generics (snippet 1) */
- val ownTypeParams = newTParams.toList
-/* START CLR generics (snippet 2) */
- if (!ownTypeParams.isEmpty) {
- clazz.setInfo(new TypeParamsType(ownTypeParams))
- if(typ.IsValueType && !typ.IsEnum) {
- clazzBoxed.setInfo(new TypeParamsType(ownTypeParams))
- }
- }
-/* END CLR generics (snippet 2) */
- instanceDefs = newScope
- staticDefs = newScope
-
- val classInfoAsInMetadata = {
- val ifaces: Array[MSILType] = typ.getInterfaces()
- val superType = if (typ.BaseType() != null) getCLRType(typ.BaseType())
- else if (typ.IsInterface()) definitions.ObjectClass.tpe
- else definitions.AnyClass.tpe; // this branch activates for System.Object only.
- // parents (i.e., base type and interfaces)
- val parents = new scala.collection.mutable.ListBuffer[Type]()
- parents += superType
- for (iface <- ifaces) {
- parents += getCLRType(iface) // here the variance doesn't matter
- }
- // methods, properties, events, fields are entered in a moment
- if (canBeTakenAddressOf) {
- val instanceDefsBoxed = newScope
- ClassInfoType(parents.toList, instanceDefsBoxed, clazzBoxed)
- } else
- ClassInfoType(parents.toList, instanceDefs, clazz)
- }
-
- val staticInfo = ClassInfoType(List(), staticDefs, statics)
-
- clazz.setFlag(flags)
-
- if (canBeTakenAddressOf) {
- clazzBoxed.setInfo( if (ownTypeParams.isEmpty) classInfoAsInMetadata
- else genPolyType(ownTypeParams, classInfoAsInMetadata) )
- clazzBoxed.setFlag(flags)
- val rawValueInfoType = ClassInfoType(definitions.anyvalparam, instanceDefs, clazz)
- clazz.setInfo( if (ownTypeParams.isEmpty) rawValueInfoType
- else genPolyType(ownTypeParams, rawValueInfoType) )
- } else {
- clazz.setInfo( if (ownTypeParams.isEmpty) classInfoAsInMetadata
- else genPolyType(ownTypeParams, classInfoAsInMetadata) )
- }
-
- // TODO I don't remember if statics.setInfo and staticModule.setInfo should also know about type params
- statics.setFlag(Flags.JAVA)
- statics.setInfo(staticInfo)
- staticModule.setFlag(Flags.JAVA)
- staticModule.setInfo(statics.tpe)
-
-
- if (canBeTakenAddressOf) {
- // implicit conversions are owned by staticModule.moduleClass
- createViewFromTo("2Boxed", clazz.tpe, clazzBoxed.tpe, addToboxMethodMap = true, isAddressOf = false)
- // createViewFromTo("2Object", clazz.tpe, definitions.ObjectClass.tpe, addToboxMethodMap = true, isAddressOf = false)
- createViewFromTo("2MgdPtr", clazz.tpe, clazzMgdPtr.tpe, addToboxMethodMap = false, isAddressOf = true)
- // a return can't have type managed-pointer, thus a dereference-conversion is not needed
- // similarly, a method can't declare as return type "boxed valuetype"
- if (!typ.IsEnum) {
- // a synthetic default constructor for raw-type allows `new X' syntax
- createDefaultConstructor(typ)
- }
- }
-
- // import nested types
- for (ntype <- typ.getNestedTypes() if !(ntype.IsNestedPrivate || ntype.IsNestedAssembly || ntype.IsNestedFamANDAssem)
- || ntype.IsInterface /* TODO why shouldn't nested ifaces be type-parsed too? */ )
- {
- val loader = new loaders.MsilFileLoader(new MsilFile(ntype))
- val nclazz = statics.newClass(ntype.Name)
- val nmodule = statics.newModule(ntype.Name)
- nclazz.setInfo(loader)
- nmodule.setInfo(loader)
- staticDefs.enter(nclazz)
- staticDefs.enter(nmodule)
-
- assert(nclazz.companionModule == nmodule, nmodule)
- assert(nmodule.companionClass == nclazz, nclazz)
- }
-
- val fields = typ.getFields()
- for (field <- fields
- if !(field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly)
- if (getCLRType(field.FieldType) != null)
- ) {
- assert (!field.FieldType.IsPointer && !field.FieldType.IsByRef, "CLR requirement")
- val flags = translateAttributes(field);
- val name = newTermName(field.Name);
- val fieldType =
- if (field.IsLiteral && !field.FieldType.IsEnum && isDefinedAtgetConstant(getCLRType(field.FieldType)))
- ConstantType(getConstant(getCLRType(field.FieldType), field.getValue))
- else
- getCLRType(field.FieldType)
- val owner = if (field.IsStatic()) statics else clazz;
- val sym = owner.newValue(name, NoPosition, flags).setInfo(fieldType);
- // TODO: set private within!!! -> look at typechecker/Namers.scala
- (if (field.IsStatic()) staticDefs else instanceDefs).enter(sym);
- clrTypes.fields(sym) = field;
- }
-
- for (constr <- typ.getConstructors() if !constr.IsStatic() && !constr.IsPrivate() &&
- !constr.IsAssembly() && !constr.IsFamilyAndAssembly() && !constr.HasPtrParamOrRetType())
- createMethod(constr);
-
- // initially also contains getters and setters of properties.
- val methodsSet = new mutable.HashSet[MethodInfo]();
- methodsSet ++= typ.getMethods();
-
- for (prop <- typ.getProperties) {
- val propType: Type = getCLSType(prop.PropertyType);
- if (propType != null) {
- val getter: MethodInfo = prop.GetGetMethod(true);
- val setter: MethodInfo = prop.GetSetMethod(true);
- var gparamsLength: Int = -1;
- if (!(getter == null || getter.IsPrivate || getter.IsAssembly
- || getter.IsFamilyAndAssembly || getter.HasPtrParamOrRetType))
- {
- assert(prop.PropertyType == getter.ReturnType);
- val gparams: Array[ParameterInfo] = getter.GetParameters();
- gparamsLength = gparams.length;
- val name: TermName = if (gparamsLength == 0) prop.Name else nme.apply;
- val flags = translateAttributes(getter);
- val owner: Symbol = if (getter.IsStatic) statics else clazz;
- val methodSym = owner.newMethod(name, NoPosition, flags)
- val mtype: Type = if (gparamsLength == 0) NullaryMethodType(propType) // .NET properties can't be polymorphic
- else methodType(getter, getter.ReturnType)(methodSym)
- methodSym.setInfo(mtype);
- methodSym.setFlag(Flags.ACCESSOR);
- (if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym)
- clrTypes.methods(methodSym) = getter;
- methodsSet -= getter;
- }
- if (!(setter == null || setter.IsPrivate || setter.IsAssembly
- || setter.IsFamilyAndAssembly || setter.HasPtrParamOrRetType))
- {
- val sparams: Array[ParameterInfo] = setter.GetParameters()
- if(getter != null)
- assert(getter.IsStatic == setter.IsStatic);
- assert(setter.ReturnType == clrTypes.VOID);
- if(getter != null)
- assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);
-
- val name: TermName = if (gparamsLength == 0) nme.getterToSetter(prop.Name)
- else nme.update;
- val flags = translateAttributes(setter);
- val mtype = methodType(setter, definitions.UnitClass.tpe);
- val owner: Symbol = if (setter.IsStatic) statics else clazz;
- val methodSym = owner.newMethod(name, NoPosition, flags)
- methodSym.setInfo(mtype(methodSym))
- methodSym.setFlag(Flags.ACCESSOR);
- (if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym);
- clrTypes.methods(methodSym) = setter;
- methodsSet -= setter;
- }
- }
- }
-
-/* for (event <- typ.GetEvents) {
- // adding += and -= methods to add delegates to an event.
- // raising the event ist not possible from outside the class (this is so
- // generally in .net world)
- val adder: MethodInfo = event.GetAddMethod();
- val remover: MethodInfo = event.GetRemoveMethod();
- if (!(adder == null || adder.IsPrivate || adder.IsAssembly
- || adder.IsFamilyAndAssembly))
- {
- assert(adder.ReturnType == clrTypes.VOID);
- assert(adder.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
- val name = encode("+=");
- val flags = translateAttributes(adder);
- val mtype: Type = methodType(adder, adder.ReturnType);
- createMethod(name, flags, mtype, adder, adder.IsStatic)
- methodsSet -= adder;
- }
- if (!(remover == null || remover.IsPrivate || remover.IsAssembly
- || remover.IsFamilyAndAssembly))
- {
- assert(remover.ReturnType == clrTypes.VOID);
- assert(remover.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));
- val name = encode("-=");
- val flags = translateAttributes(remover);
- val mtype: Type = methodType(remover, remover.ReturnType);
- createMethod(name, flags, mtype, remover, remover.IsStatic)
- methodsSet -= remover;
- }
- } */
-
-/* Adds view amounting to syntax sugar for a CLR implicit overload.
- The long-form syntax can also be supported if "methodsSet -= method" (last statement) is removed.
-
- /* remember, there's typ.getMethods and type.GetMethods */
- for (method <- typ.getMethods)
- if(!method.HasPtrParamOrRetType &&
- method.IsPublic && method.IsStatic && method.IsSpecialName &&
- method.Name == "op_Implicit") {
- // create a view: typ => method's return type
- val viewRetType: Type = getCLRType(method.ReturnType)
- val viewParamTypes: List[Type] = method.GetParameters().map(_.ParameterType).map(getCLSType).toList;
- /* The spec says "The operator method shall be defined as a static method on either the operand or return type."
- * We don't consider the declaring type for the purposes of definitions.functionType,
- * instead we regard op_Implicit's argument type and return type as defining the view's signature.
- */
- if (viewRetType != null && !viewParamTypes.contains(null)) {
- /* The check above applies e.g. to System.Decimal that has a conversion from UInt16, a non-CLS type, whose CLS-mapping returns null */
- val funType: Type = definitions.functionType(viewParamTypes, viewRetType);
- val flags = Flags.JAVA | Flags.STATIC | Flags.IMPLICIT; // todo: static? shouldn't be final instead?
- val viewMethodType = (msym: Symbol) => JavaMethodType(msym.newSyntheticValueParams(viewParamTypes), funType)
- val vmsym = createMethod(nme.view_, flags, viewMethodType, method, true);
- methodsSet -= method;
- }
- }
-*/
-
- for (method <- methodsSet.iterator)
- if (!method.IsPrivate() && !method.IsAssembly() && !method.IsFamilyAndAssembly()
- && !method.HasPtrParamOrRetType)
- createMethod(method);
-
- // Create methods and views for delegate support
- if (clrTypes.isDelegateType(typ)) {
- createDelegateView(typ)
- createDelegateChainers(typ)
- }
-
- // for enumerations introduce comparison and bitwise logical operations;
- // the backend will recognize them and replace them with comparison or
- // bitwise logical operations on the primitive underlying type
-
- if (typ.IsEnum) {
- val ENUM_CMP_NAMES = List(nme.EQ, nme.NE, nme.LT, nme.LE, nme.GT, nme.GE);
- val ENUM_BIT_LOG_NAMES = List(nme.OR, nme.AND, nme.XOR);
-
- val flags = Flags.JAVA | Flags.FINAL
- for (cmpName <- ENUM_CMP_NAMES) {
- val enumCmp = clazz.newMethod(cmpName)
- val enumCmpType = JavaMethodType(enumCmp.newSyntheticValueParams(List(clazz.tpe)), definitions.BooleanClass.tpe)
- enumCmp.setFlag(flags).setInfo(enumCmpType)
- instanceDefs.enter(enumCmp)
- }
-
- for (bitLogName <- ENUM_BIT_LOG_NAMES) {
- val enumBitLog = clazz.newMethod(bitLogName)
- val enumBitLogType = JavaMethodType(enumBitLog.newSyntheticValueParams(List(clazz.tpe)), clazz.tpe /* was classInfo, infinite typer */)
- enumBitLog.setFlag(flags).setInfo(enumBitLogType)
- instanceDefs.enter(enumBitLog)
- }
- }
-
- } // parseClass
-
- private def populateMethodTParams(method: MethodBase, methodSym: MethodSymbol) : List[Symbol] = {
- if(!method.IsGeneric) Nil
- else {
- methodTParams.clear
- val newMethodTParams = new scala.collection.mutable.ListBuffer[Symbol]()
-
- // first pass
- for (mvarCILDef <- method.getSortedMVars() ) {
- val mtpname = newTypeName(mvarCILDef.Name.replaceAll("!", "")) // TODO are really all method-level-type-params named in all assemblies out there? (NO)
- val mtpsym = methodSym.newTypeParameter(mtpname)
- methodTParams.put(mvarCILDef.Number, mtpsym)
- newMethodTParams += mtpsym
- // TODO wouldn't the following also be needed later, i.e. during getCLRType
- mtpsym.setInfo(definitions.AnyClass.tpe)
- }
- // second pass
- for (mvarCILDef <- method.getSortedMVars() ) {
- val mtpsym = methodTParams(mvarCILDef.Number)
- mtpsym.setInfo(sig2typeBounds(mvarCILDef)) // we never skip bounds unlike in forJVM
- }
-
- newMethodTParams.toList
- }
- }
-
- private def createMethod(method: MethodBase) {
-
- val flags = translateAttributes(method);
- val owner = if (method.IsStatic()) statics else clazz;
- val methodSym = owner.newMethod(getName(method), NoPosition, flags)
- /* START CLR generics (snippet 3) */
- val newMethodTParams = populateMethodTParams(method, methodSym)
- /* END CLR generics (snippet 3) */
-
- val rettype = if (method.IsConstructor()) clazz.tpe
- else getCLSType(method.asInstanceOf[MethodInfo].ReturnType);
- if (rettype == null) return;
- val mtype = methodType(method, rettype);
- if (mtype == null) return;
-/* START CLR generics (snippet 4) */
- val mInfo = if (method.IsGeneric) genPolyType(newMethodTParams, mtype(methodSym))
- else mtype(methodSym)
-/* END CLR generics (snippet 4) */
-/* START CLR non-generics (snippet 4)
- val mInfo = mtype(methodSym)
- END CLR non-generics (snippet 4) */
- methodSym.setInfo(mInfo)
- (if (method.IsStatic()) staticDefs else instanceDefs).enter(methodSym);
- if (method.IsConstructor())
- clrTypes.constructors(methodSym) = method.asInstanceOf[ConstructorInfo]
- else clrTypes.methods(methodSym) = method.asInstanceOf[MethodInfo];
- }
-
- private def createMethod(name: TermName, flags: Long, args: Array[MSILType], retType: MSILType, method: MethodInfo, statik: Boolean): Symbol = {
- val mtype = methodType(args, getCLSType(retType))
- assert(mtype != null)
- createMethod(name, flags, mtype, method, statik)
- }
-
- private def createMethod(name: TermName, flags: Long, mtype: Symbol => Type, method: MethodInfo, statik: Boolean): Symbol = {
- val methodSym: Symbol = (if (statik) statics else clazz).newMethod(name)
- methodSym.setFlag(flags).setInfo(mtype(methodSym))
- (if (statik) staticDefs else instanceDefs).enter(methodSym)
- if (method != null)
- clrTypes.methods(methodSym) = method
- methodSym
- }
-
- private def createDelegateView(typ: MSILType) = {
- val invoke: MethodInfo = typ.GetMember("Invoke")(0).asInstanceOf[MethodInfo];
- val invokeRetType: Type = getCLRType(invoke.ReturnType);
- val invokeParamTypes: List[Type] =invoke.GetParameters().map(_.ParameterType).map(getCLSType).toList;
- val funType: Type = definitions.functionType(invokeParamTypes, invokeRetType);
-
- val typClrType: Type = getCLRType(typ);
- val flags = Flags.JAVA | Flags.STATIC | Flags.IMPLICIT; // todo: static? think not needed
-
- // create the forward view: delegate => function
- val delegateParamTypes: List[Type] = List(typClrType);
- // not ImplicitMethodType, this is for methods with implicit parameters (not implicit methods)
- val forwardViewMethodType = (msym: Symbol) => JavaMethodType(msym.newSyntheticValueParams(delegateParamTypes), funType)
- createMethod(nme.view_, flags, forwardViewMethodType, null, true);
-
- // create the backward view: function => delegate
- val functionParamTypes: List[Type] = List(funType);
- val backwardViewMethodType = (msym: Symbol) => JavaMethodType(msym.newSyntheticValueParams(functionParamTypes), typClrType)
- createMethod(nme.view_, flags, backwardViewMethodType, null, true);
- }
-
- private def createDelegateChainers(typ: MSILType) = {
- val flags: Long = Flags.JAVA | Flags.FINAL
- val args: Array[MSILType] = Array(typ)
-
- var s = createMethod(encode("+="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_COMBINE, false);
- s = createMethod(encode("-="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_REMOVE, false);
-
- s = createMethod(nme.PLUS, flags, args, typ, clrTypes.DELEGATE_COMBINE, false);
- s = createMethod(nme.MINUS, flags, args, typ, clrTypes.DELEGATE_REMOVE, false);
- }
-
- private def getName(method: MethodBase): TermName = {
-
- def operatorOverload(name : String, paramsArity : Int) : Option[Name] = paramsArity match {
- case 1 => name match {
- // PartitionI.10.3.1
- case "op_Decrement" => Some(encode("--"))
- case "op_Increment" => Some(encode("++"))
- case "op_UnaryNegation" => Some(nme.UNARY_-)
- case "op_UnaryPlus" => Some(nme.UNARY_+)
- case "op_LogicalNot" => Some(nme.UNARY_!)
- case "op_OnesComplement" => Some(nme.UNARY_~)
- /* op_True and op_False have no operator symbol assigned,
- Other methods that will have to be written in full are:
- op_AddressOf & (unary)
- op_PointerDereference * (unary) */
- case _ => None
- }
- case 2 => name match {
- // PartitionI.10.3.2
- case "op_Addition" => Some(nme.ADD)
- case "op_Subtraction" => Some(nme.SUB)
- case "op_Multiply" => Some(nme.MUL)
- case "op_Division" => Some(nme.DIV)
- case "op_Modulus" => Some(nme.MOD)
- case "op_ExclusiveOr" => Some(nme.XOR)
- case "op_BitwiseAnd" => Some(nme.AND)
- case "op_BitwiseOr" => Some(nme.OR)
- case "op_LogicalAnd" => Some(nme.ZAND)
- case "op_LogicalOr" => Some(nme.ZOR)
- case "op_LeftShift" => Some(nme.LSL)
- case "op_RightShift" => Some(nme.ASR)
- case "op_Equality" => Some(nme.EQ)
- case "op_GreaterThan" => Some(nme.GT)
- case "op_LessThan" => Some(nme.LT)
- case "op_Inequality" => Some(nme.NE)
- case "op_GreaterThanOrEqual" => Some(nme.GE)
- case "op_LessThanOrEqual" => Some(nme.LE)
-
- /* op_MemberSelection is reserved in Scala */
-
- /* The standard does not assign operator symbols to op_Assign , op_SignedRightShift , op_UnsignedRightShift ,
- * and op_UnsignedRightShiftAssignment so those names will be used instead to invoke those methods. */
-
- /*
- The remaining binary operators are not overloaded in C# and are therefore not in widespread use. They have to be written in full.
-
- op_RightShiftAssignment >>=
- op_MultiplicationAssignment *=
- op_PointerToMemberSelection ->*
- op_SubtractionAssignment -=
- op_ExclusiveOrAssignment ^=
- op_LeftShiftAssignment <<=
- op_ModulusAssignment %=
- op_AdditionAssignment +=
- op_BitwiseAndAssignment &=
- op_BitwiseOrAssignment |=
- op_Comma ,
- op_DivisionAssignment /=
- */
- case _ => None
- }
- case _ => None
- }
-
- if (method.IsConstructor()) return nme.CONSTRUCTOR;
- val name = method.Name;
- if (method.IsStatic()) {
- if(method.IsSpecialName) {
- val paramsArity = method.GetParameters().size
- // handle operator overload, otherwise handle as any static method
- val operName = operatorOverload(name, paramsArity)
- if (operName.isDefined) { return operName.get; }
- }
- return newTermName(name);
- }
- val params = method.GetParameters();
- name match {
- case "GetHashCode" if (params.length == 0) => nme.hashCode_;
- case "ToString" if (params.length == 0) => nme.toString_;
- case "Finalize" if (params.length == 0) => nme.finalize_;
- case "Equals" if (params.length == 1 && params(0).ParameterType == clrTypes.OBJECT) =>
- nme.equals_;
- case "Invoke" if (clrTypes.isDelegateType(method.DeclaringType)) => nme.apply;
- case _ => newTermName(name);
- }
- }
-
- //##########################################################################
-
- private def methodType(method: MethodBase, rettype: MSILType): Symbol => Type = {
- val rtype = getCLSType(rettype);
- if (rtype == null) null else methodType(method, rtype);
- }
-
- /** Return a method type for the given method. */
- private def methodType(method: MethodBase, rettype: Type): Symbol => Type =
- methodType(method.GetParameters().map(_.ParameterType), rettype);
-
- /** Return a method type for the provided argument types and return type. */
- private def methodType(argtypes: Array[MSILType], rettype: Type): Symbol => Type = {
- def paramType(typ: MSILType): Type =
- if (typ eq clrTypes.OBJECT) definitions.AnyClass.tpe // TODO a hack to compile scalalib, should be definitions.AnyRefClass.tpe
- else getCLSType(typ);
- val ptypes = argtypes.map(paramType).toList;
- if (ptypes.contains(null)) null
- else method => JavaMethodType(method.newSyntheticValueParams(ptypes), rettype);
- }
-
- //##########################################################################
-
- private def getClassType(typ: MSILType): Type = {
- assert(typ != null);
- val res = rootMirror.getClassByName(typ.FullName.replace('+', '.') : TypeName).tpe;
- //if (res.isError())
- // global.reporter.error("unknown class reference " + type.FullName);
- res
- }
-
- private def getCLSType(typ: MSILType): Type = { // getCLS returns non-null for types GenMSIL can handle, be they CLS-compliant or not
- if (typ.IsTMVarUsage())
- /* START CLR generics (snippet 5) */
- getCLRType(typ)
- /* END CLR generics (snippet 5) */
- /* START CLR non-generics (snippet 5)
- null
- END CLR non-generics (snippet 5) */
- else if ( /* TODO hack if UBYE, uncommented, "ambiguous reference to overloaded definition" ensues, for example for System.Math.Max(x, y) */
- typ == clrTypes.USHORT || typ == clrTypes.UINT || typ == clrTypes.ULONG
- /* || typ == clrTypes.UBYTE */
- || typ.IsNotPublic() || typ.IsNestedPrivate()
- || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem()
- || typ.IsPointer()
- || (typ.IsArray() && getCLRType(typ.GetElementType()) == null) /* TODO hack: getCLR instead of getCLS */
- || (typ.IsByRef() && !typ.GetElementType().CanBeTakenAddressOf()))
- null
- else
- getCLRType(typ)
- }
-
- private def getCLRTypeIfPrimitiveNullOtherwise(typ: MSILType): Type =
- if (typ == clrTypes.OBJECT)
- definitions.ObjectClass.tpe;
- else if (typ == clrTypes.VALUE_TYPE)
- definitions.AnyValClass.tpe
- else if (typ == clrTypes.STRING)
- definitions.StringClass.tpe;
- else if (typ == clrTypes.VOID)
- definitions.UnitClass.tpe
- else if (typ == clrTypes.BOOLEAN)
- definitions.BooleanClass.tpe
- else if (typ == clrTypes.CHAR)
- definitions.CharClass.tpe
- else if ((typ == clrTypes.BYTE) || (typ == clrTypes.UBYTE)) // TODO U... is a hack to compile scalalib
- definitions.ByteClass.tpe
- else if ((typ == clrTypes.SHORT) || (typ == clrTypes.SHORT)) // TODO U... is a hack to compile scalalib
- definitions.ShortClass.tpe
- else if ((typ == clrTypes.INT) || (typ == clrTypes.UINT)) // TODO U... is a hack to compile scalalib
- definitions.IntClass.tpe
- else if ((typ == clrTypes.LONG) || (typ == clrTypes.LONG)) // TODO U... is a hack to compile scalalib
- definitions.LongClass.tpe
- else if (typ == clrTypes.FLOAT)
- definitions.FloatClass.tpe
- else if (typ == clrTypes.DOUBLE)
- definitions.DoubleClass.tpe
- else null
-
-
- private def getCLRType(tMSIL: MSILType): Type = {
- var res = getCLRTypeIfPrimitiveNullOtherwise(tMSIL)
- if (res != null) res
- else if (tMSIL.isInstanceOf[ConstructedType]) {
- val ct = tMSIL.asInstanceOf[ConstructedType]
- /* START CLR generics (snippet 6) */
- val cttpArgs = ct.typeArgs.map(tmsil => getCLRType(tmsil)).toList
- appliedType(getCLRType(ct.instantiatedType), cttpArgs)
- /* END CLR generics (snippet 6) */
- /* START CLR non-generics (snippet 6)
- getCLRType(ct.instantiatedType)
- END CLR non-generics (snippet 6) */
- } else if (tMSIL.isInstanceOf[TMVarUsage]) {
- /* START CLR generics (snippet 7) */
- val tVarUsage = tMSIL.asInstanceOf[TMVarUsage]
- val tVarNumber = tVarUsage.Number
- if (tVarUsage.isTVar) classTParams(tVarNumber).typeConstructor // shouldn't fail, just return definitions.AnyClass.tpe at worst
- else methodTParams(tVarNumber).typeConstructor // shouldn't fail, just return definitions.AnyClass.tpe at worst
- /* END CLR generics (snippet 7) */
- /* START CLR non-generics (snippet 7)
- null // definitions.ObjectClass.tpe
- END CLR non-generics (snippet 7) */
- } else if (tMSIL.IsArray()) {
- var elemtp = getCLRType(tMSIL.GetElementType())
- // cut&pasted from ClassfileParser
- // make unbounded Array[T] where T is a type variable into Array[T with Object]
- // (this is necessary because such arrays have a representation which is incompatible
- // with arrays of primitive types).
- // TODO does that incompatibility also apply to .NET?
- if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< definitions.ObjectClass.tpe))
- elemtp = intersectionType(List(elemtp, definitions.ObjectClass.tpe))
- appliedType(definitions.ArrayClass.tpe, List(elemtp))
- } else {
- res = clrTypes.sym2type.get(tMSIL) match {
- case Some(sym) => sym.tpe
- case None => if (tMSIL.IsByRef && tMSIL.GetElementType.IsValueType) {
- val addressed = getCLRType(tMSIL.GetElementType)
- val clasym = addressed.typeSymbolDirect // TODO should be .typeSymbol?
- clasym.info.load(clasym)
- val secondAttempt = clrTypes.sym2type.get(tMSIL)
- secondAttempt match { case Some(sym) => sym.tpe
- case None => null
- }
- } else getClassType(tMSIL)
- }
- if (res == null)
- null // TODO new RuntimeException()
- else res
- }
- }
-
- // the values are Java-Box-Classes (e.g. Integer, Boolean, Character)
- // java.lang.Number to get the value (if a number, not for boolean, character)
- // see ch.epfl.lamp.compiler.msil.util.PEStream.java
- def getConstant(constType: Type, value: Object): Constant = {
- val typeClass = constType.typeSymbol
- if (typeClass == definitions.BooleanClass)
- Constant(value.asInstanceOf[java.lang.Boolean].booleanValue)
- else if (typeClass == definitions.ByteClass)
- Constant(value.asInstanceOf[java.lang.Number].byteValue)
- else if (typeClass == definitions.ShortClass)
- Constant(value.asInstanceOf[java.lang.Number].shortValue)
- else if (typeClass == definitions.CharClass)
- Constant(value.asInstanceOf[java.lang.Character].charValue)
- else if (typeClass == definitions.IntClass)
- Constant(value.asInstanceOf[java.lang.Number].intValue)
- else if (typeClass == definitions.LongClass)
- Constant(value.asInstanceOf[java.lang.Number].longValue)
- else if (typeClass == definitions.FloatClass)
- Constant(value.asInstanceOf[java.lang.Number].floatValue)
- else if (typeClass == definitions.DoubleClass)
- Constant(value.asInstanceOf[java.lang.Number].doubleValue)
- else if (typeClass == definitions.StringClass)
- Constant(value.asInstanceOf[java.lang.String])
- else
- abort("illegal value: " + value + ", class-symbol: " + typeClass)
- }
-
- def isDefinedAtgetConstant(constType: Type): Boolean = {
- val typeClass = constType.typeSymbol
- if ( (typeClass == definitions.BooleanClass)
- || (typeClass == definitions.ByteClass)
- || (typeClass == definitions.ShortClass)
- || (typeClass == definitions.CharClass)
- || (typeClass == definitions.IntClass)
- || (typeClass == definitions.LongClass)
- || (typeClass == definitions.FloatClass)
- || (typeClass == definitions.DoubleClass)
- || (typeClass == definitions.StringClass)
- )
- true
- else
- false
- }
-
- private def translateAttributes(typ: MSILType): Long = {
- var flags: Long = Flags.JAVA;
- if (typ.IsNotPublic() || typ.IsNestedPrivate()
- || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem())
- flags = flags | Flags.PRIVATE;
- else if (typ.IsNestedFamily() || typ.IsNestedFamORAssem())
- flags = flags | Flags.PROTECTED;
- if (typ.IsAbstract())
- flags = flags | Flags.ABSTRACT;
- if (typ.IsSealed())
- flags = flags | Flags.FINAL;
- if (typ.IsInterface())
- flags = flags | Flags.INTERFACE | Flags.TRAIT | Flags.ABSTRACT;
-
- flags
- }
-
- private def translateAttributes(field: FieldInfo): Long = {
- var flags: Long = Flags.JAVA;
- if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly())
- flags = flags | Flags.PRIVATE;
- else if (field.IsFamily() || field.IsFamilyOrAssembly())
- flags = flags | Flags.PROTECTED;
- if (field.IsInitOnly() || field.IsLiteral())
- flags = flags | Flags.FINAL;
- else
- flags = flags | Flags.MUTABLE;
- if (field.IsStatic)
- flags = flags | Flags.STATIC
-
- flags
- }
-
- private def translateAttributes(method: MethodBase): Long = {
- var flags: Long = Flags.JAVA;
- if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly())
- flags = flags | Flags.PRIVATE;
- else if (method.IsFamily() || method.IsFamilyOrAssembly())
- flags = flags | Flags.PROTECTED;
- if (method.IsAbstract())
- flags = flags | Flags.DEFERRED;
- if (method.IsStatic)
- flags = flags | Flags.STATIC
-
- flags
- }
-}
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 847ca574a9..39460ef004 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -69,12 +69,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
case "mono-cache" => MONO_CACHE
case "poly-cache" => POLY_CACHE
}
-
- def shouldRewriteTry(tree: Try) = {
- val sym = tree.tpe.typeSymbol
- forMSIL && (sym != UnitClass) && (sym != NothingClass)
- }
-
private def typedWithPos(pos: Position)(tree: Tree) =
localTyper.typedPos(pos)(tree)
@@ -120,7 +114,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
def addStaticMethodToClass(forBody: (Symbol, Symbol) => Tree): Symbol = {
- val methSym = currentClass.newMethod(mkTerm(nme.reflMethodName), ad.pos, STATIC | SYNTHETIC)
+ val methSym = currentClass.newMethod(mkTerm(nme.reflMethodName.toString), ad.pos, STATIC | SYNTHETIC)
val params = methSym.newSyntheticValueParams(List(ClassClass.tpe))
methSym setInfoAndEnter MethodType(params, MethodClass.tpe)
@@ -543,10 +537,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* constructor. */
case Template(parents, self, body) =>
localTyper = typer.atOwner(tree, currentClass)
- if (forMSIL) savingStatics( transformTemplate(tree) )
- else transformTemplate(tree)
+ transformTemplate(tree)
- case Literal(c) if (c.tag == ClazzTag) && !forMSIL=>
+ case Literal(c) if c.tag == ClazzTag =>
val tpe = c.typeValue
typedWithPos(tree.pos) {
if (isPrimitiveValueClass(tpe.typeSymbol)) {
@@ -559,24 +552,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
else tree
}
- /* MSIL requires that the stack is empty at the end of a try-block.
- * Hence, we here rewrite all try blocks with a result != {Unit, All} such that they
- * store their result in a local variable. The catch blocks are adjusted as well.
- * The try tree is subsituted by a block whose result expression is read of that variable. */
- case theTry @ Try(block, catches, finalizer) if shouldRewriteTry(theTry) =>
- def transformTry = {
- val tpe = theTry.tpe.widen
- val tempVar = currentOwner.newVariable(mkTerm(nme.EXCEPTION_RESULT_PREFIX), theTry.pos).setInfo(tpe)
- def assignBlock(rhs: Tree) = super.transform(BLOCK(Ident(tempVar) === transform(rhs)))
-
- val newBlock = assignBlock(block)
- val newCatches = for (CaseDef(pattern, guard, body) <- catches) yield
- (CASE(super.transform(pattern)) IF (super.transform(guard))) ==> assignBlock(body)
- val newTry = Try(newBlock, newCatches, super.transform(finalizer))
-
- typedWithPos(theTry.pos)(BLOCK(VAL(tempVar) === EmptyTree, newTry, Ident(tempVar)))
- }
- transformTry
/*
* This transformation should identify Scala symbol invocations in the tree and replace them
* with references to a static member. Also, whenever a class has at least a single symbol invocation
@@ -645,9 +620,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create a symbol for the static field
val stfieldSym = (
currentClass.newVariable(mkTerm("symbol$"), pos, PRIVATE | STATIC | SYNTHETIC | FINAL)
- setInfo SymbolClass.tpe
+ setInfoAndEnter SymbolClass.tpe
)
- currentClass.info.decls enter stfieldSym
// create field definition and initialization
val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs)
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 323c7c7261..e99b42a402 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -60,7 +60,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// The constructor parameter corresponding to an accessor
def parameter(acc: Symbol): Symbol =
- parameterNamed(nme.getterName(acc.originalName))
+ parameterNamed(nme.getterName(acc.originalName.toTermName))
// The constructor parameter with given name. This means the parameter
// has given name, or starts with given name, and continues with a `$` afterwards.
@@ -68,7 +68,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
def matchesName(param: Symbol) = param.name == name || param.name.startsWith(name + nme.NAME_JOIN_STRING)
(constrParams filter matchesName) match {
- case Nil => assert(false, name + " not in " + constrParams) ; null
+ case Nil => abort(name + " not in " + constrParams)
case p :: _ => p
}
}
@@ -281,7 +281,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
specializedStats find {
case Assign(sel @ Select(This(_), _), rhs) =>
( (sel.symbol hasFlag SPECIALIZED)
- && (nme.unspecializedName(nme.localToGetter(sel.symbol.name)) == nme.localToGetter(sym.name))
+ && (nme.unspecializedName(nme.localToGetter(sel.symbol.name.toTermName)) == nme.localToGetter(sym.name.toTermName))
)
case _ => false
}
@@ -399,7 +399,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
def addGetter(sym: Symbol): Symbol = {
val getr = addAccessor(
- sym, nme.getterName(sym.name), getterFlags(sym.flags))
+ sym, nme.getterName(sym.name.toTermName), getterFlags(sym.flags))
getr setInfo MethodType(List(), sym.tpe)
defBuf += localTyper.typedPos(sym.pos)(DefDef(getr, Select(This(clazz), sym)))
getr
@@ -408,7 +408,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
def addSetter(sym: Symbol): Symbol = {
sym setFlag MUTABLE
val setr = addAccessor(
- sym, nme.getterToSetter(nme.getterName(sym.name)), setterFlags(sym.flags))
+ sym, nme.getterToSetter(nme.getterName(sym.name.toTermName)), setterFlags(sym.flags))
setr setInfo MethodType(setr.newSyntheticValueParams(List(sym.tpe)), UnitClass.tpe)
defBuf += localTyper.typed {
//util.trace("adding setter def for "+setr) {
@@ -511,7 +511,6 @@ abstract class Constructors extends Transform with ast.TreeDSL {
sym = closureClass,
constrMods = Modifiers(0),
vparamss = List(List(outerFieldDef)),
- argss = ListOfNil,
body = List(applyMethodDef),
superPos = impl.pos)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index cfc3d0a377..45bd5cf003 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -437,19 +437,19 @@ abstract class Erasure extends AddInterfaces
noclash = false
unit.error(
if (member.owner == root) member.pos else root.pos,
- s"""bridge generated for member ${fulldef(member)}
- |which overrides ${fulldef(other)}
- |clashes with definition of $what;
- |both have erased type ${exitingPostErasure(bridge.tpe)}""".stripMargin)
+ sm"""bridge generated for member ${fulldef(member)}
+ |which overrides ${fulldef(other)}
+ |clashes with definition of $what;
+ |both have erased type ${exitingPostErasure(bridge.tpe)}""")
}
for (bc <- root.baseClasses) {
if (settings.debug.value)
exitingPostErasure(println(
- s"""check bridge overrides in $bc
- ${bc.info.nonPrivateDecl(bridge.name)}
- ${site.memberType(bridge)}
- ${site.memberType(bc.info.nonPrivateDecl(bridge.name) orElse IntClass)}
- ${(bridge.matchingSymbol(bc, site))}""".stripMargin))
+ sm"""check bridge overrides in $bc
+ |${bc.info.nonPrivateDecl(bridge.name)}
+ |${site.memberType(bridge)}
+ |${site.memberType(bc.info.nonPrivateDecl(bridge.name) orElse IntClass)}
+ |${(bridge.matchingSymbol(bc, site))}"""))
def overriddenBy(sym: Symbol) =
sym.matchingSymbol(bc, site).alternatives filter (sym => !sym.isBridge)
@@ -522,7 +522,7 @@ abstract class Erasure extends AddInterfaces
&& !exitingErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?)
import CODE._
- val _false = FALSE_typed
+ val _false = FALSE
val pt = member.tpe.resultType
lazy val zero =
if (_false.tpe <:< pt) _false
@@ -693,7 +693,7 @@ abstract class Erasure extends AddInterfaces
adaptToType(unbox(tree, pt), pt)
else if (isPrimitiveValueType(tree.tpe) && !isPrimitiveValueType(pt)) {
adaptToType(box(tree, pt.toString), pt)
- } else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) {
+ } else if (isMethodTypeWithEmptyParams(tree.tpe)) {
// [H] this assert fails when trying to typecheck tree !(SomeClass.this.bitmap) for single lazy val
//assert(tree.symbol.isStable, "adapt "+tree+":"+tree.tpe+" to "+pt)
adaptToType(Apply(tree, List()) setPos tree.pos setType tree.tpe.resultType, pt)
@@ -774,16 +774,21 @@ abstract class Erasure extends AddInterfaces
else if (!isPrimitiveValueType(qual1.tpe) && isPrimitiveValueMember(tree.symbol))
qual1 = unbox(qual1, tree.symbol.owner.tpe)
- if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe))
+ def selectFrom(qual: Tree) = treeCopy.Select(tree, qual, name)
+
+ if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe)) {
tree.symbol = NoSymbol
- else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.params.isEmpty) {
+ selectFrom(qual1)
+ } else if (isMethodTypeWithEmptyParams(qual1.tpe)) {
assert(qual1.symbol.isStable, qual1.symbol);
- qual1 = Apply(qual1, List()) setPos qual1.pos setType qual1.tpe.resultType
+ val applied = Apply(qual1, List()) setPos qual1.pos setType qual1.tpe.resultType
+ adaptMember(selectFrom(applied))
} else if (!(qual1.isInstanceOf[Super] || (qual1.tpe.typeSymbol isSubClass tree.symbol.owner))) {
assert(tree.symbol.owner != ArrayClass)
- qual1 = cast(qual1, tree.symbol.owner.tpe)
+ selectFrom(cast(qual1, tree.symbol.owner.tpe))
+ } else {
+ selectFrom(qual1)
}
- treeCopy.Select(tree, qual1, name)
}
case SelectFromArray(qual, name, erasure) =>
var qual1 = typedQualifier(qual)
@@ -861,6 +866,11 @@ abstract class Erasure extends AddInterfaces
tree1
}
}
+
+ private def isMethodTypeWithEmptyParams(tpe: Type) = tpe match {
+ case MethodType(Nil, _) => true
+ case _ => false
+ }
}
/** The erasure transformer */
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 521d732664..77e7e013ab 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -184,7 +184,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
def makeExtensionMethodSymbol = {
val extensionName = extensionNames(origMeth).head
val extensionMeth = (
- companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL)
+ companion.moduleClass.newMethod(extensionName.toTermName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL)
setAnnotations origMeth.annotations
)
companion.info.decls.enter(extensionMeth)
@@ -232,12 +232,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
super.transformStats(stats, exprOwner) map {
- case md @ ModuleDef(_, _, _) if extensionDefs contains md.symbol =>
- val defns = extensionDefs(md.symbol).toList map (member =>
- atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(member))
- )
- extensionDefs -= md.symbol
- deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ defns))
+ case md @ ModuleDef(_, _, _) =>
+ val extraStats = extensionDefs remove md.symbol match {
+ case Some(defns) => defns.toList map (defn => atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(defn.duplicate)))
+ case _ => Nil
+ }
+ if (extraStats.isEmpty) md
+ else deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ extraStats))
case stat =>
stat
}
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index a52dadb134..b2602f47de 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -23,7 +23,7 @@ abstract class Flatten extends InfoTransform {
val old = (scope lookupUnshadowedEntries sym.name).toList
old foreach (scope unlink _)
scope enter sym
- log(s"lifted ${sym.fullLocationString}" + ( if (old.isEmpty) "" else " after unlinking $old from scope." ))
+ log(s"lifted ${sym.fullLocationString}" + ( if (old.isEmpty) "" else s" after unlinking $old from scope." ))
old
}
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 4a23e65ad2..0198f959e3 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -247,8 +247,8 @@ abstract class LambdaLift extends InfoTransform {
// SI-5652 If the lifted symbol is accessed from an inner class, it will be made public. (where?)
// Generating a a unique name, mangled with the enclosing class name, avoids a VerifyError
// in the case that a sub-class happens to lifts out a method with the *same* name.
- val name = freshen(sym.name + nme.NAME_JOIN_STRING)
- if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name, sym.enclClass)
+ val name = freshen("" + sym.name + nme.NAME_JOIN_STRING)
+ if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name.toTermName, sym.enclClass)
else name
}
}
@@ -290,7 +290,7 @@ abstract class LambdaLift extends InfoTransform {
proxies(owner) =
for (fv <- freeValues.toList) yield {
val proxyName = proxyNames.getOrElse(fv, fv.name)
- val proxy = owner.newValue(proxyName, owner.pos, newFlags) setInfo fv.info
+ val proxy = owner.newValue(proxyName.toTermName, owner.pos, newFlags) setInfo fv.info
if (owner.isClass) owner.info.decls enter proxy
proxy
}
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 481228fb3d..e6c9afb042 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -68,7 +68,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
curTree = tree
tree match {
-
+
case Block(_, _) =>
val block1 = super.transform(tree)
val Block(stats, expr) = block1
@@ -79,7 +79,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
List(stat)
})
treeCopy.Block(block1, stats1, expr)
-
+
case DefDef(_, _, _, _, _, rhs) => atOwner(tree.symbol) {
val (res, slowPathDef) = if (!sym.owner.isClass && sym.isLazy) {
val enclosingClassOrDummyOrMethod = {
@@ -100,9 +100,9 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
val (rhs1, sDef) = mkLazyDef(enclosingClassOrDummyOrMethod, transform(rhs), idx, sym)
sym.resetFlag((if (lazyUnit(sym)) 0 else LAZY) | ACCESSOR)
(rhs1, sDef)
- } else
+ } else
(transform(rhs), EmptyTree)
-
+
val ddef1 = deriveDefDef(tree)(_ => if (LocalLazyValFinder.find(res)) typed(addBitmapDefs(sym, res)) else res)
if (slowPathDef != EmptyTree) Block(slowPathDef, ddef1) else ddef1
}
@@ -189,10 +189,10 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
case _ => prependStats(bmps, rhs)
}
}
-
+
def mkSlowPathDef(clazz: Symbol, lzyVal: Symbol, cond: Tree, syncBody: List[Tree],
stats: List[Tree], retVal: Tree): Tree = {
- val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name), lzyVal.pos, STABLE | PRIVATE)
+ val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name.toTermName), lzyVal.pos, STABLE | PRIVATE)
defSym setInfo MethodType(List(), lzyVal.tpe.resultType)
defSym.owner = lzyVal.owner
debuglog(s"crete slow compute path $defSym with owner ${defSym.owner} for lazy val $lzyVal")
@@ -201,8 +201,8 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
val rhs: Tree = (gen.mkSynchronizedCheck(clazz, cond, syncBody, stats)).changeOwner(currentOwner -> defSym)
DEF(defSym).mkTree(addBitmapDefs(lzyVal, BLOCK(rhs, retVal))) setSymbol defSym
}
-
-
+
+
def mkFastPathBody(clazz: Symbol, lzyVal: Symbol, cond: Tree, syncBody: List[Tree],
stats: List[Tree], retVal: Tree): (Tree, Tree) = {
val slowPathDef: Tree = mkSlowPathDef(clazz, lzyVal, cond, syncBody, stats, retVal)
@@ -221,7 +221,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
* Similarly as for normal lazy val members (see Mixin), the result will be a tree of the form
* { if ((bitmap&n & MASK) == 0) this.l$compute()
* else l$
- *
+ *
* def l$compute() = { synchronized(enclosing_class_or_dummy) {
* if ((bitmap$n & MASK) == 0) {
* l$ = <rhs>
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index ac1cdd1f46..45ef083b66 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -207,14 +207,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// println("creating new getter for "+ field +" : "+ field.info +" at "+ field.locationString+(field hasFlag MUTABLE))
val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED | ( if (field.isMutable) 0 else STABLE )
// TODO preserve pre-erasure info?
- clazz.newMethod(nme.getterName(field.name), field.pos, newFlags) setInfo MethodType(Nil, field.info)
+ clazz.newMethod(nme.getterName(field.name.toTermName), field.pos, newFlags) setInfo MethodType(Nil, field.info)
}
/** Create a new setter. Setters are never private or local. They are
* always accessors and deferred. */
def newSetter(field: Symbol): Symbol = {
//println("creating new setter for "+field+field.locationString+(field hasFlag MUTABLE))
- val setterName = nme.getterToSetter(nme.getterName(field.name))
+ val setterName = nme.getterToSetter(nme.getterName(field.name.toTermName))
val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED
val setter = clazz.newMethod(setterName, field.pos, newFlags)
// TODO preserve pre-erasure info?
@@ -266,7 +266,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Mix in members of implementation class mixinClass into class clazz */
def mixinImplClassMembers(mixinClass: Symbol, mixinInterface: Symbol) {
- assert(mixinClass.isImplClass, "Not an impl class:" +
+ if (!mixinClass.isImplClass) debugwarn ("Impl class flag is not set " +
((mixinClass.debugLocationString, mixinInterface.debugLocationString)))
for (member <- mixinClass.info.decls ; if isForwarded(member)) {
@@ -315,7 +315,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// carries over the current entry in the type history)
val sym = enteringErasure {
// so we have a type history entry before erasure
- clazz.newValue(nme.getterToLocal(mixinMember.name), mixinMember.pos).setInfo(mixinMember.tpe.resultType)
+ clazz.newValue(nme.getterToLocal(mixinMember.name.toTermName), mixinMember.pos).setInfo(mixinMember.tpe.resultType)
}
sym updateInfo mixinMember.tpe.resultType // info at current phase
@@ -357,7 +357,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// first complete the superclass with mixed in members
addMixedinMembers(clazz.superClass, unit)
- //Console.println("adding members of " + clazz.info.baseClasses.tail.takeWhile(superclazz !=) + " to " + clazz);//DEBUG
for (mc <- clazz.mixinClasses ; if mc hasFlag lateINTERFACE) {
// @SEAN: adding trait tracking so we don't have to recompile transitive closures
unit.depends += mc
@@ -381,20 +380,20 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (clazz.isImplClass) {
clazz setFlag lateMODULE
var sourceModule = clazz.owner.info.decls.lookup(sym.name.toTermName)
- if (sourceModule != NoSymbol) {
- sourceModule setPos sym.pos
- if (sourceModule.flags != MODULE) {
- log("!!! Directly setting sourceModule flags from %s to MODULE".format(sourceModule.flagString))
- sourceModule.flags = MODULE
- }
- }
- else {
+ if (sourceModule == NoSymbol) {
sourceModule = (
clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE)
setModuleClass sym.asInstanceOf[ClassSymbol]
)
clazz.owner.info.decls enter sourceModule
}
+ else {
+ sourceModule setPos sym.pos
+ if (sourceModule.flags != MODULE) {
+ log("!!! Directly setting sourceModule flags from %s to MODULE".format(sourceModule.flagString))
+ sourceModule.flags = MODULE
+ }
+ }
sourceModule setInfo sym.tpe
// Companion module isn't visible for anonymous class at this point anyway
assert(clazz.sourceModule != NoSymbol || clazz.isAnonymousClass,
@@ -513,7 +512,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
* - create a new method definition that also has a `self` parameter
* (which comes first) Iuli: this position is assumed by tail call elimination
* on a different receiver. Storing a new 'this' assumes it is located at
- * index 0 in the local variable table. See 'STORE_THIS' and GenJVM/GenMSIL.
+ * index 0 in the local variable table. See 'STORE_THIS' and GenASM.
* - Map implementation class types in type-apply's to their interfaces
* - Remove all fields in implementation classes
*/
@@ -711,7 +710,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
*/
def bitmapFor(clazz0: Symbol, offset: Int, field: Symbol): Symbol = {
val category = bitmapCategory(field)
- val bitmapName = nme.newBitmapName(category, offset / flagsPerBitmap(field))
+ val bitmapName = nme.newBitmapName(category, offset / flagsPerBitmap(field)).toTermName
val sym = clazz0.info.decl(bitmapName)
assert(!sym.isOverloaded, sym)
@@ -775,7 +774,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def mkSlowPathDef(clazz: Symbol, lzyVal: Symbol, cond: Tree, syncBody: List[Tree],
stats: List[Tree], retVal: Tree, attrThis: Tree, args: List[Tree]): Symbol = {
- val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name), lzyVal.pos, PRIVATE)
+ val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name.toTermName), lzyVal.pos, PRIVATE)
val params = defSym newSyntheticValueParams args.map(_.symbol.tpe)
defSym setInfoAndEnter MethodType(params, lzyVal.tpe.resultType)
val rhs: Tree = (gen.mkSynchronizedCheck(attrThis, cond, syncBody, stats)).changeOwner(currentOwner -> defSym)
@@ -868,8 +867,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val cond = Apply(Select(moduleVarRef, Object_eq), List(NULL))
mkFastPathBody(clazz, moduleSym, cond, List(assign), List(NULL), returnTree, attrThis, args)
case _ =>
- assert(false, "Invalid getter " + rhs + " for module in class " + clazz)
- EmptyTree
+ abort(s"Invalid getter $rhs for module in $clazz")
}
def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position, fieldSym: Symbol): Tree = {
@@ -877,7 +875,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
val bitmapSym = bitmapFor(clazz, offset, sym)
val kind = bitmapKind(sym)
val mask = maskForOffset(offset, sym, kind)
- val msg = "Uninitialized field: " + unit.source + ": " + pos.line
+ val msg = s"Uninitialized field: ${unit.source}: ${pos.line}"
val result =
IF (mkTest(clazz, mask, bitmapSym, false, kind)) .
THEN (retVal) .
@@ -1037,16 +1035,17 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
// if class is not a trait add accessor definitions
else if (!clazz.isTrait) {
+ // This needs to be a def to avoid sharing trees
+ def accessedRef = accessedReference(sym)
if (sym.hasAccessorFlag && (!sym.isDeferred || sym.hasFlag(lateDEFERRED))) {
// add accessor definitions
addDefDef(sym, {
- val accessedRef = accessedReference(sym)
if (sym.isSetter) {
if (isOverriddenSetter(sym)) UNIT
else accessedRef match {
- case Literal(_) => accessedRef
- case _ =>
- val init = Assign(accessedRef, Ident(sym.firstParam))
+ case ref @ Literal(_) => ref
+ case ref =>
+ val init = Assign(ref, Ident(sym.firstParam))
val getter = sym.getter(clazz)
if (!needsInitFlag(getter)) init
@@ -1061,11 +1060,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
else if (sym.isModule && !(sym hasFlag LIFTED | BRIDGE)) {
// add modules
- val vdef = gen.mkModuleVarDef(sym)
- addDef(position(sym), vdef)
+ val vsym = sym.owner.newModuleVarSymbol(sym)
+ addDef(position(sym), ValDef(vsym))
- val rhs = gen.newModule(sym, vdef.symbol.tpe)
- val assignAndRet = gen.mkAssignAndReturn(vdef.symbol, rhs)
+ // !!! TODO - unravel the enormous duplication between this code and
+ // eliminateModuleDefs in RefChecks.
+ val rhs = gen.newModule(sym, vsym.tpe)
+ val assignAndRet = gen.mkAssignAndReturn(vsym, rhs)
val attrThis = gen.mkAttributedThis(clazz)
val rhs1 = mkInnerClassAccessorDoubleChecked(attrThis, assignAndRet, sym, List())
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 2574644727..4e4c1b98ac 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -323,11 +323,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def specializedName(name: Name, types1: List[Type], types2: List[Type]): TermName = {
if (nme.INITIALIZER == name || (types1.isEmpty && types2.isEmpty))
- name
+ name.toTermName
else if (nme.isSetterName(name))
- nme.getterToSetter(specializedName(nme.setterToGetter(name), types1, types2))
+ nme.getterToSetter(specializedName(nme.setterToGetter(name.toTermName), types1, types2))
else if (nme.isLocalName(name))
- nme.getterToLocal(specializedName(nme.localToGetter(name), types1, types2))
+ nme.getterToLocal(specializedName(nme.localToGetter(name.toTermName), types1, types2))
else {
val (base, cs, ms) = nme.splitSpecializedName(name)
newTermName(base.toString + "$"
@@ -689,7 +689,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def mkAccessor(field: Symbol, name: Name) = {
val newFlags = (SPECIALIZED | m.getter(clazz).flags) & ~(LOCAL | CASEACCESSOR | PARAMACCESSOR)
// we rely on the super class to initialize param accessors
- val sym = sClass.newMethod(name, field.pos, newFlags)
+ val sym = sClass.newMethod(name.toTermName, field.pos, newFlags)
info(sym) = SpecializedAccessor(field)
sym
}
@@ -708,7 +708,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name))
if (nme.isLocalName(m.name)) {
- val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name)) setInfo MethodType(Nil, specVal.info)
+ val specGetter = mkAccessor(specVal, nme.localToGetter(specVal.name.toTermName)) setInfo MethodType(Nil, specVal.info)
val origGetter = overrideIn(sClass, m.getter(clazz))
info(origGetter) = Forward(specGetter)
enterMember(specGetter)
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 6ab99eaec6..c375bc4362 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -149,7 +149,7 @@ abstract class TailCalls extends Transform {
def enclosingType = method.enclClass.typeOfThis
def isEligible = method.isEffectivelyFinal
// @tailrec annotation indicates mandatory transformation
- def isMandatory = method.hasAnnotation(TailrecClass) && !forMSIL
+ def isMandatory = method.hasAnnotation(TailrecClass)
def isTransformed = isEligible && accessed(label)
def tailrecFailure() = unit.error(failPos, "could not optimize @tailrec annotated " + method + ": " + failReason)
@@ -229,7 +229,6 @@ abstract class TailCalls extends Transform {
}
else if (!matchesTypeArgs) failHere("it is called recursively with different type arguments")
else if (receiver == EmptyTree) rewriteTailCall(This(currentClass))
- else if (forMSIL) fail("it cannot be optimized on MSIL")
else if (!receiverIsSame) failHere("it changes type of 'this' on a polymorphic recursive call")
else rewriteTailCall(receiver)
}
@@ -326,8 +325,16 @@ abstract class TailCalls extends Transform {
transformTrees(cases).asInstanceOf[List[CaseDef]]
)
+ case Try(block, catches, finalizer @ EmptyTree) =>
+ // SI-1672 Catches are in tail position when there is no finalizer
+ treeCopy.Try(tree,
+ noTailTransform(block),
+ transformTrees(catches).asInstanceOf[List[CaseDef]],
+ EmptyTree
+ )
+
case Try(block, catches, finalizer) =>
- // no calls inside a try are in tail position, but keep recursing for nested functions
+ // no calls inside a try are in tail position if there is a finalizer, but keep recursing for nested functions
treeCopy.Try(tree,
noTailTransform(block),
noTailTransforms(catches).asInstanceOf[List[CaseDef]],
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 4f889a1d86..90ea6c94d8 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -61,24 +61,6 @@ abstract class UnCurry extends InfoTransform
// uncurry and uncurryType expand type aliases
- /** Traverse tree omitting local method definitions.
- * If a `return` is encountered, set `returnFound` to true.
- * Used for MSIL only.
- */
- private object lookForReturns extends Traverser {
- var returnFound = false
- override def traverse(tree: Tree): Unit = tree match {
- case Return(_) => returnFound = true
- case DefDef(_, _, _, _, _, _) => ;
- case _ => super.traverse(tree)
- }
- def found(tree: Tree) = {
- returnFound = false
- traverse(tree)
- returnFound
- }
- }
-
class UnCurryTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
private var needTryLift = false
private var inPattern = false
@@ -268,7 +250,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, List(applyMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
@@ -371,7 +353,7 @@ abstract class UnCurry extends InfoTransform
}
val isDefinedAtMethodDef = {
- val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL)
+ val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL | SYNTHETIC)
val params = methSym newSyntheticValueParams formals
methSym setInfoAndEnter MethodType(params, BooleanClass.tpe)
@@ -380,11 +362,11 @@ abstract class UnCurry extends InfoTransform
val body = bodyForIDA match {
case Match(selector, cases) =>
- if (cases exists treeInfo.isDefaultCase) TRUE_typed
+ if (cases exists treeInfo.isDefaultCase) TRUE
else
doSubst(Match(/*gen.mkUnchecked*/(selector),
- (cases map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ (
- DEFAULT ==> FALSE_typed)))
+ (cases map (c => deriveCaseDef(c)(x => TRUE))) :+ (
+ DEFAULT ==> FALSE)))
}
body.changeOwner(fun.symbol -> methSym)
@@ -394,7 +376,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
}
@@ -537,13 +519,6 @@ abstract class UnCurry extends InfoTransform
finally needTryLift = saved
}
- /** A try or synchronized needs to be lifted anyway for MSIL if it contains
- * return statements. These are disallowed in the CLR. By lifting
- * such returns will be converted to throws.
- */
- def shouldBeLiftedAnyway(tree: Tree) = false && // buggy, see #1981
- forMSIL && lookForReturns.found(tree)
-
/** Transform tree `t` to { def f = t; f } where `f` is a fresh name
*/
def liftTree(tree: Tree) = {
@@ -618,13 +593,10 @@ abstract class UnCurry extends InfoTransform
treeCopy.UnApply(tree, fn1, args1)
case Apply(fn, args) =>
- if (fn.symbol == Object_synchronized && shouldBeLiftedAnyway(args.head))
- transform(treeCopy.Apply(tree, fn, List(liftTree(args.head))))
- else
- withNeedLift(true) {
- val formals = fn.tpe.paramTypes
- treeCopy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, fn.symbol, args, formals)))
- }
+ withNeedLift(true) {
+ val formals = fn.tpe.paramTypes
+ treeCopy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, fn.symbol, args, formals)))
+ }
case Assign(_: RefTree, _) =>
withNeedLift(true) { super.transform(tree) }
@@ -643,7 +615,7 @@ abstract class UnCurry extends InfoTransform
super.transform(tree)
case Try(block, catches, finalizer) =>
- if (needTryLift || shouldBeLiftedAnyway(tree)) transform(liftTree(tree))
+ if (needTryLift) transform(liftTree(tree))
else super.transform(tree)
case CaseDef(pat, guard, body) =>
@@ -668,7 +640,7 @@ abstract class UnCurry extends InfoTransform
tree1
}
)
- assert(result.tpe != null, result + " tpe is null")
+ assert(result.tpe != null, result.shortClass + " tpe is null:\n" + result)
result setType uncurryTreeType(result.tpe)
}
@@ -835,7 +807,7 @@ abstract class UnCurry extends InfoTransform
}
// create the symbol
- val forwsym = currentClass.newMethod(dd.name, dd.pos, VARARGS | SYNTHETIC | flatdd.symbol.flags) setInfo forwtype
+ val forwsym = currentClass.newMethod(dd.name.toTermName, dd.pos, VARARGS | SYNTHETIC | flatdd.symbol.flags) setInfo forwtype
// create the tree
val forwtree = theTyper.typedPos(dd.pos) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index bfc9f08553..30c12a4286 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -106,9 +106,9 @@ trait ContextErrors {
s"$name extends Any, not AnyRef"
)
if (isPrimitiveValueType(found) || isTrivialTopType(tp)) "" else "\n" +
- s"""|Note that $what.
- |Such types can participate in value classes, but instances
- |cannot appear in singleton types or in reference comparisons.""".stripMargin
+ sm"""|Note that $what.
+ |Such types can participate in value classes, but instances
+ |cannot appear in singleton types or in reference comparisons."""
}
import ErrorUtils._
@@ -182,14 +182,18 @@ trait ContextErrors {
}
def ParentTypesError(templ: Template, ex: TypeError) = {
- templ.tpe = null
- issueNormalTypeError(templ, ex.getMessage())
+ templ.tpe = null
+ issueNormalTypeError(templ, ex.getMessage())
+ setError(templ)
}
// additional parentTypes errors
- def ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) =
+ def ConstrArgsInParentWhichIsTraitError(arg: Tree, parent: Symbol) =
issueNormalTypeError(arg, parent + " is a trait; does not take constructor arguments")
+ def ConstrArgsInParentOfTraitError(arg: Tree, parent: Symbol) =
+ issueNormalTypeError(arg, "parents of traits may not have parameters")
+
def MissingTypeArgumentsParentTpeError(supertpt: Tree) =
issueNormalTypeError(supertpt, "missing type arguments")
@@ -511,7 +515,7 @@ trait ContextErrors {
NormalTypeError(tree, fun.tpe+" does not take parameters")
// Dynamic
- def DynamicVarArgUnsupported(tree: Tree, name: String) =
+ def DynamicVarArgUnsupported(tree: Tree, name: Name) =
issueNormalTypeError(tree, name+ " does not support passing a vararg parameter")
def DynamicRewriteError(tree: Tree, err: AbsTypeError) = {
@@ -1040,9 +1044,6 @@ trait ContextErrors {
def MaxParametersCaseClassError(tree: Tree) =
issueNormalTypeError(tree, "Implementation restriction: case classes cannot have more than " + definitions.MaxFunctionArity + " parameters.")
- def InheritsItselfError(tree: Tree) =
- issueNormalTypeError(tree, tree.tpe.typeSymbol+" inherits itself")
-
def MissingParameterOrValTypeError(vparam: Tree) =
issueNormalTypeError(vparam, "missing parameter type")
@@ -1125,9 +1126,9 @@ trait ContextErrors {
(isView: Boolean, pt: Type, tree: Tree)(implicit context0: Context) = {
if (!info1.tpe.isErroneous && !info2.tpe.isErroneous) {
def coreMsg =
- s"""| $pre1 ${info1.sym.fullLocationString} of type ${info1.tpe}
- | $pre2 ${info2.sym.fullLocationString} of type ${info2.tpe}
- | $trailer""".stripMargin
+ sm"""| $pre1 ${info1.sym.fullLocationString} of type ${info1.tpe}
+ | $pre2 ${info2.sym.fullLocationString} of type ${info2.tpe}
+ | $trailer"""
def viewMsg = {
val found :: req :: _ = pt.typeArgs
def explanation = {
@@ -1138,19 +1139,19 @@ trait ContextErrors {
// involving Any, are further explained from foundReqMsg.
if (AnyRefClass.tpe <:< req) (
if (sym == AnyClass || sym == UnitClass) (
- s"""|Note: ${sym.name} is not implicitly converted to AnyRef. You can safely
- |pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so.""".stripMargin
+ sm"""|Note: ${sym.name} is not implicitly converted to AnyRef. You can safely
+ |pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so."""
)
else boxedClass get sym map (boxed =>
- s"""|Note: an implicit exists from ${sym.fullName} => ${boxed.fullName}, but
- |methods inherited from Object are rendered ambiguous. This is to avoid
- |a blanket implicit which would convert any ${sym.fullName} to any AnyRef.
- |You may wish to use a type ascription: `x: ${boxed.fullName}`.""".stripMargin
+ sm"""|Note: an implicit exists from ${sym.fullName} => ${boxed.fullName}, but
+ |methods inherited from Object are rendered ambiguous. This is to avoid
+ |a blanket implicit which would convert any ${sym.fullName} to any AnyRef.
+ |You may wish to use a type ascription: `x: ${boxed.fullName}`."""
) getOrElse ""
)
else
- s"""|Note that implicit conversions are not applicable because they are ambiguous:
- |${coreMsg}are possible conversion functions from $found to $req""".stripMargin
+ sm"""|Note that implicit conversions are not applicable because they are ambiguous:
+ |${coreMsg}are possible conversion functions from $found to $req"""
}
typeErrorMsg(found, req, infer.isPossiblyMissingArgs(found, req)) + (
if (explanation == "") "" else "\n" + explanation
@@ -1276,7 +1277,10 @@ trait ContextErrors {
fail()
}
- private def implRefError(message: String) = genericError(methPart(macroDdef.rhs), message)
+ private def implRefError(message: String) = {
+ val treeInfo.Applied(implRef, _, _) = macroDdef.rhs
+ genericError(implRef, message)
+ }
private def compatibilityError(message: String) =
implRefError(
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 1af61d31ec..c0d2f44c7b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -996,7 +996,14 @@ trait Contexts { self: Analyzer =>
if (settings.lint.value && selectors.nonEmpty && result != NoSymbol && pos != NoPosition)
recordUsage(current, result)
- result
+ // Harden against the fallout from bugs like SI-6745
+ //
+ // [JZ] I considered issuing a devWarning and moving the
+ // check inside the above loop, as I believe that
+ // this always represents a mistake on the part of
+ // the caller.
+ if (definitions isImportable result) result
+ else NoSymbol
}
private def selectorString(s: ImportSelector): String = {
if (s.name == nme.WILDCARD && s.rename == null) "_"
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index eb45f9b847..bf5aa95f22 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -149,9 +149,20 @@ trait Implicits {
class SearchResult(val tree: Tree, val subst: TreeTypeSubstituter) {
override def toString = "SearchResult(%s, %s)".format(tree,
if (subst.isEmpty) "" else subst)
+
+ def isFailure = false
+ def isAmbiguousFailure = false
+ final def isSuccess = !isFailure
+ }
+
+ lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ override def isFailure = true
}
- lazy val SearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter)
+ lazy val AmbiguousSearchFailure = new SearchResult(EmptyTree, EmptyTreeTypeSubstituter) {
+ override def isFailure = true
+ override def isAmbiguousFailure = true
+ }
/** A class that records an available implicit
* @param name The name of the implicit
@@ -823,7 +834,7 @@ trait Implicits {
catch divergenceHandler
tryImplicitInfo(i) match {
- case SearchFailure =>
+ case sr if sr.isFailure =>
// We don't want errors that occur during checking implicit info
// to influence the check of further infos.
context.condBufferFlush(_.kind != ErrorKinds.Divergent)
@@ -863,14 +874,14 @@ trait Implicits {
rest find (alt => !improves(chosen, alt)) match {
case Some(competing) =>
AmbiguousImplicitError(chosen, competing, "both", "and", "")(isView, pt, tree)(context)
- return SearchFailure // Stop the search once ambiguity is encountered, see t4457_2.scala
+ return AmbiguousSearchFailure // Stop the search once ambiguity is encountered, see t4457_2.scala
case _ =>
if (isView) chosen.useCountView += 1
else chosen.useCountArg += 1
}
}
- if (best == SearchFailure) {
+ if (best.isFailure) {
/** If there is no winner, and we witnessed and caught divergence,
* now we can throw it for the error message.
*/
@@ -1298,17 +1309,17 @@ trait Implicits {
else {
if (ReflectRuntimeUniverse == NoSymbol) {
// todo. write a test for this
- context.error(pos, s"""
- |to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
- |however typetag -> manifest conversion requires Scala reflection, which is not present on the classpath.
- |to proceed put scala-reflect.jar on your compilation classpath and recompile.""".trim.stripMargin)
+ context.error(pos,
+ sm"""to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
+ |however typetag -> manifest conversion requires Scala reflection, which is not present on the classpath.
+ |to proceed put scala-reflect.jar on your compilation classpath and recompile.""")
return SearchFailure
}
if (resolveClassTag(pos, tp, allowMaterialization = true) == EmptyTree) {
- context.error(pos, s"""
- |to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
- |however typetag -> manifest conversion requires a class tag for the corresponding type to be present.
- |to proceed add a class tag to the type `$tp` (e.g. by introducing a context bound) and recompile.""".trim.stripMargin)
+ context.error(pos,
+ sm"""to create a manifest here, it is necessary to interoperate with the type tag `$tagInScope` in scope.
+ |however typetag -> manifest conversion requires a class tag for the corresponding type to be present.
+ |to proceed add a class tag to the type `$tp` (e.g. by introducing a context bound) and recompile.""")
return SearchFailure
}
val cm = typed(Ident(ReflectRuntimeCurrentMirror))
@@ -1369,24 +1380,25 @@ trait Implicits {
var result = searchImplicit(context.implicitss, true)
- if (result == SearchFailure) {
+ if (result.isFailure) {
if (Statistics.canEnable) Statistics.stopTimer(inscopeFailNanos, failstart)
} else {
if (Statistics.canEnable) Statistics.stopTimer(inscopeSucceedNanos, succstart)
if (Statistics.canEnable) Statistics.incCounter(inscopeImplicitHits)
}
- if (result == SearchFailure) {
+ if (result.isFailure) {
val previousErrs = context.flushAndReturnBuffer()
val failstart = if (Statistics.canEnable) Statistics.startTimer(oftypeFailNanos) else null
val succstart = if (Statistics.canEnable) Statistics.startTimer(oftypeSucceedNanos) else null
+ val wasAmbigious = result.isAmbiguousFailure // SI-6667, never search companions after an ambiguous error in in-scope implicits
result = materializeImplicit(pt)
// `materializeImplicit` does some preprocessing for `pt`
// is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
- if (result == SearchFailure) result = searchImplicit(implicitsOfExpectedType, false)
+ if (result.isFailure && !wasAmbigious) result = searchImplicit(implicitsOfExpectedType, false)
- if (result == SearchFailure) {
+ if (result.isFailure) {
context.updateBuffer(previousErrs)
if (Statistics.canEnable) Statistics.stopTimer(oftypeFailNanos, failstart)
} else {
@@ -1395,7 +1407,7 @@ trait Implicits {
}
}
- if (result == SearchFailure && settings.debug.value)
+ if (result.isFailure && settings.debug.value)
log("no implicits found for "+pt+" "+pt.typeSymbol.info.baseClasses+" "+implicitsOfExpectedType)
result
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index be3c027259..6cc536ad9b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -220,7 +220,7 @@ trait Infer extends Checkable {
// such as T <: T gets completed. See #360
tvar.constr.inst = ErrorType
else
- assert(false, tvar.origin+" at "+tvar.origin.typeSymbol.owner)
+ abort(tvar.origin+" at "+tvar.origin.typeSymbol.owner)
}
tvars map instantiate
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 4b534b0d2e..4d1ab98fa0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -117,16 +117,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
}
def pickle(macroImplRef: Tree): Tree = {
- val macroImpl = macroImplRef.symbol
+ val MacroImplReference(owner, macroImpl, targs) = macroImplRef
val paramss = macroImpl.paramss
- // this logic relies on the assumptions that were valid for the old macro prototype
- // namely that macro implementations can only be defined in top-level classes and modules
- // with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different
- // for example, a macro def could be defined in a trait that is implemented by an object
- // there are some more clever cases when seemingly non-static method ends up being statically accessible
- // however, the code below doesn't account for these guys, because it'd take a look of time to get it right
- // for now I leave it as a todo and move along to more the important stuff
// todo. refactor when fixing SI-5498
def className: String = {
def loop(sym: Symbol): String = sym match {
@@ -138,7 +131,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
loop(sym.owner) + separator + sym.javaSimpleName.toString
}
- loop(macroImpl.owner.enclClass)
+ loop(owner)
}
def signature: List[Int] = {
@@ -159,7 +152,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
// I just named it "macro", because it's macro-related, but I could as well name it "foobar"
val nucleus = Ident(newTermName("macro"))
val wrapped = Apply(nucleus, payload map { case (k, v) => Assign(pickleAtom(k), pickleAtom(v)) })
- val pickle = gen.mkTypeApply(wrapped, treeInfo.typeArguments(macroImplRef.duplicate))
+ val pickle = gen.mkTypeApply(wrapped, targs map (_.duplicate))
// assign NoType to all freshly created AST nodes
// otherwise pickler will choke on tree.tpe being null
@@ -324,7 +317,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
def sigma(tpe: Type): Type = SigmaTypeMap(tpe)
def makeParam(name: Name, pos: Position, tpe: Type, flags: Long) =
- macroDef.newValueParameter(name, pos, flags) setInfo tpe
+ macroDef.newValueParameter(name.toTermName, pos, flags) setInfo tpe
def implType(isType: Boolean, origTpe: Type): Type = {
def tsym = if (isType) WeakTagClass else ExprClass
def targ = origTpe.typeArgs.headOption getOrElse NoType
@@ -477,9 +470,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
* Is also capable of detecting REPL and reusing its classloader.
*/
lazy val macroClassloader: ClassLoader = {
- if (global.forMSIL)
- throw new UnsupportedOperationException("Scala reflection not available on this platform")
-
val classpath = global.classPath.asURLs
macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath))
val loader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 3ac5d388d3..d74d5ecfbe 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -50,7 +50,9 @@ trait MethodSynthesis {
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
def mkThis = This(clazz) setPos clazz.pos.focus
- def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(Select(mkThis, sym))
+ def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(
+ if (clazz.isClass) Select(This(clazz), sym) else Ident(sym)
+ )
private def isOverride(name: TermName) =
clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz))
@@ -60,7 +62,7 @@ trait MethodSynthesis {
overrideFlag | SYNTHETIC
}
def newMethodFlags(method: Symbol) = {
- val overrideFlag = if (isOverride(method.name)) OVERRIDE else 0L
+ val overrideFlag = if (isOverride(method.name.toTermName)) OVERRIDE else 0L
(method.flags | overrideFlag | SYNTHETIC) & ~DEFERRED
}
@@ -68,11 +70,13 @@ trait MethodSynthesis {
localTyper typed ValOrDefDef(method, f(method))
private def createInternal(name: Name, f: Symbol => Tree, info: Type): Tree = {
- val m = clazz.newMethod(name.toTermName, clazz.pos.focus, newMethodFlags(name))
+ val name1 = name.toTermName
+ val m = clazz.newMethod(name1, clazz.pos.focus, newMethodFlags(name1))
finishMethod(m setInfoAndEnter info, f)
}
private def createInternal(name: Name, f: Symbol => Tree, infoFn: Symbol => Type): Tree = {
- val m = clazz.newMethod(name.toTermName, clazz.pos.focus, newMethodFlags(name))
+ val name1 = name.toTermName
+ val m = clazz.newMethod(name1, clazz.pos.focus, newMethodFlags(name1))
finishMethod(m setInfoAndEnter infoFn(m), f)
}
private def cloneInternal(original: Symbol, f: Symbol => Tree, name: Name): Tree = {
@@ -201,8 +205,7 @@ trait MethodSynthesis {
)
def beanAccessors(vd: ValDef): List[DerivedFromValDef] = {
val setter = if (vd.mods.isMutable) List(BeanSetter(vd)) else Nil
- if (forMSIL) Nil
- else if (vd.symbol hasAnnotation BeanPropertyAttr)
+ if (vd.symbol hasAnnotation BeanPropertyAttr)
BeanGetter(vd) :: setter
else if (vd.symbol hasAnnotation BooleanBeanPropertyAttr)
BooleanBeanGetter(vd) :: setter
@@ -521,9 +524,6 @@ trait MethodSynthesis {
}
protected def enterBeans(tree: ValDef) {
- if (forMSIL)
- return
-
val ValDef(mods, name, _, _) = tree
val beans = beanAccessorsFromNames(tree)
if (beans.nonEmpty) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 79fc0e0081..9a32747c3a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -300,11 +300,11 @@ trait Namers extends MethodSynthesis {
case DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => owner.newConstructor(pos, flags)
case DefDef(_, _, _, _, _, _) => owner.newMethod(name.toTermName, pos, flags)
case ClassDef(_, _, _, _) => owner.newClassSymbol(name.toTypeName, pos, flags)
- case ModuleDef(_, _, _) => owner.newModule(name, pos, flags)
+ case ModuleDef(_, _, _) => owner.newModule(name.toTermName, pos, flags)
case PackageDef(pid, _) => createPackageSymbol(pos, pid)
case ValDef(_, _, _, _) =>
- if (isParameter) owner.newValueParameter(name, pos, flags)
- else owner.newValue(name, pos, flags)
+ if (isParameter) owner.newValueParameter(name.toTermName, pos, flags)
+ else owner.newValue(name.toTermName, pos, flags)
}
}
private def createFieldSymbol(tree: ValDef): TermSymbol =
@@ -874,13 +874,8 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
- val tp = tpt.tpe
- val inheritsSelf = tp.typeSymbol == owner
- if (inheritsSelf)
- InheritsItselfError(tpt)
-
- if (inheritsSelf || tp.isError) AnyRefClass.tpe
- else tp
+ if (tpt.tpe.isError) AnyRefClass.tpe
+ else tpt.tpe
}
val parents = typer.parentTypes(templ) map checkParent
@@ -1285,8 +1280,12 @@ trait Namers extends MethodSynthesis {
if (!annotated.isInitialized) tree match {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann =>
- // need to be lazy, #1782. enteringTyper to allow inferView in annotation args, SI-5892.
- AnnotationInfo lazily enteringTyper(typer typedAnnotation ann)
+ // need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892.
+ AnnotationInfo lazily {
+ val context1 = typer.context.make(ann)
+ context1.setReportErrors()
+ enteringTyper(newTyper(context1) typedAnnotation ann)
+ }
}
if (ainfos.nonEmpty) {
annotated setAnnotations ainfos
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index c5245c4e9e..ede117f51a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -1146,12 +1146,12 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
val expectedOuter = expectedTp.prefix match {
case ThisType(clazz) => THIS(clazz)
case pre if pre != NoType => REF(pre.prefix, pre.termSymbol)
- case _ => TRUE_typed // fallback for SI-6183
+ case _ => TRUE // fallback for SI-6183
}
// ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix`
// if there's an outer accessor, otherwise the condition becomes `true` -- TODO: can we improve needsOuterTest so there's always an outerAccessor?
- val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC | ARTIFACT
+ val outer = expectedTp.typeSymbol.newMethod(vpmName.outer, newFlags = SYNTHETIC | ARTIFACT) setInfo expectedTp.prefix
(Select(codegen._asInstanceOf(testedBinder, expectedTp), outer)) OBJ_EQ expectedOuter
}
@@ -1278,10 +1278,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// one alternative may still generate multiple trees (e.g., an extractor call + equality test)
// (for now,) alternatives may not bind variables (except wildcards), so we don't care about the final substitution built internally by makeTreeMakers
val combinedAlts = altss map (altTreeMakers =>
- ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE_typed)))(casegen))
+ ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE)))(casegen))
)
- val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE_typed))
+ val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE))
codegenAlt.ifThenElseZero(findAltMatcher, substitution(next))
}
}
@@ -1413,7 +1413,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// assert(owner ne null); assert(owner ne NoSymbol)
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") =
- NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp
+ NoSymbol.newTermSymbol(freshName(prefix), pos, newFlags = SYNTHETIC) setInfo tp
def newSynthCaseLabel(name: String) =
NoSymbol.newLabel(freshName(name), NoPosition) setFlag treeInfo.SYNTH_CASE_FLAGS
@@ -3241,7 +3241,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
}
}
- private val defaultLabel: Symbol = newSynthCaseLabel("default")
+ private val defaultLabel: Symbol = newSynthCaseLabel("default")
/** Collapse guarded cases that switch on the same constant (the last case may be unguarded).
*
@@ -3600,7 +3600,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
*/
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree = {
val matchEnd = newSynthCaseLabel("matchEnd")
- val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations
+ val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, newFlags = SYNTHETIC) setInfo restpe.withoutAnnotations
matchEnd setInfo MethodType(List(matchRes), restpe)
def newCaseSym = newSynthCaseLabel("case") setInfo MethodType(Nil, restpe)
@@ -3682,7 +3682,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def flatMapCondStored(cond: Tree, condSym: Symbol, res: Tree, nextBinder: Symbol, next: Tree): Tree =
ifThenElseZero(cond, BLOCK(
- condSym === TRUE_typed,
+ condSym === TRUE,
nextBinder === res,
next
))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 7a7c7c7d25..396c6acd38 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1116,8 +1116,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass
def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || isAnyNumber(s)
def isScalaNumber(s: Symbol) = s isSubClass ScalaNumberClass
- // test is behind a platform guard
- def isJavaNumber(s: Symbol) = !forMSIL && (s isSubClass JavaNumberClass)
+ def isJavaNumber(s: Symbol) = s isSubClass JavaNumberClass
// includes java.lang.Number if appropriate [SI-5779]
def isAnyNumber(s: Symbol) = isScalaNumber(s) || isJavaNumber(s)
def isMaybeAnyValue(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || isMaybeValue(s)
@@ -1160,7 +1159,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
nonSensiblyNeq()
}
else if (isNumeric(receiver)) {
- if (!isNumeric(actual) && !forMSIL)
+ if (!isNumeric(actual))
if (isUnit(actual) || isBoolean(actual) || !isMaybeValue(actual)) // 5 == "abc"
nonSensiblyNeq()
}
@@ -1252,55 +1251,61 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
finally popLevel()
}
- /** Eliminate ModuleDefs.
- * - A top level object is replaced with their module class.
- * - An inner object is transformed into a module var, created on first access.
+ /** Eliminate ModuleDefs. In all cases the ModuleDef (carrying a module symbol) is
+ * replaced with a ClassDef (carrying the corresponding module class symbol) with additional
+ * trees created as follows:
*
- * In both cases, this transformation returns the list of replacement trees:
- * - Top level: the module class accessor definition
- * - Inner: a class definition, declaration of module var, and module var accessor
+ * 1) A statically reachable object (either top-level or nested only in objects) receives
+ * no additional trees.
+ * 2) An inner object which matches an existing member (e.g. implements an interface)
+ * receives an accessor DefDef to implement the interface.
+ * 3) An inner object otherwise receives a private ValDef which declares a module var
+ * (the field which holds the module class - it has a name like Foo$module) and an
+ * accessor for that field. The instance is created lazily, on first access.
*/
- private def eliminateModuleDefs(tree: Tree): List[Tree] = {
- val ModuleDef(mods, name, impl) = tree
- val sym = tree.symbol
- val classSym = sym.moduleClass
- val cdef = ClassDef(mods | MODULE, name.toTypeName, Nil, impl) setSymbol classSym setType NoType
-
- def findOrCreateModuleVar() = localTyper.typedPos(tree.pos) {
- lazy val createModuleVar = gen.mkModuleVarDef(sym)
- sym.enclClass.info.decl(nme.moduleVarName(sym.name.toTermName)) match {
- // In case we are dealing with local symbol then we already have
- // to correct error with forward reference
- case NoSymbol => createModuleVar
- case vsym => ValDef(vsym)
- }
- }
- def createStaticModuleAccessor() = exitingRefchecks {
- val method = (
- sym.owner.newMethod(sym.name.toTermName, sym.pos, (sym.flags | STABLE) & ~MODULE)
- setInfoAndEnter NullaryMethodType(sym.moduleClass.tpe)
+ private def eliminateModuleDefs(moduleDef: Tree): List[Tree] = exitingRefchecks {
+ val ModuleDef(mods, name, impl) = moduleDef
+ val module = moduleDef.symbol
+ val site = module.owner
+ val moduleName = module.name.toTermName
+ // The typer doesn't take kindly to seeing this ClassDef; we have to
+ // set NoType so it will be ignored.
+ val cdef = ClassDef(module.moduleClass, impl) setType NoType
+
+ // Create the module var unless the immediate owner is a class and
+ // the module var already exists there. See SI-5012, SI-6712.
+ def findOrCreateModuleVar() = {
+ val vsym = (
+ if (site.isTerm) NoSymbol
+ else site.info decl nme.moduleVarName(moduleName)
)
- localTyper.typedPos(tree.pos)(gen.mkModuleAccessDef(method, sym))
+ vsym orElse (site newModuleVarSymbol module)
}
- def createInnerModuleAccessor(vdef: Tree) = List(
- vdef,
- localTyper.typedPos(tree.pos) {
- val vsym = vdef.symbol
- exitingRefchecks {
- val rhs = gen.newModule(sym, vsym.tpe)
- val body = if (sym.owner.isTrait) rhs else gen.mkAssignAndReturn(vsym, rhs)
- DefDef(sym, body.changeOwner(vsym -> sym))
- }
- }
- )
- transformTrees(cdef :: {
- if (!sym.isStatic)
- createInnerModuleAccessor(findOrCreateModuleVar)
- else if (sym.isOverridingSymbol)
- List(createStaticModuleAccessor())
+ def newInnerObject() = {
+ // Create the module var unless it is already in the module owner's scope.
+ // The lookup is on module.enclClass and not module.owner lest there be a
+ // nullary method between us and the class; see SI-5012.
+ val moduleVar = findOrCreateModuleVar()
+ val rhs = gen.newModule(module, moduleVar.tpe)
+ val body = if (site.isTrait) rhs else gen.mkAssignAndReturn(moduleVar, rhs)
+ val accessor = DefDef(module, body.changeOwner(moduleVar -> module))
+
+ ValDef(moduleVar) :: accessor :: Nil
+ }
+ def matchingInnerObject() = {
+ val newFlags = (module.flags | STABLE) & ~MODULE
+ val newInfo = NullaryMethodType(module.moduleClass.tpe)
+ val accessor = site.newMethod(moduleName, module.pos, newFlags) setInfoAndEnter newInfo
+
+ DefDef(accessor, Select(This(site), module)) :: Nil
+ }
+ val newTrees = cdef :: (
+ if (module.isStatic)
+ if (module.isOverridingSymbol) matchingInnerObject() else Nil
else
- Nil
- })
+ newInnerObject()
+ )
+ transformTrees(newTrees map localTyper.typedPos(moduleDef.pos))
}
def transformStat(tree: Tree, index: Int): List[Tree] = tree match {
@@ -1382,8 +1387,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
private def checkCompileTimeOnly(sym: Symbol, pos: Position) = {
if (sym.isCompileTimeOnly) {
def defaultMsg =
- s"""|Reference to ${sym.fullLocationString} should not have survived past type checking,
- |it should have been processed and eliminated during expansion of an enclosing macro.""".stripMargin
+ sm"""Reference to ${sym.fullLocationString} should not have survived past type checking,
+ |it should have been processed and eliminated during expansion of an enclosing macro."""
// The getOrElse part should never happen, it's just here as a backstop.
unit.error(pos, sym.compileTimeOnlyMessage getOrElse defaultMsg)
}
@@ -1680,7 +1685,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
checkAnyValSubclass(currentOwner)
if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree
- case dc@TypeTreeWithDeferredRefCheck() => assert(false, "adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc"); dc
+ case dc@TypeTreeWithDeferredRefCheck() => abort("adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc")
case tpt@TypeTree() =>
if(tpt.original != null) {
tpt.original foreach {
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 64c5b41638..0a1d3bfa7a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -4,7 +4,31 @@ package typechecker
trait StdAttachments {
self: Analyzer =>
+ import global._
+
+ /** Carries information necessary to expand the host tree.
+ * At times we need to store this info, because macro expansion can be delayed until its targs are inferred.
+ * After a macro application has been successfully expanded, this attachment is destroyed.
+ */
type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context
type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type }
case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
+
+ /** After being synthesized by the parser, primary constructors aren't fully baked yet.
+ * A call to super in such constructors is just a fill-me-in-later dummy resolved later
+ * by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
+ * allows them to complete the synthesis.
+ */
+ case class SuperCallArgsAttachment(argss: List[List[Tree]])
+
+ /** Convenience method for `SuperCallArgsAttachment`.
+ * Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
+ * so it really benefits from a dedicated extractor.
+ */
+ def superCallArgs(tree: Tree): Option[List[List[Tree]]] =
+ tree.attachments.get[SuperCallArgsAttachment] collect { case SuperCallArgsAttachment(argss) => argss }
+
+ /** Determines whether the given tree has an associated SuperCallArgsAttachment.
+ */
+ def hasSuperArgs(tree: Tree): Boolean = superCallArgs(tree).nonEmpty
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 5fb9a5e67e..0992cd7955 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -525,8 +525,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
def isJavaProtected = host.isTrait && sym.isJavaDefined && {
restrictionError(pos, unit,
- s"""|$clazz accesses protected $sym inside a concrete trait method.
- |Add an accessor in a class extending ${sym.enclClass} as a workaround.""".stripMargin
+ sm"""$clazz accesses protected $sym inside a concrete trait method.
+ |Add an accessor in a class extending ${sym.enclClass} as a workaround."""
)
true
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index be7554abe2..fb95c952d2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -268,11 +268,9 @@ abstract class TreeCheckers extends Analyzer {
if (sym.owner != currentOwner) {
val expected = currentOwner.ownerChain find (x => cond(x)) getOrElse { fail("DefTree can't find owner: ") ; NoSymbol }
if (sym.owner != expected)
- fail("""|
- | currentOwner chain: %s
- | symbol chain: %s""".stripMargin.format(
- currentOwner.ownerChain take 3 mkString " -> ",
- sym.ownerChain mkString " -> ")
+ fail(sm"""|
+ | currentOwner chain: ${currentOwner.ownerChain take 3 mkString " -> "}
+ | symbol chain: ${sym.ownerChain mkString " -> "}"""
)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 19f0b56e94..3bb6ae53dc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -480,7 +480,7 @@ trait TypeDiagnostics {
&& (m.isPrivate || m.isLocal)
&& !targets(m)
&& !(m.name == nme.WILDCARD) // e.g. val _ = foo
- && !ignoreNames(m.name) // serialization methods
+ && !ignoreNames(m.name.toTermName) // serialization methods
&& !isConstantType(m.info.resultType) // subject to constant inlining
&& !treeTypes.exists(_ contains m) // e.g. val a = new Foo ; new a.Bar
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 42c7d4a6b8..a1c1b53cce 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -52,8 +52,10 @@ trait Typers extends Modes with Adaptations with Tags {
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
- if (tree != EmptyTree) tree.tpe = null
- if (tree.hasSymbolField) tree.symbol = NoSymbol
+ if (tree.canHaveAttrs) {
+ tree.tpe = null
+ if (tree.hasSymbolField) tree.symbol = NoSymbol
+ }
super.traverse(tree)
}
}
@@ -135,7 +137,7 @@ trait Typers extends Modes with Adaptations with Tags {
val res = if (paramFailed || (paramTp.isError && {paramFailed = true; true})) SearchFailure else inferImplicit(fun, paramTp, context.reportErrors, false, context)
argResultsBuff += res
- if (res != SearchFailure) {
+ if (res.isSuccess) {
argBuff += mkArg(res.tree, param.name)
} else {
mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
@@ -711,7 +713,7 @@ trait Typers extends Modes with Adaptations with Tags {
featureTrait.owner.ownerChain.takeWhile(_ != languageFeatureModule.moduleClass).reverse
val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name
def action(): Boolean = {
- def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context) != SearchFailure
+ def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, true, false, context).isSuccess
def hasOption = settings.language.value exists (s => s == featureName || s == "_")
val OK = hasImport || hasOption
if (!OK) {
@@ -1130,13 +1132,6 @@ trait Typers extends Modes with Adaptations with Tags {
// (14); the condition prevents chains of views
debuglog("inferring view from " + tree.tpe + " to " + pt)
val coercion = inferView(tree, tree.tpe, pt, true)
- // convert forward views of delegate types into closures wrapped around
- // the delegate's apply method (the "Invoke" method, which was translated into apply)
- if (forMSIL && coercion != null && isCorrespondingDelegate(tree.tpe, pt)) {
- val meth: Symbol = tree.tpe.member(nme.apply)
- debuglog("replacing forward delegate view with: " + meth + ":" + meth.tpe)
- return typed(Select(tree, meth), mode, pt)
- }
if (coercion != EmptyTree) {
def msg = "inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe
if (settings.logImplicitConv.value)
@@ -1327,13 +1322,6 @@ trait Typers extends Modes with Adaptations with Tags {
if (member(qual, name) != NoSymbol) qual
else adaptToMember(qual, HasMember(name))
- private def typePrimaryConstrBody(clazz : Symbol, cbody: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]]): Tree = {
- // XXX: see about using the class's symbol....
- enclTparams foreach (sym => context.scope.enter(sym))
- namer.enterValueParams(vparamss)
- typed(cbody)
- }
-
private def validateNoCaseAncestor(clazz: Symbol) = {
if (!phase.erasedTypes) {
for (ancestor <- clazz.ancestors find (_.isCase)) {
@@ -1435,114 +1423,242 @@ trait Typers extends Modes with Adaptations with Tags {
unit.error(tparam.pos, "type parameter of value class may not be specialized")
}
- def parentTypes(templ: Template): List[Tree] =
- if (templ.parents.isEmpty) List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
- else try {
- val clazz = context.owner
- // Normalize supertype and mixins so that supertype is always a class, not a trait.
- var supertpt = typedTypeConstructor(templ.parents.head)
- val firstParent = supertpt.tpe.typeSymbol
- var mixins = templ.parents.tail map typedType
- // If first parent is a trait, make it first mixin and add its superclass as first parent
- while ((supertpt.tpe.typeSymbol ne null) && supertpt.tpe.typeSymbol.initialize.isTrait) {
- val supertpt1 = typedType(supertpt)
- if (!supertpt1.isErrorTyped) {
- mixins = supertpt1 :: mixins
- supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
- }
+ /** Typechecks a parent type reference.
+ *
+ * This typecheck is harder than it might look, because it should honor early
+ * definitions and also perform type argument inference with the help of super call
+ * arguments provided in `encodedtpt`.
+ *
+ * The method is called in batches (batch = 1 time per each parent type referenced),
+ * two batches per definition: once from namer, when entering a ClassDef or a ModuleDef
+ * and once from typer, when typechecking the definition.
+ *
+ * ***Arguments***
+ *
+ * `encodedtpt` represents the parent type reference wrapped in an `Apply` node
+ * which indicates value arguments (i.e. type macro arguments or super constructor call arguments)
+ * If no value arguments are provided by the user, the `Apply` node is still
+ * there, but its `args` will be set to `Nil`.
+ * This argument is synthesized by `tools.nsc.ast.Parsers.templateParents`.
+ *
+ * `templ` is an enclosing template, which contains a primary constructor synthesized by the parser.
+ * Such a constructor is a DefDef which contains early initializers and maybe a super constructor call
+ * (I wrote "maybe" because trait constructors don't call super constructors).
+ * This argument is synthesized by `tools.nsc.ast.Trees.Template`.
+ *
+ * `inMixinPosition` indicates whether the reference is not the first in the
+ * list of parents (and therefore cannot be a class) or the opposite.
+ *
+ * ***Return value and side effects***
+ *
+ * Returns a `TypeTree` representing a resolved parent type.
+ * If the typechecked parent reference implies non-nullary and non-empty argument list,
+ * this argument list is attached to the returned value in SuperCallArgsAttachment.
+ * The attachment is necessary for the subsequent typecheck to fixup a super constructor call
+ * in the body of the primary constructor (see `typedTemplate` for details).
+ *
+ * This method might invoke `typedPrimaryConstrBody`, hence it might cause the side effects
+ * described in the docs of that method. It might also attribute the Super(_, _) reference
+ * (if present) inside the primary constructor of `templ`.
+ *
+ * ***Example***
+ *
+ * For the following definition:
+ *
+ * class D extends {
+ * val x = 2
+ * val y = 4
+ * } with B(x)(3) with C(y) with T
+ *
+ * this method will be called six times:
+ *
+ * (3 times from the namer)
+ * typedParentType(Apply(Apply(Ident(B), List(Ident(x))), List(3)), templ, inMixinPosition = false)
+ * typedParentType(Apply(Ident(C), List(Ident(y))), templ, inMixinPosition = true)
+ * typedParentType(Apply(Ident(T), List()), templ, inMixinPosition = true)
+ *
+ * (3 times from the typer)
+ * <the same three calls>
+ */
+ private def typedParentType(encodedtpt: Tree, templ: Template, inMixinPosition: Boolean): Tree = {
+ val app = treeInfo.dissectApplied(encodedtpt)
+ val (treeInfo.Applied(core, targs, argss), decodedtpt) = (app, app.callee)
+ val argssAreTrivial = argss == Nil || argss == ListOfNil
+
+ // we cannot avoid cyclic references with `initialize` here, because when type macros arrive,
+ // we'll have to check the probe for isTypeMacro anyways.
+ // therefore I think it's reasonable to trade a more specific "inherits itself" error
+ // for a generic, yet understandable "cyclic reference" error
+ var probe = typedTypeConstructor(core.duplicate).tpe.typeSymbol
+ if (probe == null) probe = NoSymbol
+ probe.initialize
+
+ if (probe.isTrait || inMixinPosition) {
+ if (!argssAreTrivial) {
+ if (probe.isTrait) ConstrArgsInParentWhichIsTraitError(encodedtpt, probe)
+ else () // a class in a mixin position - this warrants an error in `validateParentClasses`
+ // therefore here we do nothing, e.g. don't check that the # of ctor arguments
+ // matches the # of ctor parameters or stuff like that
}
- if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait)
- supertpt.tpe = AnyRefClass.tpe
-
- // Determine
- // - supertparams: Missing type parameters from supertype
- // - supertpe: Given supertype, polymorphic in supertparams
- val supertparams = if (supertpt.hasSymbolField) supertpt.symbol.typeParams else List()
- var supertpe = supertpt.tpe
- if (!supertparams.isEmpty)
- supertpe = PolyType(supertparams, appliedType(supertpe.typeConstructor, supertparams map (_.tpeHK)))
-
- // A method to replace a super reference by a New in a supercall
- def transformSuperCall(scall: Tree): Tree = (scall: @unchecked) match {
- case Apply(fn, args) =>
- treeCopy.Apply(scall, transformSuperCall(fn), args map (_.duplicate))
- case Select(Super(_, _), nme.CONSTRUCTOR) =>
- treeCopy.Select(
- scall,
- atPos(supertpt.pos.focus)(New(TypeTree(supertpe)) setType supertpe),
- nme.CONSTRUCTOR)
+ typedType(decodedtpt)
+ } else {
+ var supertpt = typedTypeConstructor(decodedtpt)
+ val supertparams = if (supertpt.hasSymbolField) supertpt.symbol.typeParams else Nil
+ if (supertparams.nonEmpty) {
+ typedPrimaryConstrBody(templ) {
+ val supertpe = PolyType(supertparams, appliedType(supertpt.tpe, supertparams map (_.tpeHK)))
+ val supercall = New(supertpe, mmap(argss)(_.duplicate))
+ val treeInfo.Applied(Select(ctor, nme.CONSTRUCTOR), _, _) = supercall
+ ctor setType supertpe // this is an essential hack, otherwise it will occasionally fail to typecheck
+ atPos(supertpt.pos.focus)(supercall)
+ } match {
+ case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
+ case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus
+ }
}
+ // this is the place where we tell the typer what argss should be used for the super call
+ // if argss are nullary or empty, then (see the docs for `typedPrimaryConstrBody`)
+ // the super call dummy is already good enough, so we don't need to do anything
+ if (argssAreTrivial) supertpt else supertpt updateAttachment SuperCallArgsAttachment(argss)
+ }
+ }
- treeInfo.firstConstructor(templ.body) match {
- case constr @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
- // Convert constructor body to block in environment and typecheck it
- val (preSuperStats, superCall) = {
- val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
- (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
- }
- val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall match {
- case Apply(_, _) if supertparams.nonEmpty => transformSuperCall(superCall)
- case _ => cunit.duplicate
- })
- val outercontext = context.outer
-
- assert(clazz != NoSymbol, templ)
- val cscope = outercontext.makeNewScope(constr, outercontext.owner)
- val cbody2 = newTyper(cscope) // called both during completion AND typing.
- .typePrimaryConstrBody(clazz,
- cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate)))
-
- superCall match {
- case Apply(_, _) =>
- val sarg = treeInfo.firstArgument(superCall)
- if (sarg != EmptyTree && supertpe.typeSymbol != firstParent)
- ConstrArgsInTraitParentTpeError(sarg, firstParent)
- if (!supertparams.isEmpty)
- supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
- case _ =>
- if (!supertparams.isEmpty)
- MissingTypeArgumentsParentTpeError(supertpt)
- }
+ /** Typechecks the mishmash of trees that happen to be stuffed into the primary constructor of a given template.
+ * Before commencing the typecheck, replaces the `pendingSuperCall` dummy with the result of `actualSuperCall`.
+ * `actualSuperCall` can return `EmptyTree`, in which case the dummy is replaced with a literal unit.
+ *
+ * ***Return value and side effects***
+ *
+ * If a super call is present in the primary constructor and is not erased by the transform, returns it typechecked.
+ * Otherwise (e.g. if the primary constructor is missing or the super call isn't there) returns `EmptyTree`.
+ *
+ * As a side effect, this method attributes the underlying fields of early vals.
+ * Early vals aren't typechecked anywhere else, so it's essential to call `typedPrimaryConstrBody`
+ * at least once per definition. It'd be great to disentangle this logic at some point.
+ *
+ * ***Example***
+ *
+ * For the following definition:
+ *
+ * class D extends {
+ * val x = 2
+ * val y = 4
+ * } with B(x)(3) with C(y) with T
+ *
+ * the primary constructor of `templ` will be:
+ *
+ * Block(List(
+ * ValDef(NoMods, x, TypeTree(), 2)
+ * ValDef(NoMods, y, TypeTree(), 4)
+ * global.pendingSuperCall,
+ * Literal(Constant(())))
+ *
+ * Note the `pendingSuperCall` part. This is the representation of a fill-me-in-later supercall dummy,
+ * which encodes the fact that supercall argss are unknown during parsing and need to be transplanted
+ * from one of the parent types. Read more about why the argss are unknown in `tools.nsc.ast.Trees.Template`.
+ */
+ private def typedPrimaryConstrBody(templ: Template)(actualSuperCall: => Tree): Tree =
+ treeInfo.firstConstructor(templ.body) match {
+ case ctor @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
+ val (preSuperStats, superCall) = {
+ val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
+ (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
+ }
+ val superCall1 = (superCall match {
+ case global.pendingSuperCall => actualSuperCall
+ case EmptyTree => EmptyTree
+ }) orElse cunit
+ val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1)
+ val clazz = context.owner
+ assert(clazz != NoSymbol, templ)
+ val cscope = context.outer.makeNewScope(ctor, context.outer.owner)
+ val cbody2 = { // called both during completion AND typing.
+ val typer1 = newTyper(cscope)
+ // XXX: see about using the class's symbol....
+ clazz.unsafeTypeParams foreach (sym => typer1.context.scope.enter(sym))
+ typer1.namer.enterValueParams(vparamss map (_.map(_.duplicate)))
+ typer1.typed(cbody1)
+ }
- val preSuperVals = treeInfo.preSuperFields(templ.body)
- if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
- devWarning("Wanted to zip empty presuper val list with " + preSuperStats)
- else
- map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
+ val preSuperVals = treeInfo.preSuperFields(templ.body)
+ if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
+ devWarning("Wanted to zip empty presuper val list with " + preSuperStats)
+ else
+ map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
- case _ =>
- if (!supertparams.isEmpty)
- MissingTypeArgumentsParentTpeError(supertpt)
- }
+ if (superCall1 == cunit) EmptyTree else cbody2
+ case _ =>
+ EmptyTree
+ }
- // Certain parents are added in the parser before it is known whether
- // that class also declared them as parents. For instance, this is an
- // error unless we take corrective action here:
- //
- // case class Foo() extends Serializable
- //
- // So we strip the duplicates before typer.
- def fixDuplicates(remaining: List[Tree]): List[Tree] = remaining match {
- case Nil => Nil
- case x :: xs =>
- val sym = x.symbol
- x :: fixDuplicates(
- if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
- else xs
- )
+ /** Makes sure that the first type tree in the list of parent types is always a class.
+ * If the first parent is a trait, prepend its supertype to the list until it's a class.
+ */
+ private def normalizeFirstParent(parents: List[Tree]): List[Tree] = parents match {
+ case first :: rest if treeInfo.isTraitRef(first) =>
+ def explode(supertpt: Tree, acc: List[Tree]): List[Tree] = {
+ if (treeInfo.isTraitRef(supertpt)) {
+ val supertpt1 = typedType(supertpt)
+ if (!supertpt1.isErrorTyped) {
+ val supersupertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
+ return explode(supersupertpt, supertpt1 :: acc)
+ }
+ }
+ if (supertpt.tpe.typeSymbol == AnyClass) supertpt.tpe = AnyRefClass.tpe
+ supertpt :: acc
}
+ explode(first, Nil) ++ rest
+ case _ => parents
+ }
- fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
- }
- catch {
- case ex: TypeError =>
- // fallback in case of cyclic errors
- // @H none of the tests enter here but I couldn't rule it out
- log("Type error calculating parents in template " + templ)
- log("Error: " + ex)
- ParentTypesError(templ, ex)
- List(TypeTree(AnyRefClass.tpe))
- }
+ /** Certain parents are added in the parser before it is known whether
+ * that class also declared them as parents. For instance, this is an
+ * error unless we take corrective action here:
+ *
+ * case class Foo() extends Serializable
+ *
+ * So we strip the duplicates before typer.
+ */
+ private def fixDuplicateSyntheticParents(parents: List[Tree]): List[Tree] = parents match {
+ case Nil => Nil
+ case x :: xs =>
+ val sym = x.symbol
+ x :: fixDuplicateSyntheticParents(
+ if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
+ else xs
+ )
+ }
+
+ def parentTypes(templ: Template): List[Tree] = templ.parents match {
+ case Nil => List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
+ case first :: rest =>
+ try {
+ val supertpts = fixDuplicateSyntheticParents(normalizeFirstParent(
+ typedParentType(first, templ, inMixinPosition = false) +:
+ (rest map (typedParentType(_, templ, inMixinPosition = true)))))
+
+ // if that is required to infer the targs of a super call
+ // typedParentType calls typedPrimaryConstrBody to do the inferring typecheck
+ // as a side effect, that typecheck also assigns types to the fields underlying early vals
+ // however if inference is not required, the typecheck doesn't happen
+ // and therefore early fields have their type trees not assigned
+ // here we detect this situation and take preventive measures
+ if (treeInfo.hasUntypedPreSuperFields(templ.body))
+ typedPrimaryConstrBody(templ)(EmptyTree)
+
+ supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
+ } catch {
+ case ex: TypeError =>
+ // fallback in case of cyclic errors
+ // @H none of the tests enter here but I couldn't rule it out
+ // upd. @E when a definitions inherits itself, we end up here
+ // because `typedParentType` triggers `initialize` for parent types symbols
+ log("Type error calculating parents in template " + templ)
+ log("Error: " + ex)
+ ParentTypesError(templ, ex)
+ List(TypeTree(AnyRefClass.tpe))
+ }
+ }
/** <p>Check that</p>
* <ul>
@@ -1757,9 +1873,12 @@ trait Typers extends Modes with Adaptations with Tags {
// the following is necessary for templates generated later
assert(clazz.info.decls != EmptyScope, clazz)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
- validateParentClasses(parents1, selfType)
+ if (!templ.isErrorTyped) // if `parentTypes` has invalidated the template, don't validate it anymore
+ validateParentClasses(parents1, selfType)
if (clazz.isCase)
validateNoCaseAncestor(clazz)
+ if (clazz.isTrait && hasSuperArgs(parents1.head))
+ ConstrArgsInParentOfTraitError(parents1.head, clazz)
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
@@ -1767,9 +1886,21 @@ trait Typers extends Modes with Adaptations with Tags {
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
- val body =
- if (isPastTyper || reporter.hasErrors) templ.body
- else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
+ val body = {
+ val body =
+ if (isPastTyper || reporter.hasErrors) templ.body
+ else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
+ val primaryCtor = treeInfo.firstConstructor(body)
+ val primaryCtor1 = primaryCtor match {
+ case DefDef(_, _, _, _, _, Block(earlyVals :+ global.pendingSuperCall, unit)) =>
+ val argss = superCallArgs(parents1.head) getOrElse Nil
+ val pos = wrappingPos(parents1.head.pos, argss.flatten)
+ val superCall = atPos(pos)(PrimarySuperCall(argss))
+ deriveDefDef(primaryCtor)(block => Block(earlyVals :+ superCall, unit) setPos pos) setPos pos
+ case _ => primaryCtor
+ }
+ body mapConserve { case `primaryCtor` => primaryCtor1; case stat => stat }
+ }
val body1 = typedStats(body, templ.symbol)
@@ -2377,7 +2508,7 @@ trait Typers extends Modes with Adaptations with Tags {
import CODE._
// need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up
- val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE_typed)).duplicate.asInstanceOf[CaseDef]) else Nil
+ val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE)).duplicate.asInstanceOf[CaseDef]) else Nil
// println("casesTrue "+ casesTrue)
def parentsPartial(targs: List[Type]) = addSerializable(appliedType(AbstractPartialFunctionClass.typeConstructor, targs))
@@ -2463,7 +2594,7 @@ trait Typers extends Modes with Adaptations with Tags {
methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe)
val match_ = methodBodyTyper.typedMatch(gen.mkUnchecked(selector), casesTrue, mode, BooleanClass.tpe)
- val body = methodBodyTyper.virtualizedMatch(match_ updateAttachment DefaultOverrideMatchAttachment(FALSE_typed), mode, BooleanClass.tpe)
+ val body = methodBodyTyper.virtualizedMatch(match_ updateAttachment DefaultOverrideMatchAttachment(FALSE), mode, BooleanClass.tpe)
DefDef(methodSym, body)
}
@@ -2480,7 +2611,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (members.head eq EmptyTree) setError(tree)
else {
val typedBlock = typedPos(tree.pos, mode, pt) {
- Block(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
+ Block(ClassDef(anonClass, NoMods, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
}
// Don't leak implementation details into the type, see SI-6575
if (isPartial && !typedBlock.isErrorTyped)
@@ -2683,7 +2814,11 @@ trait Typers extends Modes with Adaptations with Tags {
var moreToAdd = true
while (moreToAdd) {
val initElems = scope.elems
- for (sym <- scope)
+ // SI-5877 The decls of a package include decls of the package object. But we don't want to add
+ // the corresponding synthetics to the package class, only to the package object class.
+ def shouldAdd(sym: Symbol) =
+ inBlock || !context.isInPackageObject(sym, context.owner)
+ for (sym <- scope if shouldAdd(sym))
for (tree <- context.unit.synthetics get sym) {
newStats += typedStat(tree) // might add even more synthetics to the scope
context.unit.synthetics -= sym
@@ -3037,26 +3172,6 @@ trait Typers extends Modes with Adaptations with Tags {
case _ => tp
}
- // Replace the Delegate-Chainer methods += and -= with corresponding
- // + and - calls, which are translated in the code generator into
- // Combine and Remove
- if (forMSIL) {
- fun match {
- case Select(qual, name) =>
- if (isSubType(qual.tpe, DelegateClass.tpe)
- && (name == encode("+=") || name == encode("-="))) {
- val n = if (name == encode("+=")) nme.PLUS else nme.MINUS
- val f = Select(qual, n)
- // the compiler thinks, the PLUS method takes only one argument,
- // but he thinks it's an instance method -> still two ref's on the stack
- // -> translated by backend
- val rhs = treeCopy.Apply(tree, f, args)
- return typed(Assign(qual, rhs))
- }
- case _ => ()
- }
- }
-
/**
* This is translating uses of List() into Nil. This is less
* than ideal from a consistency standpoint, but it shouldn't be
@@ -3728,7 +3843,7 @@ trait Typers extends Modes with Adaptations with Tags {
case DynamicApplicationNamed(qual, _) if acceptsApplyDynamic(qual.tpe.widen) => true
case _ => false
// look deeper?
- // val methPart = treeInfo.methPart(fun)
+ // val treeInfo.Applied(methPart, _, _) = fun
// println("methPart of "+ fun +" is "+ methPart)
// if (methPart ne fun) isApplyDynamicNamed(methPart)
// else false
@@ -3763,54 +3878,44 @@ trait Typers extends Modes with Adaptations with Tags {
*
*/
def mkInvoke(cxTree: Tree, tree: Tree, qual: Tree, name: Name): Option[Tree] = {
- debuglog(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)")
+ log(s"dyna.mkInvoke($cxTree, $tree, $qual, $name)")
+ val treeInfo.Applied(treeSelection, _, _) = tree
+ def isDesugaredApply = treeSelection match {
+ case Select(`qual`, nme.apply) => true
+ case _ => false
+ }
acceptsApplyDynamicWithType(qual, name) map { tp =>
- // tp eq NoType => can call xxxDynamic, but not passing any type args (unless specified explicitly by the user)
- // in scala-virtualized, when not NoType, tp is passed as type argument (for selection on a staged Struct)
-
- // strip off type application -- we're not doing much with outer,
- // so don't bother preserving cxTree's attributes etc
- val cxTree1 = cxTree match {
- case t: ValOrDefDef => t.rhs
- case t => t
- }
- val cxTree2 = cxTree1 match {
- case Typed(t, tpe) => t // ignore outer type annotation
- case t => t
- }
- val (outer, explicitTargs) = cxTree2 match {
- case TypeApply(fun, targs) => (fun, targs)
- case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
- case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
- case t => (t, Nil)
- }
- def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty
-
- def desugaredApply = tree match {
- case Select(`qual`, nme.apply) => true
- case _ => false
+ // If tp == NoType, pass only explicit type arguments to applyXXX. Not used at all
+ // here - it is for scala-virtualized, where tp will be passed as an argument (for
+ // selection on a staged Struct)
+ def hasNamed(args: List[Tree]): Boolean = args exists (_.isInstanceOf[AssignOrNamedArg])
+ // not supported: foo.bar(a1,..., an: _*)
+ def hasStar(args: List[Tree]) = treeInfo.isWildcardStarArgList(args)
+ def applyOp(args: List[Tree]) = if (hasNamed(args)) nme.applyDynamicNamed else nme.applyDynamic
+ def matches(t: Tree) = isDesugaredApply || treeInfo.dissectApplied(t).core == treeSelection
+
+ /** Note that the trees which arrive here are potentially some distance from
+ * the trees of direct interest. `cxTree` is some enclosing expression which
+ * may apparently be arbitrarily larger than `tree`; and `tree` itself is
+ * too small, having at least in some cases lost its explicit type parameters.
+ * This logic is designed to use `tree` to pinpoint the immediately surrounding
+ * Apply/TypeApply/Select node, and only then creates the dynamic call.
+ * See SI-6731 among others.
+ */
+ def findSelection(t: Tree): Option[(TermName, Tree)] = t match {
+ case Apply(fn, args) if hasStar(args) => DynamicVarArgUnsupported(tree, applyOp(args)) ; None
+ case Apply(fn, args) if matches(fn) => Some((applyOp(args), fn))
+ case Assign(lhs, _) if matches(lhs) => Some((nme.updateDynamic, lhs))
+ case _ if matches(t) => Some((nme.selectDynamic, t))
+ case _ => t.children flatMap findSelection headOption
}
- // note: context.tree includes at most one Apply node
- // thus, we can't use it to detect we're going to receive named args in expressions such as:
- // qual.sel(a)(a2, arg2 = "a2")
- val oper = outer match {
- case Apply(q, as) if q == tree || desugaredApply =>
- val oper =
- if (hasNamedArg(as)) nme.applyDynamicNamed
- else nme.applyDynamic
- // not supported: foo.bar(a1,..., an: _*)
- if (treeInfo.isWildcardStarArgList(as)) {
- DynamicVarArgUnsupported(tree, oper)
- return Some(setError(tree))
- } else oper
- case Assign(`tree`, _) => nme.updateDynamic
- case _ => nme.selectDynamic
+ findSelection(cxTree) match {
+ case Some((opName, treeInfo.Applied(_, targs, _))) =>
+ val fun = gen.mkTypeApply(Select(qual, opName), targs)
+ atPos(qual.pos)(Apply(fun, Literal(Constant(name.decode)) :: Nil))
+ case _ =>
+ setError(tree)
}
-
- val dynSel = Select(qual, oper)
- val tappSel = if (explicitTargs.nonEmpty) TypeApply(dynSel, explicitTargs) else dynSel
-
- atPos(qual.pos)(Apply(tappSel, List(Literal(Constant(name.decode)))))
}
}
@@ -4001,8 +4106,8 @@ trait Typers extends Modes with Adaptations with Tags {
return fail()
if (treeInfo.mayBeVarGetter(varsym)) {
- treeInfo.methPart(lhs1) match {
- case Select(qual, name) =>
+ lhs1 match {
+ case treeInfo.Applied(Select(qual, name), _, _) =>
val sel = Select(qual, nme.getterToSetter(name.toTermName)) setPos lhs.pos
val app = Apply(sel, List(rhs)) setPos tree.pos
return typed(app, mode, pt)
@@ -4171,24 +4276,7 @@ trait Typers extends Modes with Adaptations with Tags {
else adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
case MethodType(formals, _) =>
if (isFunctionType(pt)) expr1
- else expr1 match {
- case Select(qual, name) if (forMSIL &&
- pt != WildcardType &&
- pt != ErrorType &&
- isSubType(pt, DelegateClass.tpe)) =>
- val scalaCaller = newScalaCaller(pt)
- addScalaCallerInfo(scalaCaller, expr1.symbol)
- val n: Name = scalaCaller.name
- val del = Ident(DelegateClass) setType DelegateClass.tpe
- val f = Select(del, n)
- //val f1 = TypeApply(f, List(Ident(pt.symbol) setType pt))
- val args: List[Tree] = if(expr1.symbol.isStatic) List(Literal(Constant(null)))
- else List(qual) // where the scala-method is located
- val rhs = Apply(f, args)
- typed(rhs)
- case _ =>
- adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
- }
+ else adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType))
case ErrorType =>
expr1
case _ =>
@@ -4400,9 +4488,9 @@ trait Typers extends Modes with Adaptations with Tags {
}
case Apply(fn, indices) =>
- treeInfo.methPart(fn) match {
- case Select(table, nme.apply) => mkUpdate(table, indices)
- case _ => UnexpectedTreeAssignmentConversionError(qual)
+ fn match {
+ case treeInfo.Applied(Select(table, nme.apply), _, _) => mkUpdate(table, indices)
+ case _ => UnexpectedTreeAssignmentConversionError(qual)
}
}
typed1(tree1, mode, pt)
@@ -5015,7 +5103,7 @@ trait Typers extends Modes with Adaptations with Tags {
case tt @ TypeTree() => tree setOriginal tt.original
case _ => tree
}
- }
+ }
else
// we should get here only when something before failed
// and we try again (@see tryTypedApply). In that case we can assign
@@ -5235,21 +5323,21 @@ trait Typers extends Modes with Adaptations with Tags {
// enough to see those. See #3938
ConstructorPrefixError(tree, restpe)
} else {
- //@M fix for #2208
- // if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef
- if (result.tpe.typeArgs.isEmpty) {
- // minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) {
- // must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not
- // designed to deal with the cycles in the scala package (ScalaObject extends
- // AnyRef, but the AnyRef type alias is entered after the scala package is
- // loaded and completed, so that ScalaObject is unpickled while AnyRef is not
- // yet defined )
- // !!! TODO - revisit now that ScalaObject is gone.
- result setType(restpe)
- } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208
- // during uncurry (after refchecks), all types are normalized
- result
- }
+ //@M fix for #2208
+ // if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef
+ if (result.tpe.typeArgs.isEmpty) {
+ // minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) {
+ // must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not
+ // designed to deal with the cycles in the scala package (ScalaObject extends
+ // AnyRef, but the AnyRef type alias is entered after the scala package is
+ // loaded and completed, so that ScalaObject is unpickled while AnyRef is not
+ // yet defined )
+ // !!! TODO - revisit now that ScalaObject is gone.
+ result setType(restpe)
+ } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208
+ // during uncurry (after refchecks), all types are normalized
+ result
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 061c6679da..3e76da4fdc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -114,7 +114,7 @@ trait Unapplies extends ast.TreeDSL
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(parents, emptyValDef, NoMods, Nil, ListOfNil, body, cdef.impl.pos.focus))
+ Template(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index ee66801c45..cbf6ef69d7 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -184,8 +184,7 @@ abstract class ClassPath[T] {
def sourcepaths: IndexedSeq[AbstractFile]
/**
- * Represents classes which can be loaded with a ClassfileLoader/MsilFileLoader
- * and / or a SourcefileLoader.
+ * Represents classes which can be loaded with a ClassfileLoader and/or SourcefileLoader.
*/
case class ClassRep(binary: Option[T], source: Option[AbstractFile]) {
def name: String = binary match {
diff --git a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala b/src/compiler/scala/tools/nsc/util/MsilClassPath.scala
deleted file mode 100644
index 2f209c550d..0000000000
--- a/src/compiler/scala/tools/nsc/util/MsilClassPath.scala
+++ /dev/null
@@ -1,166 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2006-2013 LAMP/EPFL
- * @author Martin Odersky
- */
-
-// $Id$
-
-package scala.tools.nsc
-package util
-
-import scala.util.Sorting
-import scala.collection.mutable
-import scala.tools.nsc.io.{ AbstractFile, MsilFile }
-import ch.epfl.lamp.compiler.msil.{ Type => MSILType, Assembly }
-import ClassPath.{ ClassPathContext, isTraitImplementation }
-
-/** Keeping the MSIL classpath code in its own file is important to make sure
- * we don't accidentally introduce a dependency on msil.jar in the jvm.
- */
-
-object MsilClassPath {
- def collectTypes(assemFile: AbstractFile) = {
- var res: Array[MSILType] = MSILType.EmptyTypes
- val assem = Assembly.LoadFrom(assemFile.path)
- if (assem != null) {
- // DeclaringType == null: true for non-inner classes
- res = assem.GetTypes() filter (_.DeclaringType == null)
- Sorting.stableSort(res, (t1: MSILType, t2: MSILType) => (t1.FullName compareTo t2.FullName) < 0)
- }
- res
- }
-
- /** On the java side this logic is in PathResolver, but as I'm not really
- * up to folding MSIL into that, I am encapsulating it here.
- */
- def fromSettings(settings: Settings): MsilClassPath = {
- val context =
- if (settings.inline.value) new MsilContext
- else new MsilContext { override def isValidName(name: String) = !isTraitImplementation(name) }
-
- import settings._
- new MsilClassPath(assemextdirs.value, assemrefs.value, sourcepath.value, context)
- }
-
- class MsilContext extends ClassPathContext[MsilFile] {
- def toBinaryName(rep: MsilFile) = rep.msilType.Name
- def newClassPath(assemFile: AbstractFile) = new AssemblyClassPath(MsilClassPath collectTypes assemFile, "", this)
- }
-
- private def assembleEntries(ext: String, user: String, source: String, context: MsilContext): List[ClassPath[MsilFile]] = {
- import ClassPath._
- val etr = new mutable.ListBuffer[ClassPath[MsilFile]]
- val names = new mutable.HashSet[String]
-
- // 1. Assemblies from -Xassem-extdirs
- for (dirName <- expandPath(ext, expandStar = false)) {
- val dir = AbstractFile.getDirectory(dirName)
- if (dir ne null) {
- for (file <- dir) {
- val name = file.name.toLowerCase
- if (name.endsWith(".dll") || name.endsWith(".exe")) {
- names += name
- etr += context.newClassPath(file)
- }
- }
- }
- }
-
- // 2. Assemblies from -Xassem-path
- for (fileName <- expandPath(user, expandStar = false)) {
- val file = AbstractFile.getFile(fileName)
- if (file ne null) {
- val name = file.name.toLowerCase
- if (name.endsWith(".dll") || name.endsWith(".exe")) {
- names += name
- etr += context.newClassPath(file)
- }
- }
- }
-
- def check(n: String) {
- if (!names.contains(n))
- throw new AssertionError("Cannot find assembly "+ n +
- ". Use -Xassem-extdirs or -Xassem-path to specify its location")
- }
- check("mscorlib.dll")
- check("scalaruntime.dll")
-
- // 3. Source path
- for (dirName <- expandPath(source, expandStar = false)) {
- val file = AbstractFile.getDirectory(dirName)
- if (file ne null) etr += new SourcePath[MsilFile](file, context)
- }
-
- etr.toList
- }
-}
-import MsilClassPath._
-
-/**
- * A assembly file (dll / exe) containing classes and namespaces
- */
-class AssemblyClassPath(types: Array[MSILType], namespace: String, val context: MsilContext) extends ClassPath[MsilFile] {
- def name = {
- val i = namespace.lastIndexOf('.')
- if (i < 0) namespace
- else namespace drop (i + 1)
- }
- def asURLs = List(new java.net.URL(name))
- def asClasspathString = sys.error("Unknown") // I don't know what if anything makes sense here?
-
- private lazy val first: Int = {
- var m = 0
- var n = types.length - 1
- while (m < n) {
- val l = (m + n) / 2
- val res = types(l).FullName.compareTo(namespace)
- if (res < 0) m = l + 1
- else n = l
- }
- if (types(m).FullName.startsWith(namespace)) m else types.length
- }
-
- lazy val classes = {
- val cls = new mutable.ListBuffer[ClassRep]
- var i = first
- while (i < types.length && types(i).Namespace.startsWith(namespace)) {
- // CLRTypes used to exclude java.lang.Object and java.lang.String (no idea why..)
- if (types(i).Namespace == namespace)
- cls += ClassRep(Some(new MsilFile(types(i))), None)
- i += 1
- }
- cls.toIndexedSeq
- }
-
- lazy val packages = {
- val nsSet = new mutable.HashSet[String]
- var i = first
- while (i < types.length && types(i).Namespace.startsWith(namespace)) {
- val subns = types(i).Namespace
- if (subns.length > namespace.length) {
- // example: namespace = "System", subns = "System.Reflection.Emit"
- // => find second "." and "System.Reflection" to nsSet.
- val end = subns.indexOf('.', namespace.length + 1)
- nsSet += (if (end < 0) subns
- else subns.substring(0, end))
- }
- i += 1
- }
- val xs = for (ns <- nsSet.toList)
- yield new AssemblyClassPath(types, ns, context)
-
- xs.toIndexedSeq
- }
-
- val sourcepaths: IndexedSeq[AbstractFile] = IndexedSeq()
-
- override def toString() = "assembly classpath "+ namespace
-}
-
-/**
- * The classpath when compiling with target:msil. Binary files are represented as
- * MSILType values.
- */
-class MsilClassPath(ext: String, user: String, source: String, context: MsilContext)
-extends MergedClassPath[MsilFile](MsilClassPath.assembleEntries(ext, user, source, context), context) { }
diff --git a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala
index a33af1754d..6997dbd402 100644
--- a/src/compiler/scala/tools/nsc/util/SimpleTracer.scala
+++ b/src/compiler/scala/tools/nsc/util/SimpleTracer.scala
@@ -6,7 +6,7 @@ package util
import java.io.PrintStream
/** A simple tracer
- * @param out: The print stream where trace info shoul be sent
+ * @param out: The print stream where trace info should be sent
* @param enabled: A condition that must be true for trace info to be produced.
*/
class SimpleTracer(out: PrintStream, enabled: Boolean = true) {
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index b1d343cee9..834f5436dc 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -148,13 +148,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
unwrapped = new Transformer {
override def transform(tree: Tree): Tree =
tree match {
- case Ident(name) if invertedIndex contains name =>
+ case Ident(name: TermName) if invertedIndex contains name =>
Ident(invertedIndex(name)) setType tree.tpe
case _ =>
super.transform(tree)
}
}.transform(unwrapped)
- new TreeTypeSubstituter(dummies1 map (_.symbol), dummies1 map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped)
+ new TreeTypeSubstituter(dummies1 map (_.symbol), dummies1 map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name.toTermName)))).traverse(unwrapped)
unwrapped = if (expr0.isTerm) unwrapped else unwrapFromTerm(unwrapped)
unwrapped
}
@@ -227,7 +227,6 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
emptyValDef,
NoMods,
List(),
- List(List()),
List(methdef),
NoPosition))
trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
diff --git a/src/compiler/scala/tools/util/Javap.scala b/src/compiler/scala/tools/util/Javap.scala
index 381dbd1d87..269cfa5dd4 100644
--- a/src/compiler/scala/tools/util/Javap.scala
+++ b/src/compiler/scala/tools/util/Javap.scala
@@ -6,12 +6,25 @@
package scala.tools
package util
+import java.lang.{ ClassLoader => JavaClassLoader, Iterable => JIterable }
import scala.tools.nsc.util.ScalaClassLoader
-import java.io.{ InputStream, PrintWriter, ByteArrayInputStream }
+import scala.tools.nsc.interpreter.IMain
+import java.io.{ ByteArrayInputStream, CharArrayWriter, FileNotFoundException, InputStream,
+ PrintWriter, Writer }
+import java.util.{ Locale }
+import javax.tools.{ Diagnostic, DiagnosticCollector, DiagnosticListener,
+ ForwardingJavaFileManager, JavaFileManager, JavaFileObject,
+ SimpleJavaFileObject, StandardLocation }
import scala.tools.nsc.io.File
-import Javap._
+import scala.io.Source
+import scala.util.{ Try, Success, Failure }
+import scala.util.Properties.lineSeparator
+import scala.collection.JavaConverters
+import scala.collection.generic.Clearable
import scala.language.reflectiveCalls
+import Javap._
+
trait Javap {
def loader: ScalaClassLoader
def printWriter: PrintWriter
@@ -29,137 +42,433 @@ object NoJavap extends Javap {
}
class JavapClass(
- val loader: ScalaClassLoader = ScalaClassLoader.appLoader,
- val printWriter: PrintWriter = new PrintWriter(System.out, true)
+ val loader: ScalaClassLoader,
+ val printWriter: PrintWriter,
+ intp: Option[IMain] = None
) extends Javap {
+ import JavapTool.ToolArgs
- lazy val parser = new JpOptions
-
- val EnvClass = loader.tryToInitializeClass[FakeEnvironment](Env).orNull
- val PrinterClass = loader.tryToInitializeClass[FakePrinter](Printer).orNull
- private def failed = (EnvClass eq null) || (PrinterClass eq null)
-
- val PrinterCtr = (
- if (failed) null
- else PrinterClass.getConstructor(classOf[InputStream], classOf[PrintWriter], EnvClass)
- )
-
- def findBytes(path: String): Array[Byte] =
- tryFile(path) getOrElse tryClass(path)
+ lazy val tool = JavapTool()
+ /** Run the tool. Option args start with "-".
+ * The default options are "-protected -verbose".
+ * Byte data for filename args is retrieved with findBytes.
+ */
def apply(args: Seq[String]): List[JpResult] = {
- if (failed) Nil
- else args.toList filterNot (_ startsWith "-") map { path =>
- val bytes = findBytes(path)
- if (bytes.isEmpty) new JpError("Could not find class bytes for '%s'".format(path))
- else new JpSuccess(newPrinter(new ByteArrayInputStream(bytes), newEnv(args)))
- }
+ val (options, claases) = args partition (s => (s startsWith "-") && s.length > 1)
+ val (flags, upgraded) = upgrade(options)
+ if (flags.help || claases.isEmpty) List(JpResult(JavapTool.helper(printWriter)))
+ else tool(flags.raw, upgraded)(claases map (claas => claas -> bytesFor(claas)))
}
- def newPrinter(in: InputStream, env: FakeEnvironment): FakePrinter =
- if (failed) null
- else PrinterCtr.newInstance(in, printWriter, env)
-
- def newEnv(opts: Seq[String]): FakeEnvironment = {
- lazy val env: FakeEnvironment = EnvClass.newInstance()
-
- if (failed) null
- else parser(opts) foreach { case (name, value) =>
- val field = EnvClass getDeclaredField name
- field setAccessible true
- field.set(env, value.asInstanceOf[AnyRef])
- }
+ /** Cull our tool options. */
+ private def upgrade(options: Seq[String]): (ToolArgs, Seq[String]) = ToolArgs fromArgs options match {
+ case (t,s) if s.nonEmpty => (t,s)
+ case (t,s) => (t, JavapTool.DefaultOptions)
+ }
- env
+ private def bytesFor(path: String) = Try {
+ def last = intp.get.mostRecentVar // fail if no intp
+ val bytes = findBytes(if (path == "-") last else path)
+ if (bytes.isEmpty) throw new FileNotFoundException(s"Could not find class bytes for '${path}'")
+ else bytes
}
+ def findBytes(path: String): Array[Byte] = tryFile(path) getOrElse tryClass(path)
+
/** Assume the string is a path and try to find the classfile
* it represents.
*/
def tryFile(path: String): Option[Array[Byte]] = {
- val file = File(
+ val file =
if (path.endsWith(".class")) path
else path.replace('.', '/') + ".class"
- )
- if (!file.exists) None
- else try Some(file.toByteArray) catch { case x: Exception => None }
+ (Try (File(file)) filter (_.exists) map (_.toByteArray)).toOption
}
/** Assume the string is a fully qualified class name and try to
* find the class object it represents.
*/
def tryClass(path: String): Array[Byte] = {
- val extName = (
- if (path endsWith ".class") (path dropRight 6).replace('/', '.')
- else path
+ def pathology(p: String) =
+ if (p endsWith ".class") (p dropRight 6).replace('/', '.')
+ else p
+ def load(name: String) = loader classBytes pathology(name)
+ // if repl, translate the name to something replish
+ if (intp.isDefined) {
+ val claas = load(intp.get.translatePath(path) getOrElse path)
+ if (!claas.isEmpty) claas
+ // take path as a Name in scope and find its enclosing class
+ else intp.get.translateEnclosingClass(path) match {
+ case Some(encl) => load(encl)
+ case _ => claas // empty
+ }
+ } else load(path)
+ }
+
+ abstract class JavapTool {
+ type ByteAry = Array[Byte]
+ type Input = Pair[String, Try[ByteAry]]
+ def apply(raw: Boolean, options: Seq[String])(inputs: Seq[Input]): List[JpResult]
+ // Since the tool is loaded by reflection, check for catastrophic failure.
+ protected def failed: Boolean
+ implicit protected class Failer[A](a: =>A) {
+ def orFailed[B >: A](b: =>B) = if (failed) b else a
+ }
+ protected def noToolError = new JpError(s"No javap tool available: ${getClass.getName} failed to initialize.")
+ }
+
+ class JavapTool6 extends JavapTool {
+ import JavapTool._
+ val EnvClass = loader.tryToInitializeClass[FakeEnvironment](Env).orNull
+ val PrinterClass = loader.tryToInitializeClass[FakePrinter](Printer).orNull
+ override protected def failed = (EnvClass eq null) || (PrinterClass eq null)
+
+ val PrinterCtr = PrinterClass.getConstructor(classOf[InputStream], classOf[PrintWriter], EnvClass) orFailed null
+ def newPrinter(in: InputStream, env: FakeEnvironment): FakePrinter =
+ PrinterCtr.newInstance(in, printWriter, env) orFailed null
+ def showable(fp: FakePrinter) = new Showable {
+ def show() = fp.asInstanceOf[{ def print(): Unit }].print()
+ }
+
+ lazy val parser = new JpOptions
+ def newEnv(opts: Seq[String]): FakeEnvironment = {
+ def result = {
+ val env: FakeEnvironment = EnvClass.newInstance()
+ parser(opts) foreach { case (name, value) =>
+ val field = EnvClass getDeclaredField name
+ field setAccessible true
+ field.set(env, value.asInstanceOf[AnyRef])
+ }
+ env
+ }
+ result orFailed null
+ }
+
+ override def apply(raw: Boolean, options: Seq[String])(inputs: Seq[Input]): List[JpResult] =
+ (inputs map {
+ case (_, Success(ba)) => JpResult(showable(newPrinter(new ByteArrayInputStream(ba), newEnv(options))))
+ case (_, Failure(e)) => JpResult(e.toString)
+ }).toList orFailed List(noToolError)
+ }
+
+ class JavapTool7 extends JavapTool {
+
+ import JavapTool._
+ type Task = {
+ def call(): Boolean // true = ok
+ //def run(args: Array[String]): Int // all args
+ //def handleOptions(args: Array[String]): Unit // options, then run() or call()
+ }
+ // result of Task.run
+ //object TaskResult extends Enumeration {
+ // val Ok, Error, CmdErr, SysErr, Abnormal = Value
+ //}
+ val TaskClaas = loader.tryToInitializeClass[Task](JavapTool.Tool).orNull
+ override protected def failed = TaskClaas eq null
+
+ val TaskCtor = TaskClaas.getConstructor(
+ classOf[Writer],
+ classOf[JavaFileManager],
+ classOf[DiagnosticListener[_]],
+ classOf[JIterable[String]],
+ classOf[JIterable[String]]
+ ) orFailed null
+
+ class JavaReporter extends DiagnosticListener[JavaFileObject] with Clearable {
+ import scala.collection.mutable.{ ArrayBuffer, SynchronizedBuffer }
+ type D = Diagnostic[_ <: JavaFileObject]
+ val diagnostics = new ArrayBuffer[D] with SynchronizedBuffer[D]
+ override def report(d: Diagnostic[_ <: JavaFileObject]) {
+ diagnostics += d
+ }
+ override def clear() = diagnostics.clear()
+ /** All diagnostic messages.
+ * @param locale Locale for diagnostic messages, null by default.
+ */
+ def messages(implicit locale: Locale = null) = (diagnostics map (_ getMessage locale)).toList
+
+ def reportable(raw: Boolean): String = {
+ // don't filter this message if raw, since the names are likely to differ
+ val container = "Binary file .* contains .*".r
+ val m = if (raw) messages
+ else messages filter (_ match { case container() => false case _ => true })
+ clear()
+ if (m.nonEmpty) m mkString ("", lineSeparator, lineSeparator)
+ else ""
+ }
+ }
+ val reporter = new JavaReporter
+
+ // DisassemblerTool.getStandardFileManager(reporter,locale,charset)
+ val defaultFileManager: JavaFileManager =
+ (loader.tryToLoadClass[JavaFileManager]("com.sun.tools.javap.JavapFileManager").get getMethod (
+ "create",
+ classOf[DiagnosticListener[_]],
+ classOf[PrintWriter]
+ ) invoke (null, reporter, new PrintWriter(System.err, true))).asInstanceOf[JavaFileManager] orFailed null
+
+ // manages named arrays of bytes, which might have failed to load
+ class JavapFileManager(val managed: Seq[Input])(delegate: JavaFileManager = defaultFileManager)
+ extends ForwardingJavaFileManager[JavaFileManager](delegate) {
+ import JavaFileObject.Kind
+ import Kind._
+ import StandardLocation._
+ import JavaFileManager.Location
+ import java.net.URI
+ def uri(name: String): URI = new URI(name) // new URI("jfo:" + name)
+
+ def inputNamed(name: String): Try[ByteAry] = (managed find (_._1 == name)).get._2
+ def managedFile(name: String, kind: Kind) = kind match {
+ case CLASS => fileObjectForInput(name, inputNamed(name), kind)
+ case _ => null
+ }
+ // todo: just wrap it as scala abstractfile and adapt it uniformly
+ def fileObjectForInput(name: String, bytes: Try[ByteAry], kind: Kind): JavaFileObject =
+ new SimpleJavaFileObject(uri(name), kind) {
+ override def openInputStream(): InputStream = new ByteArrayInputStream(bytes.get)
+ // if non-null, ClassWriter wrongly requires scheme non-null
+ override def toUri: URI = null
+ override def getName: String = name
+ // suppress
+ override def getLastModified: Long = -1L
+ }
+ override def getJavaFileForInput(location: Location, className: String, kind: Kind): JavaFileObject =
+ location match {
+ case CLASS_PATH => managedFile(className, kind)
+ case _ => null
+ }
+ override def hasLocation(location: Location): Boolean =
+ location match {
+ case CLASS_PATH => true
+ case _ => false
+ }
+ }
+ val writer = new CharArrayWriter
+ def fileManager(inputs: Seq[Input]) = new JavapFileManager(inputs)()
+ def showable(raw: Boolean): Showable = {
+ val written = {
+ writer.flush()
+ val w = writer.toString
+ writer.reset()
+ w
+ }
+ val msgs = reporter.reportable(raw)
+ new Showable {
+ val mw = msgs + written
+ // ReplStrippingWriter clips and scrubs on write(String)
+ // circumvent it by write(mw, 0, mw.length) or wrap it in withoutUnwrapping
+ def show() =
+ if (raw && intp.isDefined) intp.get withoutUnwrapping { writeLines() }
+ else writeLines()
+ private def writeLines() {
+ for (line <- Source.fromString(mw).getLines) printWriter write line+lineSeparator
+ printWriter.flush()
+ }
+ }
+ }
+ // eventually, use the tool interface
+ def task(options: Seq[String], claases: Seq[String], inputs: Seq[Input]): Task = {
+ //ServiceLoader.load(classOf[javax.tools.DisassemblerTool]).
+ //getTask(writer, fileManager, reporter, options.asJava, claases.asJava)
+ import JavaConverters.asJavaIterableConverter
+ TaskCtor.newInstance(writer, fileManager(inputs), reporter, options.asJava, claases.asJava)
+ .orFailed (throw new IllegalStateException)
+ }
+ // a result per input
+ private def applyOne(raw: Boolean, options: Seq[String], claas: String, inputs: Seq[Input]): Try[JpResult] =
+ Try {
+ task(options, Seq(claas), inputs).call()
+ } map {
+ case true => JpResult(showable(raw))
+ case _ => JpResult(reporter.reportable(raw))
+ } recoverWith {
+ case e: java.lang.reflect.InvocationTargetException => e.getCause match {
+ case t: IllegalArgumentException => Success(JpResult(t.getMessage)) // bad option
+ case x => Failure(x)
+ }
+ } lastly {
+ reporter.clear
+ }
+ override def apply(raw: Boolean, options: Seq[String])(inputs: Seq[Input]): List[JpResult] = (inputs map {
+ case (claas, Success(_)) => applyOne(raw, options, claas, inputs).get
+ case (_, Failure(e)) => JpResult(e.toString)
+ }).toList orFailed List(noToolError)
+ }
+
+ object JavapTool {
+ // >= 1.7
+ val Tool = "com.sun.tools.javap.JavapTask"
+
+ // < 1.7
+ val Env = "sun.tools.javap.JavapEnvironment"
+ val Printer = "sun.tools.javap.JavapPrinter"
+ // "documentation"
+ type FakeEnvironment = AnyRef
+ type FakePrinter = AnyRef
+
+ // support JavapEnvironment
+ class JpOptions {
+ private object Access {
+ final val PRIVATE = 0
+ final val PROTECTED = 1
+ final val PACKAGE = 2
+ final val PUBLIC = 3
+ }
+ private val envActionMap: Map[String, (String, Any)] = {
+ val map = Map(
+ "-l" -> (("showLineAndLocal", true)),
+ "-c" -> (("showDisassembled", true)),
+ "-s" -> (("showInternalSigs", true)),
+ "-verbose" -> (("showVerbose", true)),
+ "-private" -> (("showAccess", Access.PRIVATE)),
+ "-package" -> (("showAccess", Access.PACKAGE)),
+ "-protected" -> (("showAccess", Access.PROTECTED)),
+ "-public" -> (("showAccess", Access.PUBLIC)),
+ "-all" -> (("showallAttr", true))
+ )
+ map ++ List(
+ "-v" -> map("-verbose"),
+ "-p" -> map("-private")
+ )
+ }
+ def apply(opts: Seq[String]): Seq[(String, Any)] = {
+ opts flatMap { opt =>
+ envActionMap get opt match {
+ case Some(pair) => List(pair)
+ case _ =>
+ val charOpts = opt.tail.toSeq map ("-" + _)
+ if (charOpts forall (envActionMap contains _))
+ charOpts map envActionMap
+ else Nil
+ }
+ }
+ }
+ }
+
+ case class ToolArgs(raw: Boolean = false, help: Boolean = false)
+
+ object ToolArgs {
+ def fromArgs(args: Seq[String]): (ToolArgs, Seq[String]) = ((ToolArgs(), Seq[String]()) /: (args flatMap massage)) {
+ case ((t,others), s) => s match {
+ case "-help" => (t copy (help=true), others)
+ case "-raw" => (t copy (raw=true), others)
+ case _ => (t, others :+ s)
+ }
+ }
+ }
+
+ val helps = List(
+ "usage" -> ":javap [opts] [path or class or -]...",
+ "-help" -> "Prints this help message",
+ "-raw" -> "Don't unmangle REPL names",
+ "-verbose/-v" -> "Stack size, number of locals, method args",
+ "-private/-p" -> "Private classes and members",
+ "-package" -> "Package-private classes and members",
+ "-protected" -> "Protected classes and members",
+ "-public" -> "Public classes and members",
+ "-l" -> "Line and local variable tables",
+ "-c" -> "Disassembled code",
+ "-s" -> "Internal type signatures",
+ "-sysinfo" -> "System info of class",
+ "-constants" -> "Static final constants"
)
- loader.classBytes(extName)
+
+ // match prefixes and unpack opts, or -help on failure
+ def massage(arg: String): Seq[String] = {
+ require(arg startsWith "-")
+ // arg matches opt "-foo/-f" if prefix of -foo or exactly -f
+ val r = """(-[^/]*)(/(-.))?""".r
+ def maybe(opt: String, s: String): Option[String] = opt match {
+ // disambiguate by preferring short form
+ case r(lf,_,sf) if s == sf => Some(sf)
+ case r(lf,_,sf) if lf startsWith s => Some(lf)
+ case _ => None
+ }
+ def candidates(s: String) = (helps map (h => maybe(h._1, s))).flatten
+ // one candidate or one single-char candidate
+ def uniqueOf(maybes: Seq[String]) = {
+ def single(s: String) = s.length == 2
+ if (maybes.length == 1) maybes
+ else if ((maybes count single) == 1) maybes filter single
+ else Nil
+ }
+ // each optchar must decode to exactly one option
+ def unpacked(s: String): Try[Seq[String]] = {
+ val ones = (s drop 1) map { c =>
+ val maybes = uniqueOf(candidates(s"-$c"))
+ if (maybes.length == 1) Some(maybes.head) else None
+ }
+ Try(ones) filter (_ forall (_.isDefined)) map (_.flatten)
+ }
+ val res = uniqueOf(candidates(arg))
+ if (res.nonEmpty) res
+ else (unpacked(arg)
+ getOrElse (Seq("-help"))) // or else someone needs help
+ }
+
+ def helper(pw: PrintWriter) = new Showable {
+ def show() = helps foreach (p => pw write "%-12.12s%s%n".format(p._1,p._2))
+ }
+
+ val DefaultOptions = List("-protected", "-verbose")
+
+ def isAvailable = Seq(Env, Tool) exists (cn => hasClass(loader, cn))
+
+ private def hasClass(cl: ScalaClassLoader, cn: String) = cl.tryToInitializeClass[AnyRef](cn).isDefined
+
+ private def isTaskable(cl: ScalaClassLoader) = hasClass(cl, Tool)
+
+ def apply() = if (isTaskable(loader)) new JavapTool7 else new JavapTool6
}
}
+object JavapClass {
+ def apply(
+ loader: ScalaClassLoader = ScalaClassLoader.appLoader,
+ printWriter: PrintWriter = new PrintWriter(System.out, true),
+ intp: Option[IMain] = None
+ ) = new JavapClass(loader, printWriter, intp)
+}
+
object Javap {
- val Env = "sun.tools.javap.JavapEnvironment"
- val Printer = "sun.tools.javap.JavapPrinter"
- def isAvailable(cl: ScalaClassLoader = ScalaClassLoader.appLoader) =
- cl.tryToInitializeClass[AnyRef](Env).isDefined
+ def isAvailable(cl: ScalaClassLoader = ScalaClassLoader.appLoader) = JavapClass(cl).JavapTool.isAvailable
+
+ def apply(path: String): Unit = apply(Seq(path))
+ def apply(args: Seq[String]): Unit = JavapClass() apply args foreach (_.show())
- // "documentation"
- type FakeEnvironment = AnyRef
- type FakePrinter = AnyRef
+ trait Showable {
+ def show(): Unit
+ }
sealed trait JpResult {
type ResultType
def isError: Boolean
def value: ResultType
def show(): Unit
+ // todo
+ // def header(): String
+ // def fields(): List[String]
+ // def methods(): List[String]
+ // def signatures(): List[String]
+ }
+ object JpResult {
+ def apply(msg: String) = new JpError(msg)
+ def apply(res: Showable) = new JpSuccess(res)
}
class JpError(msg: String) extends JpResult {
type ResultType = String
def isError = true
def value = msg
- def show() = println(msg)
+ def show() = println(msg) // makes sense for :javap, less for -Ygen-javap
}
- class JpSuccess(val value: AnyRef) extends JpResult {
+ class JpSuccess(val value: Showable) extends JpResult {
type ResultType = AnyRef
def isError = false
- def show() = value.asInstanceOf[{ def print(): Unit }].print()
+ def show() = value.show() // output to tool's PrintWriter
}
-
- class JpOptions {
- private object Access {
- final val PRIVATE = 0
- final val PROTECTED = 1
- final val PACKAGE = 2
- final val PUBLIC = 3
- }
- private val envActionMap: Map[String, (String, Any)] = {
- val map = Map(
- "-l" -> (("showLineAndLocal", true)),
- "-c" -> (("showDisassembled", true)),
- "-s" -> (("showInternalSigs", true)),
- "-verbose" -> (("showVerbose", true)),
- "-private" -> (("showAccess", Access.PRIVATE)),
- "-package" -> (("showAccess", Access.PACKAGE)),
- "-protected" -> (("showAccess", Access.PROTECTED)),
- "-public" -> (("showAccess", Access.PUBLIC)),
- "-all" -> (("showallAttr", true))
- )
- map ++ List(
- "-v" -> map("-verbose"),
- "-p" -> map("-private")
- )
- }
- def apply(opts: Seq[String]): Seq[(String, Any)] = {
- opts flatMap { opt =>
- envActionMap get opt match {
- case Some(pair) => List(pair)
- case _ =>
- val charOpts = opt.tail.toSeq map ("-" + _)
- if (charOpts forall (envActionMap contains _))
- charOpts map envActionMap
- else Nil
- }
- }
- }
+ implicit class Lastly[A](val t: Try[A]) extends AnyVal {
+ private def effect[X](last: =>Unit)(a: X): Try[A] = { last; t }
+ def lastly(last: =>Unit): Try[A] = t transform (effect(last) _, effect(last) _)
}
}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index c591030bce..4924e056af 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
@@ -35,7 +35,7 @@ trait CPSUtils {
lazy val MarkerCPSAdaptMinus = rootMirror.getRequiredClass("scala.util.continuations.cpsMinus")
lazy val Context = rootMirror.getRequiredClass("scala.util.continuations.ControlContext")
- lazy val ModCPS = rootMirror.getRequiredPackage("scala.util.continuations")
+ lazy val ModCPS = rootMirror.getPackage("scala.util.continuations")
lazy val MethShiftUnit = definitions.getMember(ModCPS, cpsNames.shiftUnit)
lazy val MethShiftUnit0 = definitions.getMember(ModCPS, cpsNames.shiftUnit0)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index f16cfb10f8..801c328177 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -345,7 +345,7 @@ abstract class SelectiveCPSTransform extends PluginComponent with
val ctxSym = currentOwner.newValue(newTermName("" + vd.symbol.name + cpsNames.shiftSuffix)).setInfo(rhs1.tpe)
val ctxDef = localTyper.typed(ValDef(ctxSym, rhs1))
def ctxRef = localTyper.typed(Ident(ctxSym))
- val argSym = currentOwner.newValue(vd.symbol.name).setInfo(tpe)
+ val argSym = currentOwner.newValue(vd.symbol.name.toTermName).setInfo(tpe)
val argDef = localTyper.typed(ValDef(argSym, Select(ctxRef, ctxRef.tpe.member(cpsNames.getTrivialValue))))
val switchExpr = localTyper.typedPos(vd.symbol.pos) {
val body2 = mkBlock(bodyStms, bodyExpr).duplicate // dup before typing!
diff --git a/src/eclipse/README.md b/src/eclipse/README.md
index 39a3f457a0..d135f99418 100644
--- a/src/eclipse/README.md
+++ b/src/eclipse/README.md
@@ -44,7 +44,7 @@ If you want to go back to normal (for instance, to commit your changes to projec
DETAILS
=======
-The compiler project depends on the library, reflect, asm and fjbg projects. The
+The compiler project depends on the library, reflect, and asm projects. The
builder will take care of the correct ordering, and changes in one project will
be picked up by the dependent projects.
diff --git a/src/eclipse/continuations-library/.classpath b/src/eclipse/continuations-library/.classpath
new file mode 100644
index 0000000000..b3ca4eeb48
--- /dev/null
+++ b/src/eclipse/continuations-library/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="library"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
+ <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="build-quick-continuations-library"/>
+</classpath>
diff --git a/src/eclipse/fjbg/.project b/src/eclipse/continuations-library/.project
index 8acea9f5fe..f3a53a3d97 100644
--- a/src/eclipse/fjbg/.project
+++ b/src/eclipse/continuations-library/.project
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>fjbg</name>
+ <name>continuations-library</name>
<comment></comment>
<projects>
</projects>
@@ -17,14 +17,14 @@
</natures>
<linkedResources>
<link>
- <name>fjbg</name>
+ <name>build-quick-continuations-library</name>
<type>2</type>
- <locationURI>SCALA_BASEDIR/src/fjbg</locationURI>
+ <locationURI>SCALA_BASEDIR/build/quick/classes/continuations/library</locationURI>
</link>
<link>
- <name>libs-classes-fjbg</name>
+ <name>library</name>
<type>2</type>
- <locationURI>SCALA_BASEDIR/build/libs/classes/fjbg</locationURI>
+ <locationURI>SCALA_BASEDIR/src/continuations/library</locationURI>
</link>
</linkedResources>
</projectDescription>
diff --git a/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs b/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs
new file mode 100644
index 0000000000..63e1df247f
--- /dev/null
+++ b/src/eclipse/continuations-library/.settings/org.scala-ide.sdt.core.prefs
@@ -0,0 +1,2 @@
+P=continuations\:enable
+scala.compiler.useProjectSettings=true
diff --git a/src/eclipse/fjbg/.classpath b/src/eclipse/fjbg/.classpath
deleted file mode 100644
index 3e2f55f48a..0000000000
--- a/src/eclipse/fjbg/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="fjbg"/>
- <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="output" path="libs-classes-fjbg"/>
-</classpath>
diff --git a/src/eclipse/partest/.classpath b/src/eclipse/partest/.classpath
index b14e465aa6..75a9fae19a 100644
--- a/src/eclipse/partest/.classpath
+++ b/src/eclipse/partest/.classpath
@@ -8,7 +8,7 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
- <classpathentry kind="lib" path="lib/msil.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/asm"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-partest"/>
</classpath>
diff --git a/src/eclipse/reflect/.classpath b/src/eclipse/reflect/.classpath
index 57a3928dc3..36e6b6adf1 100644
--- a/src/eclipse/reflect/.classpath
+++ b/src/eclipse/reflect/.classpath
@@ -3,5 +3,6 @@
<classpathentry kind="src" path="reflect"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-reflect"/>
</classpath>
diff --git a/src/eclipse/scala-compiler/.classpath b/src/eclipse/scala-compiler/.classpath
index 40a4ed9996..0488a0dc39 100644
--- a/src/eclipse/scala-compiler/.classpath
+++ b/src/eclipse/scala-compiler/.classpath
@@ -3,11 +3,10 @@
<classpathentry kind="src" path="compiler"/>
<classpathentry combineaccessrules="false" kind="src" path="/reflect"/>
<classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
- <classpathentry combineaccessrules="false" kind="src" path="/fjbg"/>
<classpathentry combineaccessrules="false" kind="src" path="/asm"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
- <classpathentry kind="lib" path="lib/msil.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-compiler"/>
</classpath>
diff --git a/src/eclipse/scalap/.classpath b/src/eclipse/scalap/.classpath
index 2b44ad19b2..0a55745702 100644
--- a/src/eclipse/scalap/.classpath
+++ b/src/eclipse/scalap/.classpath
@@ -7,6 +7,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/ant/ant.jar"/>
<classpathentry kind="lib" path="lib/jline.jar"/>
- <classpathentry kind="lib" path="lib/msil.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/continuations-library"/>
<classpathentry kind="output" path="build-quick-scalap"/>
</classpath>
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java b/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java
deleted file mode 100644
index 9856dc7311..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-
-/**
- * Context in which FJBG executes. Used both as a factory for most
- * FJBG classes and as a repository for other factories.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class FJBGContext {
- /** Class file major version */
- final int MAJOR_VERSION;
-
- /** Class file minor version */
- final int MINOR_VERSION;
-
- public FJBGContext() {
- this(45, 3);
- }
-
- public FJBGContext(int major, int minor) {
- MAJOR_VERSION = major;
- MINOR_VERSION = minor;
- }
-
- // Factory methods
- //////////////////////////////////////////////////////////////////////
-
- public JClass JClass(int accessFlags,
- String name,
- String superclassName,
- String[] interfaceNames,
- String sourceFileName) {
- return new JClass(this,
- accessFlags,
- name,
- superclassName,
- interfaceNames,
- sourceFileName);
- }
-
- public JClass JClass(DataInputStream stream)
- throws IOException {
- return new JClass(this, stream);
- }
-
- public JConstantPool JConstantPool() {
- return new JConstantPool(this);
- }
-
- public JConstantPool JConstantPool(DataInputStream stream)
- throws IOException {
- return new JConstantPool(this, stream);
- }
-
- public JField JField(JClass owner,
- int accessFlags,
- String name,
- JType type) {
- return new JField(this,
- owner,
- accessFlags,
- name,
- type);
- }
-
- public JField JField(JClass owner, DataInputStream stream)
- throws IOException {
- return new JField(this, owner, stream);
- }
-
- public JMethod JMethod(JClass owner,
- int accessFlags,
- String name,
- JType returnType,
- JType[] argTypes,
- String[] argNames) {
- return new JMethod(this,
- owner,
- accessFlags,
- name,
- returnType,
- argTypes,
- argNames);
- }
-
- public JMethod JMethod(JClass owner,
- int accessFlags,
- String name,
- JMethodType type,
- String[] argNames) {
- return JMethod(owner,
- accessFlags,
- name,
- type.getReturnType(),
- type.getArgumentTypes(),
- argNames);
- }
-
- public JMethod JMethod(JClass owner, DataInputStream stream)
- throws IOException {
- return new JMethod(this, owner, stream);
- }
-
- public JLocalVariable JLocalVariable(JMethod owner,
- JType type,
- String name,
- int index) {
- return new JLocalVariable(this, owner, type, name, index);
- }
-
- public JCode JCode(JClass clazz, JMethod owner) {
- return new JExtendedCode(this, clazz, owner);
- }
-
- public JCode JCode(JClass clazz, JMethod owner, DataInputStream stream)
- throws IOException {
- return new JCode(this, clazz, owner, stream);
- }
-
- public JAttributeFactory JAttributeFactory() {
- return new JAttributeFactory(this);
- }
-
- // Attributes
- public JCodeAttribute JCodeAttribute(JClass clazz, JMethod owner) {
- return new JCodeAttribute(this, clazz, owner);
- }
-
- public JEnclosingMethodAttribute JEnclosingMethodAttribute(JClass clazz,
- String className,
- String methodName,
- JType methodType) {
- return new JEnclosingMethodAttribute(this, clazz, className, methodName, methodType);
- }
-
- public JExceptionsAttribute JExceptionsAttribute(JClass clazz,
- JMethod owner) {
- return new JExceptionsAttribute(this, clazz, owner);
- }
-
- public JLineNumberTableAttribute JLineNumberTableAttribute(JClass clazz,
- JCode owner) {
- return new JLineNumberTableAttribute(this, clazz, owner);
- }
-
- public JLocalVariableTableAttribute JLocalVariableTableAttribute(JClass clazz,
- JCode owner) {
- return new JLocalVariableTableAttribute(this, clazz, owner);
- }
-
- public JOtherAttribute JOtherAttribute(JClass clazz,
- Object owner,
- String name,
- byte[] contents,
- int length) {
- return new JOtherAttribute(this, clazz, owner, name, contents, length);
- }
-
- public JOtherAttribute JOtherAttribute(JClass clazz,
- Object owner,
- String name,
- byte[] contents) {
- return JOtherAttribute(clazz, owner, name, contents, contents.length);
- }
-
- public JSourceFileAttribute JSourceFileAttribute(JClass clazz,
- String sourceFileName) {
- return new JSourceFileAttribute(this, clazz, sourceFileName);
- }
-
- public JStackMapTableAttribute JStackMapTableAttribute(JClass clazz,
- JCode owner) {
- return new JStackMapTableAttribute(this, clazz, owner);
- }
-
- /// Repository
- //////////////////////////////////////////////////////////////////////
-
- protected JAttributeFactory jAttributeFactory = null;
- public JAttributeFactory getJAttributeFactory() {
- if (jAttributeFactory == null)
- jAttributeFactory = JAttributeFactory();
- return jAttributeFactory;
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java b/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java
deleted file mode 100644
index 01d8cc9a7e..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Definition of access flags for fields, methods and classes.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public interface JAccessFlags {
- public static int ACC_PUBLIC = 0x0001;
- public static int ACC_PRIVATE = 0x0002;
- public static int ACC_PROTECTED = 0x0004;
- public static int ACC_STATIC = 0x0008;
- public static int ACC_FINAL = 0x0010;
- public static int ACC_SUPER = 0x0020;
- public static int ACC_VOLATILE = 0x0040;
- public static int ACC_TRANSIENT = 0x0080;
- public static int ACC_NATIVE = 0x0100;
- public static int ACC_INTERFACE = 0x0200;
- public static int ACC_ABSTRACT = 0x0400;
- public static int ACC_STRICT = 0x0800;
- public static int ACC_SYNTHETIC = 0x1000;
- public static int ACC_ANNOTATION= 0x2000;
- public static int ACC_ENUM = 0x4000;
-
- // 1.5 specifics
- public static int ACC_BRIDGE = 0x0040;
- public static int ACC_VARARGS = 0x0080;
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java b/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java
deleted file mode 100644
index 61a04523ca..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Types for Java arrays.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JArrayType extends JReferenceType {
- protected final JType elementType;
- protected String signature = null;
-
- public JArrayType(JType elementType) {
- this.elementType = elementType;
- }
-
- public int getSize() { return 1; }
-
- public String getSignature() {
- if (signature == null)
- signature = "[" + elementType.getSignature();
- return signature;
- }
-
- public String getDescriptor() {
- return getSignature();
- }
-
- public int getTag() { return T_ARRAY; }
-
- public JType getElementType() { return elementType; }
-
- public String toString() {
- return elementType.toString() + "[]";
- }
-
- public boolean isArrayType() { return true; }
-
- public boolean isCompatibleWith(JType other) {
- if (other instanceof JObjectType)
- return (JObjectType)other == JObjectType.JAVA_LANG_OBJECT;
- else if (other instanceof JArrayType)
- return elementType.isCompatibleWith(((JArrayType)other).elementType);
- else return other == JType.REFERENCE;
- }
-
- public static JArrayType BOOLEAN = new JArrayType(JType.BOOLEAN);
- public static JArrayType BYTE = new JArrayType(JType.BYTE);
- public static JArrayType CHAR = new JArrayType(JType.CHAR);
- public static JArrayType SHORT = new JArrayType(JType.SHORT);
- public static JArrayType INT = new JArrayType(JType.INT);
- public static JArrayType FLOAT = new JArrayType(JType.FLOAT);
- public static JArrayType LONG = new JArrayType(JType.LONG);
- public static JArrayType DOUBLE = new JArrayType(JType.DOUBLE);
- public static JArrayType REFERENCE = new JArrayType(JType.REFERENCE);
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java
deleted file mode 100644
index 6a825beb18..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Abstract superclass for attributes which can be attached to various
- * parts of a class file.
- *
- * Attributes are used for classes (section 4.2), fields (section 4.6),
- * methods (section 4.7) and the Code attribute (section 4.8.3).
- * See sections 4.2 and later of the JVM specification.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public abstract class JAttribute {
- protected final int nameIdx;
-
- static public void writeTo(List/*<JAttribute>*/ attrs, DataOutputStream stream)
- throws IOException {
- stream.writeShort(attrs.size());
- Iterator attrsIt = attrs.iterator();
- while (attrsIt.hasNext()) {
- JAttribute attr = (JAttribute)attrsIt.next();
- attr.writeTo(stream);
- }
- }
-
- static public List/*<JAttribute>*/ readFrom(FJBGContext context,
- JClass clazz,
- Object owner,
- DataInputStream stream)
- throws IOException {
- JAttributeFactory factory = context.getJAttributeFactory();
- int count = stream.readShort();
- ArrayList list = new ArrayList(count);
- for (int i = 0; i < count; ++i)
- list.add(factory.newInstance(clazz, owner, stream));
- return list;
- }
-
- public JAttribute(FJBGContext context, JClass clazz) {
- this.nameIdx = clazz.getConstantPool().addUtf8(getName());
- }
-
- public JAttribute(FJBGContext context, JClass clazz, String name) {
- this.nameIdx = clazz.getConstantPool().addUtf8(name);
- }
-
- abstract public String getName();
-
- /**
- * Write the attribute to a stream.
- */
- public void writeTo(DataOutputStream stream) throws IOException {
- int contentsSize = getSize();
-
- stream.writeShort(nameIdx);
- stream.writeInt(contentsSize);
- int streamSizeBefore = stream.size();
- writeContentsTo(stream);
- int streamSizeDiff = stream.size() - streamSizeBefore;
-
- assert contentsSize == streamSizeDiff
- : "invalid size for attribute " + getName()
- + " given: " + contentsSize
- + " actual: " + streamSizeDiff;
- }
-
- // Note: it is not legal to add data to the constant pool during
- // the execution of any of the following two methods.
- protected abstract int getSize();
- protected abstract void writeContentsTo(DataOutputStream stream)
- throws IOException;
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java
deleted file mode 100644
index 33cdce2760..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-
-/**
- * Extensible factory to build subclasses of JAttribute based on an
- * attribute name.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JAttributeFactory {
- protected FJBGContext context;
- protected HashMap/*<String, Constructor>*/ constructors = new HashMap();
-
- protected final static Class[] CONSTRUCTOR_ARGS = new Class[] {
- FJBGContext.class,
- JClass.class,
- Object.class,
- String.class,
- int.class,
- DataInputStream.class
- };
-
- protected final static Constructor defaultDefaultConstructor;
- static {
- try {
- defaultDefaultConstructor =
- JOtherAttribute.class.getConstructor(CONSTRUCTOR_ARGS);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
-
- protected final Constructor defaultConstructor;
-
- public JAttributeFactory(FJBGContext context,
- Constructor defaultConstructor) {
- this.context = context;
- this.defaultConstructor = defaultConstructor;
- registerClass("Code", JCodeAttribute.class);
- registerClass("ConstantValue", JConstantValueAttribute.class);
- registerClass("EnclosingMethod", JEnclosingMethodAttribute.class);
- registerClass("Exceptions", JExceptionsAttribute.class);
- registerClass("InnerClasses", JInnerClassesAttribute.class);
- registerClass("LineNumberTable", JLineNumberTableAttribute.class);
- registerClass("LocalVariableTable", JLocalVariableTableAttribute.class);
- registerClass("SourceFile", JSourceFileAttribute.class);
- registerClass("StackMapTable", JStackMapTableAttribute.class);
- }
-
- public JAttributeFactory(FJBGContext context) {
- this(context, defaultDefaultConstructor);
- }
-
- public void registerClass(String attributeName,
- Class clazz) {
- if (! JAttribute.class.isAssignableFrom(clazz))
- throw new IllegalArgumentException("Not a subclass of JAttribute: "
- + clazz);
-
- try {
- Constructor constr = clazz.getConstructor(CONSTRUCTOR_ARGS);
- constructors.put(attributeName, constr);
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("No appropriate constructor for "
- + clazz);
- }
- }
-
- public JAttribute newInstance(JClass clazz,
- Object owner,
- DataInputStream stream)
- throws IOException {
- String name = clazz.getConstantPool().lookupUtf8(stream.readShort());
- Integer size = new Integer(stream.readInt());
- Constructor constr = (Constructor)constructors.get(name);
- if (constr == null) constr = defaultConstructor;
-
- Object[] args = new Object[] { context, clazz, owner, name, size, stream };
- try {
- return (JAttribute)constr.newInstance(args);
- } catch (InstantiationException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java
deleted file mode 100644
index bb1538ec23..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * Representation of a Java class.
- *
- * @author Michel Schinz, Stephane Micheloud
- * @version 1.1
- */
-public class JClass extends JMember {
-
- /** Magic number for Java class files. */
- public final static int MAGIC_NUMBER = 0xCAFEBABE;
-
- protected final JAttributeFactory attributeFactory;
-
- protected final String superclassName;
- protected final String[] interfaceNames;
- protected final String sourceFileName;
- protected final JConstantPool pool;
-
- public final static String[] NO_INTERFACES = new String[0];
-
- protected final LinkedList/*<JMethod>*/ methods = new LinkedList();
- protected final LinkedList/*<JField>*/ fields = new LinkedList();
-
- protected JInnerClassesAttribute innerClasses;
-
- protected int major;
- protected int minor;
-
- /**
- * Creates a new class with its access flags, name, superclass name,
- * interfaces names and source file name initialized to a given value.
- * The constructor also initializes the pool and adds a sourceFileName
- * attribute to the class.
- * @param accessFlags the int representing the access flags of the class.
- * @param name the string representing the name of the class.
- * @param superclassName the string representing the name of the class'
- * superclass.
- * @param interfaceNames the list of strings representing the names of the
- * interfaces implemented by the class.
- * @param sourceFileName name of the file from which the class was compiled.
- */
- protected JClass(FJBGContext context,
- int accessFlags,
- String name,
- String superclassName,
- String[] interfaceNames,
- String sourceFileName) {
- super(context, accessFlags, name);
- this.attributeFactory = context.getJAttributeFactory();
-
- this.major = context.MAJOR_VERSION;
- this.minor = context.MINOR_VERSION;
-
- this.superclassName = superclassName;
- this.interfaceNames = interfaceNames;
- this.sourceFileName = sourceFileName;
- this.pool = context.JConstantPool();
- if (sourceFileName != null)
- addAttribute(context.JSourceFileAttribute(this, sourceFileName));
- }
-
- protected JClass(FJBGContext context, DataInputStream stream)
- throws IOException {
- super(context);
- this.attributeFactory = context.getJAttributeFactory();
-
- int magic = stream.readInt();
- if (magic != MAGIC_NUMBER)
- throw new IllegalArgumentException("invalid magic number: "+magic);
-
- minor = stream.readShort();
- major = stream.readShort();
- pool = context.JConstantPool(stream);
- accessFlags = stream.readShort();
-
- // This class, super class and interfaces
- name = pool.lookupClass(stream.readShort());
- superclassName = pool.lookupClass(stream.readShort());
- interfaceNames = new String[stream.readShort()];
- for (int i = 0; i < interfaceNames.length; ++i)
- interfaceNames[i] = pool.lookupClass(stream.readShort());
-
- // Fields, methods and attributes
- int fieldsCount = stream.readShort();
- for (int i = 0; i < fieldsCount; ++i)
- addField(context.JField(this, stream));
-
- int methodsCount = stream.readShort();
- for (int i = 0; i < methodsCount; ++i)
- addMethod(context.JMethod(this, stream));
-
- String fileName = null;
- int attributesCount = stream.readShort();
- for (int i = 0; i < attributesCount; ++i) {
- JAttribute attr = attributeFactory.newInstance(this, this, stream);
- if (attr instanceof JSourceFileAttribute)
- fileName = ((JSourceFileAttribute)attr).getFileName();
- else if (attr instanceof JInnerClassesAttribute)
- innerClasses = (JInnerClassesAttribute)attr;
- addAttribute(attr);
- }
- sourceFileName = fileName;
- }
-
- /**
- * Gets the name of the class' superclass.
- * @return The string representing the name of the class' superclass.
- */
- public String getSuperclassName() { return superclassName; }
-
- /**
- * Gets the names of the interfaces implemented by the class.
- * @return The array containing the string representations of the
- * names of the interfaces implemented by the class.
- */
- public String[] getInterfaceNames() { return interfaceNames; }
-
- /**
- * Gets the source file name of this class.
- * @return The string representing the source file name of this class.
- */
- public String getSourceFileName() { return sourceFileName; }
-
- /**
- * Gets the type of the objects that are instances of the class.
- * @return The type of the instances of the class.
- */
- public JType getType() { return new JObjectType(name); }
-
- public JClass getJClass() { return this; }
-
- public boolean isPublic() {
- return (accessFlags & JAccessFlags.ACC_PUBLIC) != 0;
- }
-
- public boolean isPrivate() {
- return (accessFlags & JAccessFlags.ACC_PRIVATE) != 0;
- }
-
- public boolean isProtected() {
- return (accessFlags & JAccessFlags.ACC_PROTECTED) != 0;
- }
-
- public boolean isStatic() {
- return (accessFlags & JAccessFlags.ACC_STATIC) != 0;
- }
-
- public boolean isFinal() {
- return (accessFlags & JAccessFlags.ACC_FINAL) != 0;
- }
-
- public boolean isAbstract() {
- return (accessFlags & JAccessFlags.ACC_ABSTRACT) != 0;
- }
-
- /**
- * Gets the version number of the class.
- * @param major The int representing the major part of the version number
- * of the class.
- * @param minor The int representing the minor part of the version number
- * of the class.
- */
- public void setVersion(int major, int minor) {
- assert !frozen;
- this.major = major;
- this.minor = minor;
- }
-
- /**
- * Gets the major part of the number describing the version of the class.
- * @return The int representing the major part of the version number of
- * the class.
- */
- public int getMajorVersion() { return major; }
-
- /**
- * Gets the minor part of the number describing the version of the class.
- * @return The int representing the minor part of the version number of
- * the class.
- */
- public int getMinorVersion() { return minor; }
-
- /**
- * Gets the constant pool of the class.
- * @return The constant pool of the class.
- */
- public JConstantPool getConstantPool() { return pool; }
-
- public JInnerClassesAttribute getInnerClasses() {
- if (innerClasses == null) {
- innerClasses = new JInnerClassesAttribute(context, this);
- addAttribute(innerClasses);
- }
- return innerClasses;
- }
-
- /**
- * Decides if the class is an interface.
- * @return The boolean representing if the class is an interface or not.
- */
- public boolean isInterface() {
- return (accessFlags & JAccessFlags.ACC_INTERFACE) != 0;
- }
-
- public void addField(JField field) {
- assert !frozen;
- fields.add(field);
- }
-
- /**
- * Create and add a new field to the class.
- */
- public JField addNewField(int accessFlags, String name, JType type) {
- assert !frozen;
- JField f = context.JField(this, accessFlags, name, type);
- addField(f);
- return f;
- }
-
- protected void addMethod(JMethod method) {
- assert !frozen;
- methods.add(method);
- }
-
- /**
- * Create and add a new method to the class.
- */
- public JMethod addNewMethod(int accessFlags,
- String name,
- JType returnType,
- JType[] argTypes,
- String[] argNames) {
- assert !frozen;
- JMethod m = context.JMethod(this,
- accessFlags,
- name,
- returnType,
- argTypes,
- argNames);
- addMethod(m);
- return m;
- }
-
- /**
- * Remove a previously-added method. This makes no attempt at
- * minimising the constant pool by removing all constants which
- * were used only by this method.
- */
- public void removeMethod(JMethod m) {
- assert !frozen;
- methods.remove(m);
- }
-
- public JField[] getFields() {
- return (JField[])fields.toArray(new JField[fields.size()]);
- }
-
- public JMethod[] getMethods() {
- return (JMethod[])methods.toArray(new JMethod[methods.size()]);
- }
-
- /**
- * Freeze the contents of this class so that it can be written to
- * a file.
- */
- public void freeze() {
- assert !frozen;
- frozen = true;
- }
-
- /**
- * Writes the contents of the class to a file referenced by its name.
- * @param fileName The name of the file in which the class must be written.
- */
- public void writeTo(String fileName) throws IOException {
- writeTo(new File(fileName));
- }
-
- /**
- * Writes the contents of the class to a file.
- * @param file The file in which the class must be written.
- */
- public void writeTo(File file) throws IOException {
- File parent = file.getParentFile();
- if (parent != null && !parent.isDirectory())
- if (!parent.mkdirs())
- throw new IOException("cannot create directory " + parent);
-
- FileOutputStream fStream = new FileOutputStream(file);
- BufferedOutputStream bStream = new BufferedOutputStream(fStream);
- DataOutputStream dStream = new DataOutputStream(bStream);
- writeTo(dStream);
- dStream.close();
- bStream.close();
- fStream.close();
- }
-
- /**
- * Writes the contents of the class to a data stream.
- * @param stream The data stream in which the class must be written.
- */
- public void writeTo(DataOutputStream stream) throws IOException {
- if (!frozen) freeze();
-
- int thisClassIdx = pool.addClass(name);
- int superClassIdx = pool.addClass(superclassName);
- int[] interfacesIdx = new int[interfaceNames.length];
-
- for (int i = 0; i < interfaceNames.length; ++i)
- interfacesIdx[i] = pool.addClass(interfaceNames[i]);
-
- pool.freeze();
-
- // Magic number.
- stream.writeInt(MAGIC_NUMBER);
- // Version
- stream.writeShort(minor);
- stream.writeShort(major);
- // Constant pool
- pool.writeTo(stream);
- // Access flags
- stream.writeShort(accessFlags);
-
- // This class, super class and interfaces
- stream.writeShort(thisClassIdx);
- stream.writeShort(superClassIdx);
- stream.writeShort(interfacesIdx.length);
- for (int i = 0; i < interfacesIdx.length; ++i)
- stream.writeShort(interfacesIdx[i]);
-
- // Fields and methods
- stream.writeShort(fields.size());
- Iterator fieldsIt = fields.iterator();
- while (fieldsIt.hasNext())
- ((JField)fieldsIt.next()).writeTo(stream);
-
- stream.writeShort(methods.size());
- Iterator methodsIt = methods.iterator();
- while (methodsIt.hasNext())
- ((JMethod)methodsIt.next()).writeTo(stream);
-
- // Attributes
- JAttribute.writeTo(attributes, stream);
- }
-
- // Follows javap output format for ClassFile.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer();
- if (sourceFileName != null) {
- buf.append("Compiled from \"");
- buf.append(sourceFileName);
- buf.append("\"\n");
- }
- buf.append(getMemberName());
- buf.append(toExternalName(getName()));
- if (!isInterface()) {
- buf.append(" extends ");
- buf.append(toExternalName(getSuperclassName()));
- }
- if (interfaceNames.length > 0) {
- if (isInterface()) buf.append(" extends ");
- else buf.append(" implements ");
- for (int i = 0; i < interfaceNames.length; ++i) {
- if (i > 0) buf.append(",");
- buf.append(toExternalName(interfaceNames[i]));
- }
- }
- buf.append("\n");
- Iterator attrsIt = attributes.iterator();
- while (attrsIt.hasNext()) {
- JAttribute attr = (JAttribute)attrsIt.next();
- buf.append(attr);
- }
- buf.append(" minor version: ");
- buf.append(minor);
- buf.append("\n major version: ");
- buf.append(major);
- buf.append("\n");
- buf.append(pool);
- buf.append("\n{\n");
- JField[] jfields = getFields();
- for (int i = 0; i < jfields.length; ++i) {
- if (i > 0) buf.append("\n");
- buf.append(jfields[i]);
- }
- buf.append("\n");
- JMethod[] jmethods = getMethods();
- for (int i = 0; i < jmethods.length; ++i) {
- if (i > 0) buf.append("\n");
- buf.append(jmethods[i]);
- }
- buf.append("\n}\n");
- return buf.toString();
- }
-
- private String getMemberName() {
- StringBuffer buf = new StringBuffer();
- if (isPublic()) buf.append("public ");
- else if (isProtected()) buf.append("protected ");
- else if (isPrivate()) buf.append("private ");
- if (isInterface())
- buf.append("interface ");
- else {
- if (isAbstract()) buf.append("abstract ");
- else if (isFinal()) buf.append("final ");
- buf.append("class ");
- }
- return buf.toString();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JCode.java
deleted file mode 100644
index ab6934ab30..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JCode.java
+++ /dev/null
@@ -1,1308 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.*;
-
-import ch.epfl.lamp.util.ByteArray;
-
-/**
- * List of instructions, to which Java byte-code instructions can be added.
- *
- * @author Michel Schinz, Thomas Friedli
- * @version 1.0
- */
-
-public class JCode {
- protected boolean frozen = false;
-
- public static int MAX_CODE_SIZE = 65535;
-
- protected final FJBGContext context;
- protected final JMethod owner;
-
- protected final ByteArray codeArray;
-
- protected final LinkedList/*<ExceptionHandler>*/ exceptionHandlers =
- new LinkedList();
-
- protected final JConstantPool pool;
-
- protected final ArrayList/*<OffsetToPatch>*/ offsetToPatch =
- new ArrayList();
-
- protected static int UNKNOWN_STACK_SIZE = Integer.MIN_VALUE;
- protected int maxStackSize = UNKNOWN_STACK_SIZE;
- protected int[] stackProduction = null;
- protected int[] stackSizes;
-
- protected JCode(FJBGContext context, JClass clazz, JMethod owner) {
- this.context = context;
- this.pool = clazz.getConstantPool();
- this.owner = owner;
- this.codeArray = new ByteArray();
- }
-
- protected JCode(FJBGContext context,
- JClass clazz,
- JMethod owner,
- DataInputStream stream)
- throws IOException {
- this.context = context;
- this.pool = clazz.getConstantPool();
- this.owner = owner;
- owner.setCode(this);
- int size = stream.readInt();
- if (size > MAX_CODE_SIZE) // section 4.10
- throw new Error("code size must be less than " + MAX_CODE_SIZE + ": " + size);
- this.codeArray = new ByteArray(stream, size);
- }
-
- /**
- * Gets the program counter, which is defined as the address of the
- * next instruction.
- * @return The int representing the value of the program counter
- */
- public int getPC() {
- return codeArray.getSize();
- }
-
- /**
- * Gets the size of the code
- * @return The number of bytes of the code
- */
- public int getSize() {
- return codeArray.getSize();
- }
-
- /**
- * Gets the method to which the code belongs
- * @return The method to which the code belongs
- */
- public JMethod getOwner() {
- return owner;
- }
-
- // Stack size
- public int getMaxStackSize() {
- if (maxStackSize == UNKNOWN_STACK_SIZE)
- maxStackSize = computeMaxStackSize();
- return maxStackSize;
- }
-
- // Freezing
- //////////////////////////////////////////////////////////////////////
-
- public static class CodeSizeTooBigException extends OffsetTooBigException {
- public int codeSize;
-
- public CodeSizeTooBigException(int size) {
- codeSize = size;
- }
- }
-
- public void freeze() throws OffsetTooBigException {
- assert !frozen;
-
- if (getSize() > MAX_CODE_SIZE) throw new CodeSizeTooBigException(getSize());
-
- patchAllOffset();
- codeArray.freeze();
- frozen = true;
- }
-
- // Attributes
- //////////////////////////////////////////////////////////////////////
-
- protected final LinkedList/*<JAttribute>*/ attributes = new LinkedList();
-
- public void addAttribute(JAttribute attr) {
- attributes.add(attr);
- }
-
- public List/*<JAttribute>*/ getAttributes() {
- return attributes;
- }
-
- // Emitting code
- //////////////////////////////////////////////////////////////////////
-
- public void emit(JOpcode opcode) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- }
-
- public void emitNOP() { emit(JOpcode.NOP); }
-
- // Constant loading.
- public void emitACONST_NULL() { emit(JOpcode.ACONST_NULL); }
- public void emitICONST_M1() { emit(JOpcode.ICONST_M1); }
- public void emitICONST_0() { emit(JOpcode.ICONST_0); }
- public void emitICONST_1() { emit(JOpcode.ICONST_1); }
- public void emitICONST_2() { emit(JOpcode.ICONST_2); }
- public void emitICONST_3() { emit(JOpcode.ICONST_3); }
- public void emitICONST_4() { emit(JOpcode.ICONST_4); }
- public void emitICONST_5() { emit(JOpcode.ICONST_5); }
- public void emitLCONST_0() { emit(JOpcode.LCONST_0); }
- public void emitLCONST_1() { emit(JOpcode.LCONST_1); }
- public void emitFCONST_0() { emit(JOpcode.FCONST_0); }
- public void emitFCONST_1() { emit(JOpcode.FCONST_1); }
- public void emitFCONST_2() { emit(JOpcode.FCONST_2); }
- public void emitDCONST_0() { emit(JOpcode.DCONST_0); }
- public void emitDCONST_1() { emit(JOpcode.DCONST_1); }
-
- public void emitBIPUSH(int b) { emitU1(JOpcode.BIPUSH, b); }
- public void emitSIPUSH(int s) { emitU2(JOpcode.SIPUSH, s); }
- public void emitLDC(int value) {
- emitU1(JOpcode.LDC, pool.addInteger(value));
- }
- public void emitLDC(float value) {
- emitU1(JOpcode.LDC, pool.addFloat(value));
- }
- public void emitLDC(String value) {
- emitU1(JOpcode.LDC, pool.addString(value));
- }
- public void emitLDC_W(int value) {
- emitU1(JOpcode.LDC_W, pool.addInteger(value));
- }
- public void emitLDC_W(float value) {
- emitU1(JOpcode.LDC_W, pool.addFloat(value));
- }
- public void emitLDC_W(String value) {
- emitU1(JOpcode.LDC_W, pool.addString(value));
- }
- public void emitLDC2_W(long value) {
- emitU2(JOpcode.LDC2_W, pool.addLong(value));
- }
- public void emitLDC2_W(double value) {
- emitU2(JOpcode.LDC2_W, pool.addDouble(value));
- }
-
- // Loading variables.
- public void emitILOAD(int index) { emitU1(JOpcode.ILOAD, index); }
- public void emitLLOAD(int index) { emitU1(JOpcode.LLOAD, index); }
- public void emitFLOAD(int index) { emitU1(JOpcode.FLOAD, index); }
- public void emitDLOAD(int index) { emitU1(JOpcode.DLOAD, index); }
- public void emitALOAD(int index) { emitU1(JOpcode.ALOAD, index); }
-
- public void emitILOAD_0() { emit(JOpcode.ILOAD_0); }
- public void emitILOAD_1() { emit(JOpcode.ILOAD_1); }
- public void emitILOAD_2() { emit(JOpcode.ILOAD_2); }
- public void emitILOAD_3() { emit(JOpcode.ILOAD_3); }
- public void emitLLOAD_0() { emit(JOpcode.LLOAD_0); }
- public void emitLLOAD_1() { emit(JOpcode.LLOAD_1); }
- public void emitLLOAD_2() { emit(JOpcode.LLOAD_2); }
- public void emitLLOAD_3() { emit(JOpcode.LLOAD_3); }
- public void emitFLOAD_0() { emit(JOpcode.FLOAD_0); }
- public void emitFLOAD_1() { emit(JOpcode.FLOAD_1); }
- public void emitFLOAD_2() { emit(JOpcode.FLOAD_2); }
- public void emitFLOAD_3() { emit(JOpcode.FLOAD_3); }
- public void emitDLOAD_0() { emit(JOpcode.DLOAD_0); }
- public void emitDLOAD_1() { emit(JOpcode.DLOAD_1); }
- public void emitDLOAD_2() { emit(JOpcode.DLOAD_2); }
- public void emitDLOAD_3() { emit(JOpcode.DLOAD_3); }
- public void emitALOAD_0() { emit(JOpcode.ALOAD_0); }
- public void emitALOAD_1() { emit(JOpcode.ALOAD_1); }
- public void emitALOAD_2() { emit(JOpcode.ALOAD_2); }
- public void emitALOAD_3() { emit(JOpcode.ALOAD_3); }
-
- public void emitIALOAD() { emit(JOpcode.IALOAD); }
- public void emitLALOAD() { emit(JOpcode.LALOAD); }
- public void emitFALOAD() { emit(JOpcode.FALOAD); }
- public void emitDALOAD() { emit(JOpcode.DALOAD); }
- public void emitAALOAD() { emit(JOpcode.AALOAD); }
- public void emitBALOAD() { emit(JOpcode.BALOAD); }
- public void emitCALOAD() { emit(JOpcode.CALOAD); }
- public void emitSALOAD() { emit(JOpcode.SALOAD); }
-
- // Storing variables.
- public void emitISTORE(int index) { emitU1(JOpcode.ISTORE, index); }
- public void emitLSTORE(int index) { emitU1(JOpcode.LSTORE, index); }
- public void emitFSTORE(int index) { emitU1(JOpcode.FSTORE, index); }
- public void emitDSTORE(int index) { emitU1(JOpcode.DSTORE, index); }
- public void emitASTORE(int index) { emitU1(JOpcode.ASTORE, index); }
-
- public void emitISTORE_0() { emit(JOpcode.ISTORE_0); }
- public void emitISTORE_1() { emit(JOpcode.ISTORE_1); }
- public void emitISTORE_2() { emit(JOpcode.ISTORE_2); }
- public void emitISTORE_3() { emit(JOpcode.ISTORE_3); }
- public void emitLSTORE_0() { emit(JOpcode.LSTORE_0); }
- public void emitLSTORE_1() { emit(JOpcode.LSTORE_1); }
- public void emitLSTORE_2() { emit(JOpcode.LSTORE_2); }
- public void emitLSTORE_3() { emit(JOpcode.LSTORE_3); }
- public void emitFSTORE_0() { emit(JOpcode.FSTORE_0); }
- public void emitFSTORE_1() { emit(JOpcode.FSTORE_1); }
- public void emitFSTORE_2() { emit(JOpcode.FSTORE_2); }
- public void emitFSTORE_3() { emit(JOpcode.FSTORE_3); }
- public void emitDSTORE_0() { emit(JOpcode.DSTORE_0); }
- public void emitDSTORE_1() { emit(JOpcode.DSTORE_1); }
- public void emitDSTORE_2() { emit(JOpcode.DSTORE_2); }
- public void emitDSTORE_3() { emit(JOpcode.DSTORE_3); }
- public void emitASTORE_0() { emit(JOpcode.ASTORE_0); }
- public void emitASTORE_1() { emit(JOpcode.ASTORE_1); }
- public void emitASTORE_2() { emit(JOpcode.ASTORE_2); }
- public void emitASTORE_3() { emit(JOpcode.ASTORE_3); }
-
- public void emitIASTORE() { emit(JOpcode.IASTORE); }
- public void emitLASTORE() { emit(JOpcode.LASTORE); }
- public void emitFASTORE() { emit(JOpcode.FASTORE); }
- public void emitDASTORE() { emit(JOpcode.DASTORE); }
- public void emitAASTORE() { emit(JOpcode.AASTORE); }
- public void emitBASTORE() { emit(JOpcode.BASTORE); }
- public void emitCASTORE() { emit(JOpcode.CASTORE); }
- public void emitSASTORE() { emit(JOpcode.SASTORE); }
-
- // Stack manipulation.
- public void emitPOP() { emit(JOpcode.POP); }
- public void emitPOP2() { emit(JOpcode.POP2); }
- public void emitDUP() { emit(JOpcode.DUP); }
- public void emitDUP_X1() { emit(JOpcode.DUP_X1); }
- public void emitDUP_X2() { emit(JOpcode.DUP_X2); }
- public void emitDUP2() { emit(JOpcode.DUP2); }
- public void emitDUP2_X1() { emit(JOpcode.DUP2_X1); }
- public void emitDUP2_X2() { emit(JOpcode.DUP2_X2); }
- public void emitSWAP() { emit(JOpcode.SWAP); }
-
- // Artithmetic and logic operations.
- public void emitIADD() { emit(JOpcode.IADD); }
- public void emitLADD() { emit(JOpcode.LADD); }
- public void emitFADD() { emit(JOpcode.FADD); }
- public void emitDADD() { emit(JOpcode.DADD); }
-
- public void emitISUB() { emit(JOpcode.ISUB); }
- public void emitLSUB() { emit(JOpcode.LSUB); }
- public void emitFSUB() { emit(JOpcode.FSUB); }
- public void emitDSUB() { emit(JOpcode.DSUB); }
-
- public void emitIMUL() { emit(JOpcode.IMUL); }
- public void emitLMUL() { emit(JOpcode.LMUL); }
- public void emitFMUL() { emit(JOpcode.FMUL); }
- public void emitDMUL() { emit(JOpcode.DMUL); }
-
- public void emitIDIV() { emit(JOpcode.IDIV); }
- public void emitLDIV() { emit(JOpcode.LDIV); }
- public void emitFDIV() { emit(JOpcode.FDIV); }
- public void emitDDIV() { emit(JOpcode.DDIV); }
-
- public void emitIREM() { emit(JOpcode.IREM); }
- public void emitLREM() { emit(JOpcode.LREM); }
- public void emitFREM() { emit(JOpcode.FREM); }
- public void emitDREM() { emit(JOpcode.DREM); }
-
- public void emitINEG() { emit(JOpcode.INEG); }
- public void emitLNEG() { emit(JOpcode.LNEG); }
- public void emitFNEG() { emit(JOpcode.FNEG); }
- public void emitDNEG() { emit(JOpcode.DNEG); }
-
- public void emitISHL() { emit(JOpcode.ISHL); }
- public void emitLSHL() { emit(JOpcode.LSHL); }
-
- public void emitISHR() { emit(JOpcode.ISHR); }
- public void emitLSHR() { emit(JOpcode.LSHR); }
-
- public void emitIUSHR() { emit(JOpcode.IUSHR); }
- public void emitLUSHR() { emit(JOpcode.LUSHR); }
-
- public void emitIAND() { emit(JOpcode.IAND); }
- public void emitLAND() { emit(JOpcode.LAND); }
-
- public void emitIOR() { emit(JOpcode.IOR); }
- public void emitLOR() { emit(JOpcode.LOR); }
-
- public void emitIXOR() { emit(JOpcode.IXOR); }
- public void emitLXOR() { emit(JOpcode.LXOR); }
-
- public void emitIINC(int index, int increment) {
- emitU1U1(JOpcode.IINC, index, increment);
- }
-
- // (Numeric) type conversions.
- public void emitI2L() { emit(JOpcode.I2L); }
- public void emitI2F() { emit(JOpcode.I2F); }
- public void emitI2D() { emit(JOpcode.I2D); }
- public void emitL2I() { emit(JOpcode.L2I); }
- public void emitL2F() { emit(JOpcode.L2F); }
- public void emitL2D() { emit(JOpcode.L2D); }
- public void emitF2I() { emit(JOpcode.F2I); }
- public void emitF2L() { emit(JOpcode.F2L); }
- public void emitF2D() { emit(JOpcode.F2D); }
- public void emitD2I() { emit(JOpcode.D2I); }
- public void emitD2L() { emit(JOpcode.D2L); }
- public void emitD2F() { emit(JOpcode.D2F); }
- public void emitI2B() { emit(JOpcode.I2B); }
- public void emitI2C() { emit(JOpcode.I2C); }
- public void emitI2S() { emit(JOpcode.I2S); }
-
- // Comparisons and tests.
- public void emitLCMP() { emit(JOpcode.LCMP); }
- public void emitFCMPL() { emit(JOpcode.FCMPL); }
- public void emitFCMPG() { emit(JOpcode.FCMPG); }
- public void emitDCMPL() { emit(JOpcode.DCMPL); }
- public void emitDCMPG() { emit(JOpcode.DCMPG); }
-
- protected void emitGenericIF(JOpcode opcode, Label label)
- throws OffsetTooBigException {
- emitU2(opcode, label.getOffset16(getPC() + 1, getPC()));
- }
-
- public void emitIFEQ(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFEQ, label);
- }
- public void emitIFEQ(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFEQ, targetPC - getPC());
- }
- public void emitIFEQ() {
- emitU2(JOpcode.IFEQ, 0);
- }
-
- public void emitIFNE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFNE, label);
- }
- public void emitIFNE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFNE, targetPC - getPC());
- }
- public void emitIFNE() {
- emitU2(JOpcode.IFNE, 0);
- }
-
- public void emitIFLT(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFLT, label);
- }
- public void emitIFLT(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFLT, targetPC - getPC());
- }
- public void emitIFLT() {
- emitU2(JOpcode.IFLT, 0);
- }
-
- public void emitIFGE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFGE, label);
- }
- public void emitIFGE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFGE, targetPC - getPC());
- }
- public void emitIFGE() {
- emitU2(JOpcode.IFGE, 0);
- }
-
- public void emitIFGT(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFGT, label);
- }
- public void emitIFGT(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFGT, targetPC - getPC());
- }
- public void emitIFGT() {
- emitU2(JOpcode.IFGT, 0);
- }
-
- public void emitIFLE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFLE, label);
- }
- public void emitIFLE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFLE, targetPC - getPC());
- }
- public void emitIFLE() {
- emitU2(JOpcode.IFLE, 0);
- }
-
- public void emitIF_ICMPEQ(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPEQ, label);
- }
- public void emitIF_ICMPEQ(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPEQ, targetPC - getPC());
- }
- public void emitIF_ICMPEQ() {
- emitU2(JOpcode.IF_ICMPEQ, 0);
- }
-
- public void emitIF_ICMPNE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPNE, label);
- }
- public void emitIF_ICMPNE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPNE, targetPC - getPC());
- }
- public void emitIF_ICMPNE() {
- emitU2(JOpcode.IF_ICMPNE, 0);
- }
-
- public void emitIF_ICMPLT(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPLT, label);
- }
- public void emitIF_ICMPLT(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPLT, targetPC - getPC());
- }
- public void emitIF_ICMPLT() {
- emitU2(JOpcode.IF_ICMPLT, 0);
- }
-
- public void emitIF_ICMPGE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPGE, label);
- }
- public void emitIF_ICMPGE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPGE, targetPC - getPC());
- }
- public void emitIF_ICMPGE() {
- emitU2(JOpcode.IF_ICMPGE, 0);
- }
-
- public void emitIF_ICMPGT(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPGT, label);
- }
- public void emitIF_ICMPGT(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPGT, targetPC - getPC());
- }
- public void emitIF_ICMPGT() {
- emitU2(JOpcode.IF_ICMPGT, 0);
- }
-
- public void emitIF_ICMPLE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ICMPLE, label);
- }
- public void emitIF_ICMPLE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ICMPLE, targetPC - getPC());
- }
- public void emitIF_ICMPLE() {
- emitU2(JOpcode.IF_ICMPLE, 0);
- }
-
- public void emitIF_ACMPEQ(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ACMPEQ, label);
- }
- public void emitIF_ACMPEQ(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ACMPEQ, targetPC - getPC());
- }
- public void emitIF_ACMPEQ() {
- emitU2(JOpcode.IF_ACMPEQ, 0);
- }
-
- public void emitIF_ACMPNE(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IF_ACMPNE, label);
- }
- public void emitIF_ACMPNE(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IF_ACMPNE, targetPC - getPC());
- }
- public void emitIF_ACMPNE() {
- emitU2(JOpcode.IF_ACMPNE, 0);
- }
-
- public void emitIFNULL(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFNULL, label);
- }
- public void emitIFNULL(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFNULL, targetPC - getPC());
- }
- public void emitIFNULL() {
- emitU2(JOpcode.IFNULL, 0);
- }
-
- public void emitIFNONNULL(Label label) throws OffsetTooBigException {
- emitGenericIF(JOpcode.IFNONNULL, label);
- }
- public void emitIFNONNULL(int targetPC) throws OffsetTooBigException {
- emitU2(JOpcode.IFNONNULL, targetPC - getPC());
- }
- public void emitIFNONNULL() {
- emitU2(JOpcode.IFNONNULL, 0);
- }
-
- public void emitGOTO(Label label) throws OffsetTooBigException {
- emitU2(JOpcode.GOTO, label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitGOTO(int targetPC) throws OffsetTooBigException {
- int offset = targetPC - getPC();
- checkOffset16(offset);
- emitU2(JOpcode.GOTO, offset);
- }
- public void emitGOTO() {
- emitU2(JOpcode.GOTO, 0);
- }
-
- public void emitGOTO_W(Label label) {
- emitU4(JOpcode.GOTO_W, label.getOffset32(getPC() + 1, getPC()));
- }
- public void emitGOTO_W(int targetPC) {
- emitU4(JOpcode.GOTO_W, targetPC - getPC());
- }
- public void emitGOTO_W() {
- emitU4(JOpcode.GOTO_W, 0);
- }
-
- public void emitJSR(Label label) throws OffsetTooBigException {
- emitU2(JOpcode.JSR, label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitJSR(int targetPC) {
- emitU2(JOpcode.JSR, targetPC - getPC());
- }
- public void emitJSR() {
- emitU2(JOpcode.JSR, 0);
- }
-
- public void emitJSR_W(Label label) {
- emitU4(JOpcode.JSR_W, label.getOffset32(getPC() + 1, getPC()));
- }
- public void emitJSR_W(int targetPC) {
- emitU4(JOpcode.JSR_W, targetPC - getPC());
- }
- public void emitJSR_W() {
- emitU4(JOpcode.JSR_W, 0);
- }
-
- /*
- public void emitRET(Label label) throws OffsetTooBigException {
- emitU2(JOpcode.RET, label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitRET(int targetPC) {
- emitU1(JOpcode.RET, targetPC);
- }
- public void emitRET() {
- emitU1(JOpcode.RET, 0);
- }
- */
-
- public void emitRET(int index) {
- emitU1(JOpcode.RET, index);
- }
-
- public void emitRET(JLocalVariable var) {
- emitRET(var.getIndex());
- }
-
- public void emitTABLESWITCH(int[] keys,
- Label[] branches,
- Label defaultBranch) {
- assert keys.length == branches.length;
-
- int low = keys[0], high = keys[keys.length - 1];
- int instrPC = getPC();
-
- setStackProduction(instrPC, JOpcode.TABLESWITCH);
- codeArray.addU1(JOpcode.cTABLESWITCH);
- while (getPC() % 4 != 0) codeArray.addU1(0);
-
- codeArray.addU4(defaultBranch.getOffset32(getPC(), instrPC));
- codeArray.addU4(low);
- codeArray.addU4(high);
- for (int i = 0; i < branches.length; i++) {
- assert keys[i] == low + i;
- codeArray.addU4(branches[i].getOffset32(getPC(), instrPC));
- }
- }
-
- public void emitLOOKUPSWITCH(int[] keys,
- Label[] branches,
- Label defaultBranch) {
- assert keys.length == branches.length;
-
- int instrPC = getPC();
- setStackProduction(getPC(), JOpcode.LOOKUPSWITCH);
- codeArray.addU1(JOpcode.cLOOKUPSWITCH);
- while (getPC() % 4 != 0) codeArray.addU1(0);
-
- codeArray.addU4(defaultBranch.getOffset32(getPC(), instrPC));
- codeArray.addU4(branches.length);
- for (int i = 0; i < branches.length; i++) {
- codeArray.addU4(keys[i]);
- codeArray.addU4(branches[i].getOffset32(getPC(), instrPC));
- }
- }
-
- public void emitIRETURN() { emit(JOpcode.IRETURN); }
- public void emitLRETURN() { emit(JOpcode.LRETURN); }
- public void emitFRETURN() { emit(JOpcode.FRETURN); }
- public void emitDRETURN() { emit(JOpcode.DRETURN); }
- public void emitARETURN() { emit(JOpcode.ARETURN); }
- public void emitRETURN() { emit(JOpcode.RETURN); }
-
- // Field access
- public void emitGETSTATIC(String className, String name, JType type) {
- setStackProduction(getPC(), type.getSize());
- int index = pool.addFieldRef(className, name, type.getSignature());
- emitU2(JOpcode.GETSTATIC, index);
- }
- public void emitPUTSTATIC(String className, String name, JType type) {
- setStackProduction(getPC(), -type.getSize());
- int index = pool.addFieldRef(className, name, type.getSignature());
- emitU2(JOpcode.PUTSTATIC, index);
- }
- public void emitGETFIELD(String className, String name, JType type) {
- setStackProduction(getPC(), type.getSize() - 1);
- int index = pool.addFieldRef(className, name, type.getSignature());
- emitU2(JOpcode.GETFIELD, index);
- }
- public void emitPUTFIELD(String className, String name, JType type) {
- setStackProduction(getPC(), -(type.getSize() + 1));
- int index = pool.addFieldRef(className, name, type.getSignature());
- emitU2(JOpcode.PUTFIELD, index);
- }
-
- // Method invocation
- public void emitINVOKEVIRTUAL(String className,
- String name,
- JMethodType type) {
- setStackProduction(getPC(), type.getProducedStack() - 1);
- int index =
- pool.addClassMethodRef(className, name, type.getSignature());
- emitU2(JOpcode.INVOKEVIRTUAL, index);
- }
- public void emitINVOKESPECIAL(String className,
- String name,
- JMethodType type) {
- setStackProduction(getPC(), type.getProducedStack() - 1);
- int index =
- pool.addClassMethodRef(className, name, type.getSignature());
- emitU2(JOpcode.INVOKESPECIAL, index);
- }
- public void emitINVOKESTATIC(String className,
- String name,
- JMethodType type) {
- setStackProduction(getPC(), type.getProducedStack());
- int index =
- pool.addClassMethodRef(className, name, type.getSignature());
- emitU2(JOpcode.INVOKESTATIC, index);
- }
- public void emitINVOKEINTERFACE(String className,
- String name,
- JMethodType type) {
- setStackProduction(getPC(), type.getProducedStack() - 1);
- int index =
- pool.addInterfaceMethodRef(className, name, type.getSignature());
- emitU2U1U1(JOpcode.INVOKEINTERFACE, index, type.getArgsSize() + 1, 0);
- }
-
- // Object creation
- public void emitNEW(String className) {
- emitU2(JOpcode.NEW, pool.addClass(className));
- }
- public void emitNEWARRAY(JType elemType) {
- emitU1(JOpcode.NEWARRAY, elemType.getTag());
- }
- public void emitANEWARRAY(JReferenceType elemType) {
- emitU2(JOpcode.ANEWARRAY, pool.addDescriptor(elemType));
- }
- public void emitMULTIANEWARRAY(JReferenceType elemType, int dimensions) {
- setStackProduction(getPC(), -dimensions + 1);
- emitU2U1(JOpcode.MULTIANEWARRAY,
- pool.addDescriptor(elemType),
- dimensions);
- }
- public void emitARRAYLENGTH() { emit(JOpcode.ARRAYLENGTH); }
-
- // Exception throwing
- public void emitATHROW() { emit(JOpcode.ATHROW); }
-
- // Dynamic typing
- public void emitCHECKCAST(JReferenceType type) {
- emitU2(JOpcode.CHECKCAST, pool.addDescriptor(type));
- }
- public void emitINSTANCEOF(JReferenceType type) {
- emitU2(JOpcode.INSTANCEOF, pool.addDescriptor(type));
- }
-
- // Monitors
- public void emitMONITORENTER() { emit(JOpcode.MONITORENTER); }
- public void emitMONITOREXIT() { emit(JOpcode.MONITOREXIT); }
-
- // Wide variants
- // FIXME setStackProd. will here raise an exception
- public void emitWIDE(JOpcode opcode, int index) {
- assert (opcode.code == JOpcode.cILOAD)
- || (opcode.code == JOpcode.cLLOAD)
- || (opcode.code == JOpcode.cFLOAD)
- || (opcode.code == JOpcode.cDLOAD)
- || (opcode.code == JOpcode.cALOAD)
- || (opcode.code == JOpcode.cISTORE)
- || (opcode.code == JOpcode.cLSTORE)
- || (opcode.code == JOpcode.cFSTORE)
- || (opcode.code == JOpcode.cDSTORE)
- || (opcode.code == JOpcode.cASTORE)
- || (opcode.code == JOpcode.cRET)
- : "invalide opcode for WIDE: " + opcode;
-
- setStackProduction(getPC(), opcode);
- codeArray.addU1(JOpcode.WIDE.code);
- codeArray.addU1(opcode.code);
- codeArray.addU2(index);
- }
- public void emitWIDE(JOpcode opcode, int index, int constant) {
- assert opcode.code == JOpcode.cIINC
- : "invalid opcode for WIDE: " + opcode;
-
- setStackProduction(getPC(), opcode);
- codeArray.addU1(JOpcode.cWIDE);
- codeArray.addU1(opcode.code);
- codeArray.addU2(index);
- codeArray.addU2(constant);
- }
-
- protected void emitU1(JOpcode opcode, int i1) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU1(i1);
- }
-
- protected void emitU1U1(JOpcode opcode, int i1, int i2) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU1(i1);
- codeArray.addU1(i2);
- }
-
- protected void emitU2(JOpcode opcode, int i1) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU2(i1);
- }
-
- protected void emitU2U1(JOpcode opcode, int i1, int i2) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU2(i1);
- codeArray.addU1(i2);
- }
-
- protected void emitU2U1U1(JOpcode opcode, int i1, int i2, int i3) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU2(i1);
- codeArray.addU1(i2);
- codeArray.addU1(i3);
- }
-
- protected void emitU4(JOpcode opcode, int i1) {
- setStackProduction(getPC(), opcode);
- codeArray.addU1(opcode.code);
- codeArray.addU4(i1);
- }
-
- protected int getU1(int sourcePos) {
- return codeArray.getU1(sourcePos);
- }
-
- protected int getU2(int sourcePos) {
- return codeArray.getU2(sourcePos);
- }
-
- protected int getU4(int sourcePos) {
- return codeArray.getU4(sourcePos);
- }
-
- protected int getS1(int sourcePos) {
- return codeArray.getS1(sourcePos);
- }
-
- protected int getS2(int sourcePos) {
- return codeArray.getS2(sourcePos);
- }
-
- protected int getS4(int sourcePos) {
- return codeArray.getS4(sourcePos);
- }
-
- // Stack size computation
- //////////////////////////////////////////////////////////////////////
-
- protected int getStackProduction(int pc) {
- if (stackProduction == null || pc >= stackProduction.length)
- return UNKNOWN_STACK_SIZE;
- else
- return stackProduction[pc];
- }
-
- protected void setStackProduction(int pc, int production) {
- if (stackProduction == null) {
- stackProduction = new int[256];
- Arrays.fill(stackProduction, UNKNOWN_STACK_SIZE);
- } else {
- while (pc >= stackProduction.length) {
- int[] newStackProduction = new int[stackProduction.length * 2];
- System.arraycopy(stackProduction, 0,
- newStackProduction, 0,
- stackProduction.length);
- Arrays.fill(newStackProduction,
- stackProduction.length,
- newStackProduction.length,
- UNKNOWN_STACK_SIZE);
- stackProduction = newStackProduction;
- }
- }
- stackProduction[pc] = production;
- }
-
- protected void setStackProduction(int pc, JOpcode opcode) {
- // TODO we should instead check whether the opcode has known
- // stack consumption/production.
- if (getStackProduction(pc) == UNKNOWN_STACK_SIZE)
-// && opcode.hasKnownProducedDataSize()
-// && opcode.hasKnownConsumedDataSize())
- setStackProduction(pc,
- opcode.getProducedDataSize()
- - opcode.getConsumedDataSize());
- }
-
- protected int computeMaxStackSize() {
- if (stackSizes == null) {
- stackSizes = new int[getSize()];
- Arrays.fill(stackSizes, UNKNOWN_STACK_SIZE);
- stackSizes[0] = 0;
- }
- int size = computeMaxStackSize(0, 0, 0);
-
- // compute stack sizes for exception handlers too
- ExceptionHandler exh = null;
- for (Iterator it = exceptionHandlers.iterator();
- it.hasNext();) {
- exh = (ExceptionHandler)it.next();
- int exhSize = computeMaxStackSize(exh.getHandlerPC(), 1, 1);
- if (size < exhSize)
- size = exhSize;
- }
-
- return size;
- }
-
- protected int computeMaxStackSize(int pc, int stackSize, int maxStackSize) {
- JCodeIterator iterator = new JCodeIterator(this, pc);
- for (;;) {
- int successors = iterator.getSuccessorCount();
- if (successors == 0)
- return maxStackSize;
- else {
- assert stackProduction[iterator.getPC()] != UNKNOWN_STACK_SIZE
- : "unknown stack production, pc=" + iterator.getPC()
- + " in method " + owner.getName();
- stackSize += stackProduction[iterator.getPC()];
- if (stackSize > maxStackSize)
- maxStackSize = stackSize;
- int nextPC = -1;
- for (int i = 0; i < successors; ++i) {
- int succPC = iterator.getSuccessorPC(i);
- assert succPC >= 0 && succPC < stackSizes.length
- : iterator.getPC() + ": invalid pc: " + succPC
- + " op: " + iterator.getOpcode();
- if (stackSizes[succPC] == UNKNOWN_STACK_SIZE) {
- stackSizes[succPC] = stackSize;
- if (nextPC == -1)
- nextPC = succPC;
- else
- maxStackSize = computeMaxStackSize(succPC,
- stackSize,
- maxStackSize);
- }
- }
- if (nextPC == -1)
- return maxStackSize;
- else
- iterator.moveTo(nextPC);
- }
- }
- }
-
- // Labels
- //////////////////////////////////////////////////////////////////////
-
- public static class OffsetTooBigException extends Exception {
- public OffsetTooBigException() { super(); }
- public OffsetTooBigException(String message) { super(message); }
- }
-
- protected void checkOffset16(int offset) throws OffsetTooBigException {
- if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE)
- throw new OffsetTooBigException("offset too big to fit"
- + " in 16 bits: " + offset);
- }
-
- public class Label {
- protected boolean anchored = false;
- protected int targetPC = 0;
-
- public void anchorToNext() {
- assert !anchored;
- this.targetPC = getPC();
- anchored = true;
- }
-
- public int getAnchor() {
- assert anchored;
- return targetPC;
- }
-
- protected int getOffset16(int pc, int instrPC)
- throws OffsetTooBigException {
- if (anchored) {
- int offset = targetPC - instrPC;
- checkOffset16(offset);
- return offset;
- } else {
- recordOffsetToPatch(pc, 16, instrPC, this);
- return 0;
- }
- }
-
- protected int getOffset32(int pc, int instrPC) {
- if (anchored)
- return targetPC - instrPC;
- else {
- recordOffsetToPatch(pc, 32, instrPC, this);
- return 0;
- }
- }
- }
-
- public Label newLabel() {
- return new Label();
- }
-
- public Label[] newLabels(int count) {
- Label[] labels = new Label[count];
- for (int i = 0; i < labels.length; ++i)
- labels[i] = newLabel();
- return labels;
- }
-
- protected static class OffsetToPatch {
- public final int pc;
- public final int size;
- public final int instrPC;
- public final Label label;
-
- public OffsetToPatch(int pc, int size, int instrPC, Label label) {
- this.pc = pc;
- this.size = size;
- this.instrPC = instrPC;
- this.label = label;
- }
- }
-
- protected void recordOffsetToPatch(int offsetPC,
- int size,
- int instrPC,
- Label label) {
- offsetToPatch.add(new OffsetToPatch(offsetPC, size, instrPC, label));
- }
-
- protected void patchAllOffset() throws OffsetTooBigException {
- Iterator offsetIt = offsetToPatch.iterator();
- while (offsetIt.hasNext()) {
- OffsetToPatch offset = (OffsetToPatch)offsetIt.next();
- int offsetValue = offset.label.getAnchor() - offset.instrPC;
- if (offset.size == 16) {
- checkOffset16(offsetValue);
- codeArray.putU2(offset.pc, offsetValue);
- } else
- codeArray.putU4(offset.pc, offsetValue);
- }
- }
-
- // Exception handling
- //////////////////////////////////////////////////////////////////////
-
- public class ExceptionHandler {
- protected int startPC, endPC, handlerPC;
- protected final String catchType;
- protected final int catchTypeIndex;
-
- public void setStartPC(int pc) {
- this.startPC = pc;
- }
-
- public int getStartPC() {
- return this.startPC;
- }
-
- public void setEndPC(int pc) {
- this.endPC = pc;
- }
-
- public int getEndPC() {
- return this.endPC;
- }
-
- public void setHandlerPC(int pc) {
- this.handlerPC = pc;
- }
-
- public int getHandlerPC() {
- return this.handlerPC;
- }
-
- public ExceptionHandler(String catchType) {
- this(0, 0, 0, catchType);
- }
-
- public ExceptionHandler(int startPC,
- int endPC,
- int handlerPC,
- String catchType) {
- this.startPC = startPC;
- this.endPC = endPC;
- this.handlerPC = handlerPC;
- this.catchType = catchType;
- this.catchTypeIndex = (catchType == null
- ? 0
- : pool.addClass(catchType));
- }
-
- public ExceptionHandler(DataInputStream stream) throws IOException {
- this.startPC = stream.readShort();
- this.endPC = stream.readShort();
- this.handlerPC = stream.readShort();
- this.catchTypeIndex = stream.readShort();
- this.catchType = (catchTypeIndex == 0
- ? null
- : pool.lookupClass(catchTypeIndex));
- }
-
- public void writeTo(DataOutputStream stream) throws IOException {
- stream.writeShort(startPC);
- stream.writeShort(endPC);
- stream.writeShort(handlerPC);
- stream.writeShort(catchTypeIndex);
- }
-
- // Follows javap output format for exception handlers.
- /*@Override*/public String toString() {
- StringBuffer buf = new StringBuffer(" ");
- if (startPC < 10) buf.append(" ");
- buf.append(startPC);
- buf.append(" ");
- if (endPC < 10) buf.append(" ");
- buf.append(endPC);
- buf.append(" ");
- buf.append(handlerPC);
- buf.append(" ");
- if (catchType != null) {
- buf.append("Class ");
- buf.append(catchType);
- }
- else
- buf.append("any");
- return buf.toString();
- }
-
- }
-
- public void addExceptionHandler(ExceptionHandler handler) {
- assert !frozen;
- exceptionHandlers.add(handler);
- }
-
- public void addExceptionHandler(int startPC,
- int endPC,
- int handlerPC,
- String catchType) {
- addExceptionHandler(new ExceptionHandler(startPC,
- endPC,
- handlerPC,
- catchType));
- }
-
- public void addFinallyHandler(int startPC, int endPC, int handlerPC) {
- assert !frozen;
- addExceptionHandler(startPC, endPC, handlerPC, null);
- }
-
- public List/*<ExceptionHandler>*/ getExceptionHandlers() {
- return exceptionHandlers;
- }
-
- // Line numbers
- //////////////////////////////////////////////////////////////////////
-
- protected int[] lineNumbers = null;
- protected void ensureLineNumberCapacity(int endPC) {
- assert !frozen;
- if (lineNumbers == null) {
- lineNumbers = new int[endPC];
- addAttribute(context.JLineNumberTableAttribute(owner.getOwner(),
- this));
- } else if (lineNumbers.length < endPC) {
- int[] newLN = new int[Math.max(endPC, lineNumbers.length * 2)];
- System.arraycopy(lineNumbers, 0, newLN, 0, lineNumbers.length);
- lineNumbers = newLN;
- }
- }
-
- /**
- * Set all line numbers in the interval [startPC, endPC) to
- * line, overwriting existing line numbers.
- */
- public void setLineNumber(int startPC, int endPC, int line) {
- ensureLineNumberCapacity(endPC);
- Arrays.fill(lineNumbers, startPC, endPC, line);
- }
-
- public void setLineNumber(int instrPC, int line) {
- setLineNumber(instrPC, instrPC + 1, line);
- }
-
- /** Sets all non-filled line numbers in the interval [startPC, endPC)
- * to 'line'.
- */
- public void completeLineNumber(int startPC, int endPC, int line) {
- ensureLineNumberCapacity(endPC);
- for (int pc = startPC; pc < endPC; ++pc)
- if (lineNumbers[pc] == 0) lineNumbers[pc] = line;
- }
-
- public int[] getLineNumbers() {
- assert frozen;
- if (lineNumbers == null) return new int[0];
- else if (lineNumbers.length == getPC()) return lineNumbers;
- else {
- int[] trimmedLN = new int[getPC()];
- System.arraycopy(lineNumbers, 0,
- trimmedLN, 0,
- Math.min(lineNumbers.length, trimmedLN.length));
- return trimmedLN;
- }
- }
-
- // Output
- //////////////////////////////////////////////////////////////////////
-
- public void writeTo(DataOutputStream stream) throws IOException {
- assert frozen;
- stream.writeInt(getSize());
- codeArray.writeTo(stream);
- }
-
- // Follows javap output format for opcodes.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer();
- JOpcode opcode = null;
- int pc = 0, addr = 0;
- while (pc < codeArray.getSize()) {
- buf.append("\n ");
- buf.append(pc);
- buf.append(":\t");
- opcode = JOpcode.OPCODES[codeArray.getU1(pc)];
- buf.append(decode(opcode, pc));
- if (opcode.code == JOpcode.cTABLESWITCH ||
- opcode.code == JOpcode.cLOOKUPSWITCH) {
- addr = ((pc / 4 + 1) + 1) * 4; // U4 aligned data
- int low = codeArray.getU4(addr);
- int high = codeArray.getU4(addr+4);
- pc = addr + (2/*low+high*/ + (high - low + 1)/*targets*/) * 4;
- } else
- pc += opcode.getSize();
- }
- if (exceptionHandlers.size() > 0) {
- buf.append("\n Exception table:\n from to target type\n");
- Iterator it = exceptionHandlers.iterator();
- while (it.hasNext()) {
- ExceptionHandler exh = (ExceptionHandler)it.next();
- buf.append(exh);
- buf.append("\n");
- }
- }
- return buf.toString();
- }
-
- private String decode(JOpcode opcode, int pc) {
- String ownerClassName = owner.getOwner().getName();
- int data, data2;
- StringBuilder buf = new StringBuilder();
- buf.append(opcode.name.toLowerCase());
- switch (opcode.code) {
- case JOpcode.cALOAD: case JOpcode.cASTORE: case JOpcode.cBIPUSH:
- case JOpcode.cDLOAD: case JOpcode.cDSTORE:
- case JOpcode.cFLOAD: case JOpcode.cFSTORE:
- case JOpcode.cILOAD: case JOpcode.cISTORE:
- case JOpcode.cLLOAD: case JOpcode.cLSTORE:
- data = codeArray.getU1(pc+1);
- buf.append("\t");
- buf.append(data);
- break;
- case JOpcode.cLDC:
- data = codeArray.getU1(pc+1);
- buf.append("\t#");
- buf.append(data);
- buf.append("; ");
- buf.append(pool.lookupEntry(data).toComment(ownerClassName));
- break;
- case JOpcode.cNEWARRAY:
- data = codeArray.getU1(pc+1);
- buf.append(" ");
- buf.append(JType.tagToString(data));
- break;
- case JOpcode.cIINC:
- data = codeArray.getU1(pc+1);
- data2 = codeArray.getU1(pc+2);
- buf.append("\t");
- buf.append(data);
- buf.append(", ");
- buf.append(data2);
- break;
- case JOpcode.cSIPUSH:
- data = codeArray.getU2(pc+1);
- buf.append("\t");
- buf.append(data);
- break;
- case JOpcode.cANEWARRAY: case JOpcode.cCHECKCAST:
- case JOpcode.cGETFIELD: case JOpcode.cGETSTATIC:
- case JOpcode.cINSTANCEOF:
- case JOpcode.cINVOKESPECIAL: case JOpcode.cINVOKESTATIC:
- case JOpcode.cINVOKEVIRTUAL:
- case JOpcode.cLDC_W: case JOpcode.cLDC2_W: case JOpcode.cNEW:
- case JOpcode.cPUTFIELD: case JOpcode.cPUTSTATIC:
- data = codeArray.getU2(pc+1);
- buf.append("\t#");
- buf.append(data);
- buf.append("; ");
- buf.append(pool.lookupEntry(data).toComment(ownerClassName));
- break;
- case JOpcode.cIF_ACMPEQ: case JOpcode.cIF_ACMPNE:
- case JOpcode.cIFEQ: case JOpcode.cIFGE: case JOpcode.cIFGT:
- case JOpcode.cIFLE: case JOpcode.cIFLT: case JOpcode.cIFNE:
- case JOpcode.cIFNONNULL: case JOpcode.cIFNULL:
- case JOpcode.cIF_ICMPEQ: case JOpcode.cIF_ICMPGE:
- case JOpcode.cIF_ICMPGT: case JOpcode.cIF_ICMPLE:
- case JOpcode.cIF_ICMPLT: case JOpcode.cIF_ICMPNE:
- data = codeArray.getU2(pc+1); // maybe S2 offset
- buf.append("\t");
- buf.append(pc+data);
- break;
- case JOpcode.cGOTO:
- data = codeArray.getS2(pc+1); // always S2 offset
- buf.append("\t");
- buf.append(pc+data);
- break;
- case JOpcode.cINVOKEINTERFACE:
- data = codeArray.getU2(pc+1);
- data2 = codeArray.getU1(pc+3);
- buf.append("\t#");
- buf.append(data);
- buf.append(", ");
- buf.append(data2);
- buf.append("; ");
- buf.append(pool.lookupEntry(data).toComment(ownerClassName));
- break;
- case JOpcode.cTABLESWITCH:
- buf.append("{ //");
- int addr = ((pc / 4 + 1) + 1) * 4; // U4 aligned data
- int low = codeArray.getU4(addr);
- int high = codeArray.getU4(addr+4);
- buf.append(low);
- buf.append(" to ");
- buf.append(high);
- for (int i = low; i <= high; ++i) {
- buf.append("\n\t\t");
- buf.append(i);
- buf.append(": ");
- buf.append(pc+codeArray.getU4(addr+(i-1)*4));
- buf.append(";");
- }
- buf.append("\n\t\tdefault: ");
- buf.append(pc+codeArray.getU4(addr-4));
- buf.append(" }");
- default:
- }
- return buf.toString();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java
deleted file mode 100644
index 9f3fcf8c6a..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Code attribute, containing code of methods.
- *
- * A Code attribute contains the JVM instructions and auxiliary information
- * for a single method, instance initialization method, or class or interface
- * initialization method. See section 4.8.3 of the JVM specification.
- *
- * @author Michel Schinz, Stephane Micheloud
- * @version 1.1
- */
-
-public class JCodeAttribute extends JAttribute {
- protected final JCode code;
- protected final JMethod owner;
- protected static int UNKNOWN_STACK_SIZE = Integer.MIN_VALUE;
- protected final int maxStackSize;
- protected final int maxLocals;
-
- public JCodeAttribute(FJBGContext context, JClass clazz, JMethod owner) {
- super(context, clazz);
- this.owner = owner;
-
- this.maxStackSize = UNKNOWN_STACK_SIZE;
- this.maxLocals = 0; // unknown
- this.code = owner.getCode();
-
- assert clazz == owner.getOwner();
- }
-
- public JCodeAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.owner = (JMethod)owner;
-
- this.maxStackSize = stream.readShort();
- this.maxLocals = stream.readShort();
- this.code = context.JCode(clazz, (JMethod)owner, stream);
-
- int handlersCount = stream.readShort();
- for (int i = 0; i < handlersCount; ++i)
- code.addExceptionHandler(code.new ExceptionHandler(stream));
- List/*<JAttribute>*/ attributes =
- JAttribute.readFrom(context, clazz, code, stream);
- Iterator attrIt = attributes.iterator();
- while (attrIt.hasNext())
- code.addAttribute((JAttribute)attrIt.next());
-
- assert name.equals(getName());
- }
-
- public String getName() { return "Code"; }
-
- // Follows javap output format for Code attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" Code:");
- buf.append("\n Stack=");
- buf.append(maxStackSize);
- buf.append(", Locals=");
- buf.append(maxLocals);
- buf.append(", Args_size=");
- buf.append(owner.getArgsSize());
- buf.append(code);
- buf.append("\n");
- Iterator it = code.getAttributes().iterator();
- while (it.hasNext()) {
- JAttribute attr = (JAttribute)it.next();
- buf.append(attr);
- buf.append("\n");
- }
- return buf.toString();
- }
-
- protected int getSize() {
- int handlersNum = code.getExceptionHandlers().size();
-
- int attrsSize = 0;
- Iterator attrsIt = code.getAttributes().iterator();
- while (attrsIt.hasNext()) {
- JAttribute attr = (JAttribute)attrsIt.next();
- attrsSize += attr.getSize() + 6;
- }
-
- return 2 // max stack
- + 2 // max locals
- + 4 // code size
- + code.getSize() // code
- + 2 // exception table size
- + 8 * handlersNum // exception table
- + 2 // attributes count
- + attrsSize; // attributes
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- List/*<ExceptionHandler>*/ handlers = code.getExceptionHandlers();
-
- stream.writeShort(code.getMaxStackSize());
- stream.writeShort(owner.getMaxLocals());
-
- code.writeTo(stream);
-
- stream.writeShort(handlers.size());
- Iterator handlerIt = handlers.iterator();
- while (handlerIt.hasNext())
- ((JCode.ExceptionHandler)handlerIt.next()).writeTo(stream);
- JAttribute.writeTo(code.getAttributes(), stream);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java b/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java
deleted file mode 100644
index d09dfd19a4..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import ch.epfl.lamp.util.ByteArray;
-
-/**
- * Iterator used to examine the contents of an instruction list.
- *
- * @author Michel Schinz, Thomas Friedli
- * @version 1.0
- */
-
-public class JCodeIterator {
- protected final JCode code;
- protected final JConstantPool pool;
- protected final ByteArray codeArray;
-
- protected int pc;
- protected JOpcode opcode;
-
- /**
- * Creates a new code iterator with its instruction list
- * and its pc initialized to a given value.
- */
- public JCodeIterator(JCode code, int pc) {
- this.code = code;
- this.pool = code.getOwner().getOwner().getConstantPool();
- this.codeArray = code.codeArray;
- this.pc = pc;
- setOpcode();
- }
-
- public JCodeIterator(JCode code) {
- this(code, 0);
- }
-
- /**
- * Get the current program counter.
- * @return The current program counter.
- */
- public int getPC() { return pc; }
-
- /**
- * Searches the type of the instruction positionned at the
- * current address and updates the current instruction.
- */
- protected void setOpcode() {
- // TODO : check if the current pc is the beginning
- // of an instruction
- opcode = isValid() ? JOpcode.OPCODES[codeArray.getU1(pc)] : null;
- }
-
- /**
- * Returns the opcode of the current instruction.
- * @return The opcode of the current instruction.
- */
- public JOpcode getOpcode() {
- return opcode;
- }
-
- /**
- * Updates the program counter to an given value.
- * @param pc The new value of the program counter.
- */
- public void moveTo(int pc) {
- this.pc = pc;
- setOpcode();
- }
-
- /**
- * Check the validity of the iterator.
- * @return true iff the iterator points to a valid address.
- */
- public boolean isValid() {
- return pc < codeArray.getSize();
- }
-
- /**
- * Updates the current instruction with the next one in the
- * sense of their position in the code.
- */
- public void moveToNext() {
- moveTo(pc + getInstructionSize());
- }
-
- /**
- * Updates the current instruction with a specific successor
- * of it.
- * @param succ The index of the wanted successor in the list of
- * the successors of the current instruction.
- */
- public void moveToSuccessor(int succ) {
- moveTo(getSuccessorPC(succ));
- }
-
- /**
- * Updates the current instruction with the one positionned
- * at a given index relatively to the actual program counter
- * @param offset The relative position of the instruction
- * compared with the position of the current one
- */
- public void moveRelatively(int offset) {
- moveTo(pc + offset);
- }
-
- /**
- * Returns the size in bytes of the current instruction.
- * @return The size in bytes of the current instruction.
- */
- public int getInstructionSize() {
- if (opcode.size != JOpcode.UNKNOWN) {
- return opcode.size;
- } else if (opcode == JOpcode.TABLESWITCH) {
- int lowOffset = 1 + pad4(pc + 1) + 4;
- int low = codeArray.getS4(pc + lowOffset);
- int high = codeArray.getS4(pc + lowOffset + 4);
- return lowOffset + 8 + 4 * (high - low + 1);
- } else if (opcode == JOpcode.LOOKUPSWITCH) {
- int npairsOffset = 1 + pad4(pc + 1) + 4;
- int npairs = codeArray.getS4(pc + npairsOffset);
- return npairsOffset + 4 + 8 * npairs;
- } else if (opcode == JOpcode.WIDE) {
- if (codeArray.getU1(pc + 1) == JOpcode.cIINC)
- return 6;
- else
- return 4;
- } else
- throw new Error("Unknown size for instruction " + opcode);
- }
-
- /**
- * Returns the number of successors of the current instruction.
- * @return The number of successors of the current instruction.
- */
- public int getSuccessorCount() {
- if (opcode.successorCount != JOpcode.UNKNOWN) {
- return opcode.successorCount;
- } else if (opcode == JOpcode.TABLESWITCH) {
- int lowPos = pc + 1 + pad4(pc + 1) + 4;
- return 1 // default case
- + codeArray.getS4(lowPos + 4) // value of HIGH field
- - codeArray.getS4(lowPos) + 1; // value of LOW field
- } else if (opcode == JOpcode.LOOKUPSWITCH) {
- int npairsPos = pc + 1 + pad4(pc + 1) + 4;
- return 1 + codeArray.getS4(npairsPos);
- } else
- throw new Error("Unknown successors for instruction " + opcode);
- }
-
- /**
- * Returns the address of the successor of the current instruction
- * given its index in the list of successors of the current
- * instruction.
- * @param index The index of the wanted successor in the list of
- * the successors of the current instruction.
- * @return The address of the specific successor.
- */
- public int getSuccessorPC(int index) {
- assert (index >= 0) && (index < getSuccessorCount()) : index;
-
- switch (opcode.jumpKind) {
- case JOpcode.JMP_NEXT:
- return pc + getInstructionSize();
- case JOpcode.JMP_ALWAYS_S2_OFFSET:
- return pc + codeArray.getS2(pc + 1);
- case JOpcode.JMP_ALWAYS_S4_OFFSET:
- return pc + codeArray.getS4(pc + 1);
- case JOpcode.JMP_MAYBE_S2_OFFSET:
- if (index == 0)
- return pc + getInstructionSize();
- else
- return pc + codeArray.getS2(pc + 1);
- case JOpcode.JMP_TABLE: {
- int defaultPos = pc + 1 + pad4(pc + 1);
- if (index == 0)
- return pc + codeArray.getS4(defaultPos);
- else
- return pc + codeArray.getS4(defaultPos + 3*4 + 4 * (index - 1));
- }
- case JOpcode.JMP_LOOKUP: {
- int defaultPos = pc + 1 + pad4(pc + 1);
- if (index == 0)
- return pc + codeArray.getS4(defaultPos);
- else
- return pc + codeArray.getS4(defaultPos + 2*4 + 4 + 8 * (index - 1));
- }
- default:
- throw new Error();
- }
- }
-
- /**
- * Returns the total size of data words put on the stack by the current
- * instruction.
- * @return The total size of data words put on the stack by the current
- * instruction.
- */
- public int getProducedDataSize() {
- if (opcode.getProducedDataTypes() == JOpcode.UNKNOWN_TYPE) {
- switch (opcode.code) {
- case JOpcode.cLDC: case JOpcode.cLDC_W: case JOpcode.cBALOAD:
- return 1;
- case JOpcode.cLDC2_W: case JOpcode.cDUP: case JOpcode.cSWAP:
- return 2;
- case JOpcode.cDUP_X1:
- return 3;
- case JOpcode.cDUP_X2: case JOpcode.cDUP2:
- return 4;
- case JOpcode.cDUP2_X1:
- return 5;
- case JOpcode.cDUP2_X2:
- return 6;
- case JOpcode.cGETSTATIC: case JOpcode.cGETFIELD: {
- JConstantPool.FieldOrMethodRefEntry entry =
- (JConstantPool.FieldOrMethodRefEntry)
- pool.lookupEntry(codeArray.getU2(pc + 1));
- return JType.parseSignature(entry.getSignature()).getSize();
- }
- case JOpcode.cWIDE : {
- int op = codeArray.getU1(pc + 1);
- if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD) {
- JOpcode opcode2 = JOpcode.OPCODES[op];
- return JType.getTotalSize(opcode2.getProducedDataTypes());
- } else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE)
- return 0;
- else return 0; // (IINC)
- }
- default :
- throw new Error(opcode.toString());
- }
- } else
- return JType.getTotalSize(opcode.getProducedDataTypes());
- }
-
- /**
- * Returns the total size of data words taken from the stack by the current
- * instruction.
- * @return The total size of data words taken from the stack by the current
- * instruction.
- */
- public int getConsumedDataSize() {
- if (opcode.getConsumedDataTypes() != JOpcode.UNKNOWN_TYPE)
- return JType.getTotalSize(opcode.getConsumedDataTypes());
- else {
- switch (opcode.code) {
- case JOpcode.cPOP: case JOpcode.cDUP:
- return 1;
- case JOpcode.cPOP2: case JOpcode.cSWAP:
- case JOpcode.cDUP_X1: case JOpcode.cDUP2:
- return 2;
- case JOpcode.cDUP_X2: case JOpcode.cDUP2_X1:
- return 3;
- case JOpcode.cDUP2_X2:
- return 4;
- case JOpcode.cPUTSTATIC: case JOpcode.cPUTFIELD: {
- JConstantPool.FieldOrMethodRefEntry entry =
- (JConstantPool.FieldOrMethodRefEntry)
- pool.lookupEntry(codeArray.getU2(pc + 1));
- return JType.parseSignature(entry.getSignature()).getSize();
- }
- case JOpcode.cINVOKEVIRTUAL: case JOpcode.cINVOKESPECIAL:
- case JOpcode.cINVOKESTATIC: case JOpcode.cINVOKEINTERFACE : {
- JConstantPool.FieldOrMethodRefEntry entry =
- (JConstantPool.FieldOrMethodRefEntry)
- pool.lookupEntry(codeArray.getU2(pc + 1));
- JMethodType tp = (JMethodType)
- JType.parseSignature(entry.getSignature());
- return tp.getArgsSize()
- + (opcode == JOpcode.INVOKESTATIC ? 0 : 1);
- }
- case JOpcode.cWIDE : {
- int op = codeArray.getU1(pc + 1);
- if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD)
- return 0;
- else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE) {
- JOpcode opcode2 = JOpcode.OPCODES[op];
- return JType.getTotalSize(opcode2.getConsumedDataTypes());
- } else
- return 0; // (IINC)
- }
- case JOpcode.cMULTIANEWARRAY :
- return codeArray.getU1(pc + 3);
- default:
- throw new Error(opcode.toString());
- }
- }
- }
-
- /**
- * Returns the number of data types put on the stack by the current
- * instruction.
- * @return The number of data types put on the stack by the current
- * instruction.
- */
- public int getProducedDataTypesNumber() {
- if (opcode.getProducedDataTypes() != JOpcode.UNKNOWN_TYPE)
- return opcode.getProducedDataTypes().length;
- else {
- switch (opcode.code) {
- case JOpcode.cLDC: case JOpcode.cLDC_W: case JOpcode.cLDC2_W:
- case JOpcode.cBALOAD: case JOpcode.cGETSTATIC:
- case JOpcode.cGETFIELD:
- return 1;
- case JOpcode.cDUP: case JOpcode.cSWAP:
- return 2;
- case JOpcode.cDUP_X1:
- return 3;
- case JOpcode.cWIDE: {
- int op = codeArray.getU1(pc + 1);
- if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD)
- return 1;
- else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE)
- return 0;
- else
- return 0; // (IINC)
- }
- default:
- throw new Error("JOpcode implementation error");
- }
- }
- }
-
- /**
- * Returns the number of data types taken from the stack by the current
- * instruction.
- * @return The number of data types taken from the stack by the current
- * instruction.
- */
-// public int getConsumedDataTypesNumber() {
-// if (opcode.getConsumedDataTypes() == JOpcode.UNKNOWN_TYPE) {
-// switch (opcode.code) {
-// case 87 : return 1; // POP
-// case 88 : return 2; // POP2
-// case 89 : return 1; // DUP
-// case 90 : return 2; // DUP_X1
-// case 91 : // DUP_X2
-// case 92 : // DUP2
-// case 93 : // DUP2_X1
-// case 94 : // DUP2_X2
-// throw new UnsupportedOperationException("Opcode " + opcode.name
-// + " has a stack-dependant"
-// + " data types consumption");
-// case 95 : return 2; // SWAP
-// case 179 : return 1; // PUTSTATIC
-// case 181 : return 1; // PUTFIELD
-// case 182 : // INVOKEVIRTUAL
-// case 183 : // INVOKESPECIAL
-// case 185 : // INVOKEINTERFACE
-// s = epool.getClassMethodRef(codeArray.getU2(pc + 1)).split(" ")[3];
-// return ((JMethodType)JType.parseSignature(s)).argTypes.length + 1;
-// case 184 : // INVOKESTATIC
-// s = epool.getClassMethodRef(codeArray.getU2(pc + 1)).split(" ")[3];
-// return ((JMethodType)JType.parseSignature(s)).argTypes.length;
-// case 196 : // WIDE
-// int op = codeArray.getU1(pc + 1);
-// if (op >= 21 && op <= 25) return 0; // (xLOAD)
-// else if (op >= 54 && op <= 58) // (xSTORE)
-// return JOpcode.OPCODES[op].getConsumedDataTypes().length;
-// else return 0; // (IINC)
-// case 197 : return codeArray.getU1(pc + 3); // MULTIANEWARRAY
-// default : throw new Error("JOpcode implementation error");
-// }
-// } else return opcode.getConsumedDataTypes().length;
-// }
-
-
- // Return the number between 0 and 3 which, if added to the given
- // value, would yield a multiple of 4.
- protected int[] padding = { 0, 3, 2, 1 };
- protected int pad4(int value) {
- return padding[value % 4];
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java b/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java
deleted file mode 100644
index 9867e01b25..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java
+++ /dev/null
@@ -1,771 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * Constant pool, holding constants for a Java class file.
- *
- * @author Michel Schinz
- * @version 2.0
- */
-
-public class JConstantPool {
- protected boolean frozen = false;
-
- protected HashMap/*<Entry,Integer>*/ entryToIndex = new HashMap();
- protected Entry[] indexToEntry;
- protected int currIndex;
-
- public static final short CONSTANT_Utf8 = 1;
- public static final short CONSTANT_Integer = 3;
- public static final short CONSTANT_Float = 4;
- public static final short CONSTANT_Long = 5;
- public static final short CONSTANT_Double = 6;
- public static final short CONSTANT_Class = 7;
- public static final short CONSTANT_String = 8;
- public static final short CONSTANT_Fieldref = 9;
- public static final short CONSTANT_Methodref = 10;
- public static final short CONSTANT_InterfaceMethodref = 11;
- public static final short CONSTANT_NameAndType = 12;
-
- protected JConstantPool(FJBGContext context) {
- indexToEntry = new Entry[8];
- currIndex = 1;
- }
-
- protected JConstantPool(FJBGContext context, DataInputStream stream)
- throws IOException {
- int count = stream.readShort();
- indexToEntry = new EntryIndex[count];
-
- currIndex = 1;
- while (currIndex < count) {
- EntryIndex e;
- int tag = stream.readByte();
-
- switch (tag) {
- case CONSTANT_Utf8:
- e = new Utf8Entry(stream);
- // no duplicates
- entryToIndex.put(e, new Integer(currIndex));
- break;
- case CONSTANT_Integer:
- e = new IntegerEntry(stream);
- break;
- case CONSTANT_Float:
- e = new FloatEntry(stream);
- break;
- case CONSTANT_Long:
- e = new LongEntry(stream);
- break;
- case CONSTANT_Double:
- e = new DoubleEntry(stream);
- break;
- case CONSTANT_Class:
- e = new DescriptorEntryIndex(stream);
- break;
- case CONSTANT_String:
- e = new StringEntryIndex(stream);
- break;
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- e = new FieldOrMethodRefEntryIndex(tag, stream);
- break;
- case CONSTANT_NameAndType:
- e = new NameAndTypeEntryIndex(stream);
- break;
- default:
- throw new IllegalArgumentException("unknown entry in pool: " + tag);
- }
- indexToEntry[currIndex] = e;
- currIndex += e.getSize();
- }
- }
-
- public void freeze() { frozen = true; }
-
- /**
- * Returns a string representing the type of an entry
- * knowing its tag
- * @param tag The tag representing the type of the
- * constant pool entry
- */
- public String getEntryType(int tag) {
- switch (tag) {
- case CONSTANT_Utf8 : return "Utf8";
- case CONSTANT_Integer : return "Integer";
- case CONSTANT_Float : return "Float";
- case CONSTANT_Long : return "Long";
- case CONSTANT_Double : return "Double";
- case CONSTANT_Class : return "Class";
- case CONSTANT_String : return "String";
- case CONSTANT_Fieldref : return "Field";
- case CONSTANT_Methodref : return "Method";
- case CONSTANT_InterfaceMethodref : return "InterfaceMethod";
- case CONSTANT_NameAndType : return "NameAndType";
- default : throw new Error("invalid constant pool tag : " + tag);
- }
- }
-
- public int addClass(String className) {
- return addDescriptor(className.replace('.', '/'));
- }
-
- public int addDescriptor(JReferenceType type) {
- return addDescriptor(type.getDescriptor());
- }
-
- protected int addDescriptor(String name) {
- return addEntry(new DescriptorEntryValue(name));
- }
-
- public int addClassMethodRef(String className,
- String methodName,
- String signature) {
- return addMethodRef(true, className, methodName, signature);
- }
-
- public int addInterfaceMethodRef(String className,
- String methodName,
- String signature) {
- return addMethodRef(false, className, methodName, signature);
- }
-
- public int addMethodRef(boolean isClass,
- String className,
- String methodName,
- String signature) {
- return addEntry(new FieldOrMethodRefEntryValue(isClass
- ? CONSTANT_Methodref
- : CONSTANT_InterfaceMethodref,
- className,
- methodName,
- signature));
- }
-
- public int addFieldRef(String className,
- String fieldName,
- String signature) {
- return addEntry(new FieldOrMethodRefEntryValue(CONSTANT_Fieldref,
- className,
- fieldName,
- signature));
- }
-
- public int addInteger(int value) {
- return addEntry(new IntegerEntry(value));
- }
-
- public int addFloat(float value) {
- return addEntry(new FloatEntry(value));
- }
-
- public int addLong(long value) {
- return addEntry(new LongEntry(value));
- }
-
- public int addDouble(double value) {
- return addEntry(new DoubleEntry(value));
- }
-
- public int addString(String value) {
- return addEntry(new StringEntryValue(value));
- }
-
- public int addNameAndType(String name, String descriptor) {
- return addEntry(new NameAndTypeEntryValue(name, descriptor));
- }
-
- public int addUtf8(String value) {
- return addEntry(new Utf8Entry(value));
- }
-
- public int addUtf8(byte[] value) {
- return addEntry(new Utf8Entry(value));
- }
-
- protected int addEntry(EntryValue e) {
- assert !frozen;
- Integer idx = (Integer)entryToIndex.get(e);
- if (idx != null)
- return idx.intValue();
-
- e.addChildren();
-
- int index = currIndex;
- currIndex += e.getSize();
-
- entryToIndex.put(e, new Integer(index));
- if (index >= indexToEntry.length) {
- Entry[] newI2E = new Entry[indexToEntry.length * 2];
- System.arraycopy(indexToEntry, 0, newI2E, 0, indexToEntry.length);
- indexToEntry = newI2E;
- }
- indexToEntry[index] = e;
- return index;
- }
-
- /// Lookup methods
- //////////////////////////////////////////////////////////////////////
-
- public Entry lookupEntry(int index) {
- assert index > 0 && index < currIndex
- : "invalid index: " + index;
- assert indexToEntry[index] != null
- : "invalid index (null contents): " + index;
- return indexToEntry[index];
- }
-
- public String lookupClass(int index) {
- DescriptorEntry entry = (DescriptorEntry)lookupEntry(index);
- return entry.getValue();
- }
-
- public String lookupNameAndType(int index) {
- NameAndTypeEntry entry = (NameAndTypeEntry)lookupEntry(index);
- return entry.getName()+":"+entry.getDescriptor();
- }
-
- public String lookupUtf8(int index) {
- Utf8Entry entry = (Utf8Entry)lookupEntry(index);
- return entry.getValue();
- }
-
- /// Output
- //////////////////////////////////////////////////////////////////////
-
- public void writeTo(DataOutputStream stream) throws IOException {
- if (! frozen) freeze();
-
- stream.writeShort(currIndex);
- for (int i = 0; i < currIndex; ++i) {
- Entry entry = indexToEntry[i];
- if (entry != null) {
- stream.writeByte(entry.getTag());
- entry.writeContentsTo(stream);
- }
- }
- }
-
- // Follows javap output format for constant pool.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" Constant pool:");
- for (int i = 0; i < currIndex; ++i) {
- Entry entry = indexToEntry[i];
- if (entry != null) {
- if (i > 0) buf.append("\n");
- buf.append("const #");
- buf.append(i);
- buf.append(" = ");
- buf.append(entry);
- }
- }
- buf.append("\n");
- return buf.toString();
- }
-
- /// Classes for the various kinds of entries
- //////////////////////////////////////////////////////////////////////
-
- public interface Entry {
- public int getTag();
-
- int getSize();
- void writeContentsTo(DataOutputStream stream) throws IOException;
- String toComment(String ownerClassName);
- }
-
- protected interface EntryValue extends Entry {
- abstract void addChildren();
- }
-
- protected interface EntryIndex extends Entry {
- abstract void fetchChildren();
- }
-
- abstract protected class ChildlessEntry implements EntryValue, EntryIndex {
- public void addChildren() {}
- public void fetchChildren() {}
- }
-
- public class IntegerEntry extends ChildlessEntry implements Entry {
- private final int value;
- public IntegerEntry(int value) { this.value = value; }
- public IntegerEntry(DataInputStream stream) throws IOException {
- this(stream.readInt());
- }
-
- public int hashCode() { return value; }
- public boolean equals(Object o) {
- return o instanceof IntegerEntry && ((IntegerEntry)o).value == value;
- }
-
- public int getTag() { return CONSTANT_Integer; }
- public int getValue() { return value; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeInt(value);
- }
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer("int\t");
- buf.append(getValue());
- buf.append(";");
- return buf.toString();
- }
- public String toComment(String ownerClassname) {
- return "//int "+getValue();
- }
- }
-
- public class FloatEntry extends ChildlessEntry implements Entry {
- private final float value;
- public FloatEntry(float value) { this.value = value; }
- public FloatEntry(DataInputStream stream) throws IOException {
- this(stream.readFloat());
- }
-
- public int hashCode() { return (int)value; }
- public boolean equals(Object o) {
- return o instanceof FloatEntry && ((FloatEntry)o).value == value;
- }
-
- public int getTag() { return CONSTANT_Float; }
- public float getValue() { return value; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeFloat(value);
- }
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer("float\t");
- buf.append(getValue());
- buf.append("f");
- return buf.toString();
- }
- public String toComment(String ownerClassname) {
- return "//float "+getValue()+"f";
- }
- }
-
- public class LongEntry extends ChildlessEntry implements Entry {
- private final long value;
- public LongEntry(long value) { this.value = value; }
- public LongEntry(DataInputStream stream) throws IOException {
- this(stream.readLong());
- }
-
- public int hashCode() { return (int)value; }
- public boolean equals(Object o) {
- return o instanceof LongEntry && ((LongEntry)o).value == value;
- }
-
- public int getTag() { return CONSTANT_Long; }
- public long getValue() { return value; }
-
- public int getSize() { return 2; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeLong(value);
- }
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer("long\t");
- buf.append(getValue());
- buf.append("l;");
- return buf.toString();
- }
- public String toComment(String ownerClassname) {
- return "//long "+getValue()+"l";
- }
- }
-
- public class DoubleEntry extends ChildlessEntry implements Entry {
- private final double value;
- public DoubleEntry(double value) { this.value = value; }
- public DoubleEntry(DataInputStream stream) throws IOException {
- this(stream.readDouble());
- }
-
- public int hashCode() { return (int)value; }
- public boolean equals(Object o) {
- return o instanceof DoubleEntry && ((DoubleEntry)o).value == value;
- }
-
- public int getTag() { return CONSTANT_Double; }
- public double getValue() { return value; }
-
- public int getSize() { return 2; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeDouble(value);
- }
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer("double\t");
- buf.append(getValue());
- return buf.toString();
- }
- public String toComment(String ownerClassname) {
- return "//double "+getValue();
- }
- }
-
- public class Utf8Entry extends ChildlessEntry implements Entry {
- private final String value;
- private final byte[] bytes;
- public Utf8Entry(String value) {
- this.value = value.intern();
- this.bytes = null;
- }
- public Utf8Entry(DataInputStream stream) throws IOException {
- this(stream.readUTF());
- }
- public Utf8Entry(byte[] bytes) {
- this.bytes = bytes;
- this.value = null;
- }
-
- public int hashCode() {
- if (bytes != null) return bytes.hashCode();
- return value.hashCode();
- }
- public boolean equals(Object o) {
- boolean isEqual = o instanceof Utf8Entry;
- if (bytes != null) {
- isEqual = isEqual && ((Utf8Entry)o).bytes == bytes;
- }
- else {
- isEqual = isEqual && ((Utf8Entry)o).value == value;
- }
- return isEqual;
- }
-
- public int getTag() { return CONSTANT_Utf8; }
- public String getValue() { return value; }
- public byte[] getBytes() { return bytes; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- if (bytes != null) {
- if (bytes.length > 65535) {
- throw new IOException("String literal of length " + bytes.length + " does not fit in Classfile");
- }
- stream.writeShort(bytes.length);
- stream.write(bytes);
- }
- else
- stream.writeUTF(value);
- }
- // Follows javap output format for Utf8 pool entries.
- public String toString() { return "Asciz\t"+escaped(getValue())+";"; }
- public String toComment(String ownerClassname) {
- return "//Asciz "+escaped(getValue());
- }
- private String escaped(String s) {
- return s.replace("\n", "\\n");
- }
- }
-
- abstract public class StringEntry implements Entry {
- protected String value;
- protected int valueIndex;
-
- public int hashCode() {
- assert value != null;
- return value.hashCode();
- }
- public boolean equals(Object o) {
- return o instanceof StringEntry && ((StringEntry)o).value == value;
- }
-
- public int getTag() { return CONSTANT_String; }
- public String getValue() { return value; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(valueIndex);
- }
- // Follows javap output format for String pool entries.
- public String toString() {
- return "String\t#"+valueIndex+";\t// "+escaped(getValue());
- }
- public String toComment(String ownerClassname) {
- return "//String "+escaped(getValue());
- }
- private String escaped(String s) {
- return s.replace("\n", "\\n");
- }
- }
-
- public class StringEntryValue extends StringEntry implements EntryValue {
- public StringEntryValue(String value) {
- this.value = value.intern();
- }
- public void addChildren() {
- valueIndex = addUtf8(value);
- }
- }
-
- public class StringEntryIndex extends StringEntry implements EntryIndex {
- public StringEntryIndex(int valueIndex) {
- this.valueIndex = valueIndex;
- }
- public StringEntryIndex(DataInputStream stream) throws IOException {
- this(stream.readShort());
- }
- public String getValue() {
- if (value == null) fetchChildren();
- return super.getValue();
- }
- public void fetchChildren() {
- value = lookupUtf8(valueIndex);
- }
- }
-
- abstract public class DescriptorEntry implements Entry {
- protected String name;
- protected int nameIndex;
-
- public int hashCode() {
- assert name != null;
- return name.hashCode();
- }
- public boolean equals(Object o) {
- return o instanceof DescriptorEntry && ((DescriptorEntry)o).name == name;
- }
-
- public int getTag() { return CONSTANT_Class; }
- public String getValue() { return name; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(nameIndex);
- }
- // Follows javap output format for class pool entries.
- public String toString() {
- StringBuffer buf = new StringBuffer("class\t#");
- buf.append(nameIndex);
- buf.append(";\t// ");
- buf.append(getClassName());
- return buf.toString();
- }
- public String toComment(String ownerClassname) {
- return "//class "+getClassName();
- }
- private String getClassName() {
- StringBuffer buf = new StringBuffer();
- String value = getValue();
- if (value.startsWith("[")) buf.append("\"");
- buf.append(value);
- if (value.startsWith("[")) buf.append("\"");
- return buf.toString();
- }
- }
-
- protected class DescriptorEntryValue
- extends DescriptorEntry
- implements EntryValue {
- public DescriptorEntryValue(String name) { this.name = name.intern(); }
- public void addChildren() {
- nameIndex = addUtf8(name);
- }
- }
-
- protected class DescriptorEntryIndex
- extends DescriptorEntry
- implements EntryIndex {
- public DescriptorEntryIndex(int nameIndex) { this.nameIndex = nameIndex; }
- public DescriptorEntryIndex(DataInputStream stream) throws IOException {
- this(stream.readShort());
- }
- public String getValue() {
- if (name == null) fetchChildren();
- return super.getValue();
- }
- public void fetchChildren() {
- name = lookupUtf8(nameIndex);
- }
- }
-
- abstract public class FieldOrMethodRefEntry implements Entry {
- private final int tag;
- protected String className, thingName, signature;
- protected int classIndex, nameAndTypeIndex;
-
- public FieldOrMethodRefEntry(int tag) {
- assert tag == CONSTANT_Fieldref
- || tag == CONSTANT_Methodref
- || tag == CONSTANT_InterfaceMethodref;
-
- this.tag = tag;
- }
-
- public int hashCode() {
- return tag
- + className.hashCode()
- + thingName.hashCode()
- + signature.hashCode();
- }
- public boolean equals(Object o) {
- return o instanceof FieldOrMethodRefEntry
- && ((FieldOrMethodRefEntry)o).tag == tag
- && ((FieldOrMethodRefEntry)o).className == className
- && ((FieldOrMethodRefEntry)o).thingName == thingName
- && ((FieldOrMethodRefEntry)o).signature == signature;
- }
-
- public int getTag() { return tag; }
- public String getClassName() { return className; }
- public String getFieldOrMethodName() { return thingName; }
- public String getSignature() { return signature; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(classIndex);
- stream.writeShort(nameAndTypeIndex);
- }
- // Follows javap output format for field/method pool entries.
- public String toString() {
- return getEntryType(tag)+"\t#"+classIndex+".#"+nameAndTypeIndex+
- ";\t// "+getName("")+":"+signature;
- }
- public String toComment(String ownerClassName) {
- return "//"+getEntryType(tag)+" "+getName(ownerClassName)+":"+signature;
- }
- private String getName(String ownerClassName) {
- String name = getFieldOrMethodName();
- if (JMethod.INSTANCE_CONSTRUCTOR_NAME.equals(name))
- name = "\""+name+"\"";
- if (!getClassName().equals(ownerClassName))
- name = getClassName()+"."+name;
- return name;
- }
- }
-
- protected class FieldOrMethodRefEntryValue
- extends FieldOrMethodRefEntry
- implements EntryValue {
- public FieldOrMethodRefEntryValue(int tag,
- String className,
- String thingName,
- String signature) {
- super(tag);
- this.className = className.intern();
- this.thingName = thingName.intern();
- this.signature = signature.intern();
- }
-
- public void addChildren() {
- classIndex = addClass(className);
- nameAndTypeIndex = addNameAndType(thingName, signature);
- }
- }
-
- protected class FieldOrMethodRefEntryIndex
- extends FieldOrMethodRefEntry
- implements EntryIndex {
- public FieldOrMethodRefEntryIndex(int tag,
- int classIndex,
- int nameAndTypeIndex) {
- super(tag);
- this.classIndex = classIndex;
- this.nameAndTypeIndex = nameAndTypeIndex;
- }
- public FieldOrMethodRefEntryIndex(int tag, DataInputStream stream)
- throws IOException {
- this(tag, stream.readShort(), stream.readShort());
- }
- public String getClassName() {
- if (className == null) fetchChildren();
- return super.getClassName();
- }
- public String getFieldOrMethodName() {
- if (thingName == null) fetchChildren();
- return super.getFieldOrMethodName();
- }
- public String getSignature() {
- if (signature == null) fetchChildren();
- return super.getSignature();
- }
- public void fetchChildren() {
- className = lookupClass(classIndex);
- NameAndTypeEntry nat = (NameAndTypeEntry)lookupEntry(nameAndTypeIndex);
- thingName = nat.getName();
- signature = nat.getDescriptor();
- }
- }
-
- abstract public class NameAndTypeEntry implements Entry {
- protected String name, descriptor;
- protected int nameIndex, descriptorIndex;
-
- public int hashCode() { return name.hashCode() + descriptor.hashCode(); }
- public boolean equals(Object o) {
- return o instanceof NameAndTypeEntry
- && ((NameAndTypeEntry)o).name == name
- && ((NameAndTypeEntry)o).descriptor == descriptor;
- }
-
- public int getTag() { return CONSTANT_NameAndType; }
- public String getName() { return name; }
- public String getDescriptor() { return descriptor; }
-
- public int getSize() { return 1; }
- public void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(nameIndex);
- stream.writeShort(descriptorIndex);
- }
- // Follows javap output format for name/type pool entries.
- public String toString() {
- String natName = getName();
- if (JMethod.INSTANCE_CONSTRUCTOR_NAME.equals(natName))
- natName = "\""+natName+"\"";
- return "NameAndType\t#"+nameIndex+":#"+descriptorIndex+
- ";// "+natName+":"+getDescriptor();
- }
- public String toComment(String ownerClassname) { return ""; }
- }
-
- protected class NameAndTypeEntryValue
- extends NameAndTypeEntry
- implements EntryValue {
- public NameAndTypeEntryValue(String name, String descriptor) {
- this.name = name.intern();
- this.descriptor = descriptor.intern();
- }
- public void addChildren() {
- nameIndex = addUtf8(name);
- descriptorIndex = addUtf8(descriptor);
- }
- }
-
- protected class NameAndTypeEntryIndex
- extends NameAndTypeEntry
- implements EntryIndex {
- public NameAndTypeEntryIndex(int nameIndex, int descriptorIndex) {
- this.nameIndex = nameIndex;
- this.descriptorIndex = descriptorIndex;
- }
- public NameAndTypeEntryIndex(DataInputStream stream) throws IOException {
- this(stream.readShort(), stream.readShort());
- }
- public String getName() {
- if (name == null) fetchChildren();
- return super.getName();
- }
- public String getDescriptor() {
- if (descriptor == null) fetchChildren();
- return super.getDescriptor();
- }
- public void fetchChildren() {
- name = lookupUtf8(nameIndex);
- descriptor = lookupUtf8(descriptorIndex);
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java
deleted file mode 100644
index 6ee05e43c7..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * ConstantValue attribute representing the value of a constant field.
- *
- * There can be no more than one ConstantValue attribute in the attributes
- * table of a given field_info structure.. See section 4.8.2 of the JVM
- * specification.
- *
- * @author Stephane Micheloud
- * @version 1.0
- */
-
-public class JConstantValueAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- protected int constantValueIndex;
-
- public JConstantValueAttribute(FJBGContext context,
- JClass clazz,
- JField field) {
- super(context, clazz);
- this.pool = clazz.pool;
-
- assert field.getOwner() == clazz;
- }
-
- public JConstantValueAttribute(FJBGContext context,
- JClass clazz,
- Object owner, // JField
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- this.constantValueIndex = stream.readShort();
-
- assert name.equals(getName());
- }
-
- public String getName() { return "ConstantValue"; }
-
- // Follows javap output format for ConstantValue attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" Constant value: ");
- buf.append(pool.lookupEntry(constantValueIndex));
- return buf.toString();
- }
-
- protected int getSize() {
- return 2; // Short.SIZE
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(constantValueIndex);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java
deleted file mode 100644
index f663f00ae1..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * EclosingMethod attribute
-
- * A class must have an EnclosingMethod attribute if and only if it is a
- * local class or an anonymous class. A class may have no more than one
- * EnclosingMethod attribute. See section 4.8.6 of the JVM specification.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JEnclosingMethodAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- protected final int classIdx;
- protected final int nameAndTypeIdx;
-
- public JEnclosingMethodAttribute(FJBGContext context,
- JClass clazz,
- String className,
- String methodName,
- JType methodType) {
- super(context, clazz);
- this.pool = clazz.pool;
-
- this.classIdx = pool.addClass(className);
- this.nameAndTypeIdx = pool.addNameAndType(methodName, methodType.getSignature());
- }
-
- public JEnclosingMethodAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- this.classIdx = stream.readShort();
- this.nameAndTypeIdx = stream.readShort();
-
- assert name.equals(getName());
- }
-
- public String getName() { return "EnclosingMethod"; }
-
- // Follows javap output format for EnclosingMethod attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" EnclosingMethod:");
- buf.append("\n #");
- buf.append(classIdx);
- if (nameAndTypeIdx != 0) {
- buf.append(" of #");
- buf.append(nameAndTypeIdx);
- }
- buf.append(";\t// ");
- buf.append(pool.lookupEntry(classIdx));
- buf.append("\n");
- return buf.toString();
- }
-
- protected int getSize() {
- return 4; // 2 * Short.SIZE
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(classIdx);
- stream.writeShort(nameAndTypeIdx);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java
deleted file mode 100644
index b91d0f2e93..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Exceptions attribute
-
- * This table is used by compilers to indicate which Exceptions a method
- * is declared to throw. See section 2.6.4 of the JVM specification.
- *
- * @author Stephane Micheloud
- * @version 1.0
- */
-
-public class JExceptionsAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- protected int[] indexTable;
- protected int count;
-
- public JExceptionsAttribute(FJBGContext context,
- JClass clazz,
- JMethod owner) {
- super(context, clazz);
- this.pool = clazz.pool;
-
- this.count = 0;
- this.indexTable = new int[8]; // some size > count
-
- assert clazz == owner.getOwner();
- }
-
- public JExceptionsAttribute(FJBGContext context,
- JClass clazz,
- Object owner, //JMethod
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- this.count = stream.readShort();
- this.indexTable = new int[count];
- for (int i = 0; i < count; ++i)
- indexTable[i] = stream.readShort();
-
- assert name.equals(getName());
- }
-
- public void addEntry(int classIndex) {
- if (count >= indexTable.length) {
- int[] newIT = new int[indexTable.length * 2];
- System.arraycopy(indexTable, 0, newIT, 0, indexTable.length);
- indexTable = newIT;
- }
- indexTable[count++] = classIndex;
- }
-
- public String getName() { return "Exceptions"; }
-
- // Follows javap output format for Exceptions attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" Exceptions: ");
- for (int i = 0; i < indexTable.length; ++i) {
- buf.append("\n throws ");
- buf.append(JClass.toExternalName(pool.lookupClass(indexTable[i])));
- }
- buf.append("\n");
- return buf.toString();
- }
-
- protected int getSize() {
- return 2 + indexTable.length * 2;
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(count);
- for (int i = 0; i < count; ++i)
- stream.writeShort(indexTable[i]);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java
deleted file mode 100644
index d82db8289f..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Extended list of instructions, providing pseudo-instructions which
- * are easier to use than the standard ones.
- *
- * @author Michel Schinz, Thomas Friedli
- * @version 1.0
- */
-
-public class JExtendedCode extends JCode {
- public final static int COND_EQ = 0;
- public final static int COND_NE = 1;
- public final static int COND_LT = 2;
- public final static int COND_GE = 3;
- public final static int COND_GT = 4;
- public final static int COND_LE = 5;
-
- private final JOpcode[] forbidden = new JOpcode[0];
- private final JOpcode[] nothingToDo = new JOpcode[0];
-
- private final JOpcode[][][] typeConversions = {
- {
- /* T_BOOLEAN -> T_BOOLEAN */ nothingToDo,
- /* T_BOOLEAN -> T_CHAR */ forbidden,
- /* T_BOOLEAN -> T_FLOAT */ forbidden,
- /* T_BOOLEAN -> T_DOUBLE */ forbidden,
- /* T_BOOLEAN -> T_BYTE */ forbidden,
- /* T_BOOLEAN -> T_SHORT */ forbidden,
- /* T_BOOLEAN -> T_INT */ forbidden,
- /* T_BOOLEAN -> T_LONG */ forbidden
- },
- {
- /* T_CHAR -> T_BOOLEAN */ forbidden,
- /* T_CHAR -> T_CHAR */ nothingToDo,
- /* T_CHAR -> T_FLOAT */ {JOpcode.I2F},
- /* T_CHAR -> T_DOUBLE */ {JOpcode.I2D},
- /* T_CHAR -> T_BYTE */ {JOpcode.I2B},
- /* T_CHAR -> T_SHORT */ {JOpcode.I2S},
- /* T_CHAR -> T_INT */ nothingToDo,
- /* T_CHAR -> T_LONG */ {JOpcode.I2L}
- },
- {
- /* T_FLOAT -> T_BOOLEAN */ forbidden,
- /* T_FLOAT -> T_CHAR */ {JOpcode.F2I, JOpcode.I2C},
- /* T_FLOAT -> T_FLOAT */ nothingToDo,
- /* T_FLOAT -> T_DOUBLE */ {JOpcode.F2D},
- /* T_FLOAT -> T_BYTE */ {JOpcode.F2I, JOpcode.I2B},
- /* T_FLOAT -> T_SHORT */ {JOpcode.F2I, JOpcode.I2S},
- /* T_FLOAT -> T_INT */ {JOpcode.F2I},
- /* T_FLOAT -> T_LONG */ {JOpcode.F2L}
- },
- {
- /* T_DOUBLE -> T_BOOLEAN */ forbidden,
- /* T_DOUBLE -> T_CHAR */ {JOpcode.D2I, JOpcode.I2C},
- /* T_DOUBLE -> T_FLOAT */ {JOpcode.D2F},
- /* T_DOUBLE -> T_DOUBLE */ nothingToDo,
- /* T_DOUBLE -> T_BYTE */ {JOpcode.D2I, JOpcode.I2B},
- /* T_DOUBLE -> T_SHORT */ {JOpcode.D2I, JOpcode.I2S},
- /* T_DOUBLE -> T_INT */ {JOpcode.D2I},
- /* T_DOUBLE -> T_LONG */ {JOpcode.D2L}
- },
- {
- /* T_BYTE -> T_BOOLEAN */ forbidden,
- /* T_BYTE -> T_CHAR */ {JOpcode.I2C},
- /* T_BYTE -> T_FLOAT */ {JOpcode.I2F},
- /* T_BYTE -> T_DOUBLE */ {JOpcode.I2D},
- /* T_BYTE -> T_BYTE */ nothingToDo,
- /* T_BYTE -> T_SHORT */ nothingToDo,
- /* T_BYTE -> T_INT */ nothingToDo,
- /* T_BYTE -> T_LONG */ {JOpcode.I2L}
- },
- {
- /* T_SHORT -> T_BOOLEAN */ forbidden,
- /* T_SHORT -> T_CHAR */ {JOpcode.I2C},
- /* T_SHORT -> T_FLOAT */ {JOpcode.I2F},
- /* T_SHORT -> T_DOUBLE */ {JOpcode.I2D},
- /* T_SHORT -> T_BYTE */ {JOpcode.I2B},
- /* T_SHORT -> T_SHORT */ nothingToDo,
- /* T_SHORT -> T_INT */ nothingToDo,
- /* T_SHORT -> T_LONG */ {JOpcode.I2L}
- },
- {
- /* T_INT -> T_BOOLEAN */ forbidden,
- /* T_INT -> T_CHAR */ {JOpcode.I2C},
- /* T_INT -> T_FLOAT */ {JOpcode.I2F},
- /* T_INT -> T_DOUBLE */ {JOpcode.I2D},
- /* T_INT -> T_BYTE */ {JOpcode.I2B},
- /* T_INT -> T_SHORT */ {JOpcode.I2S},
- /* T_INT -> T_INT */ nothingToDo,
- /* T_INT -> T_LONG */ {JOpcode.I2L}
- },
- {
- /* T_LONG -> T_BOOLEAN */ forbidden,
- /* T_LONG -> T_CHAR */ {JOpcode.L2I, JOpcode.I2C},
- /* T_LONG -> T_FLOAT */ {JOpcode.L2F},
- /* T_LONG -> T_DOUBLE */ {JOpcode.L2D},
- /* T_LONG -> T_BYTE */ {JOpcode.L2I, JOpcode.I2B},
- /* T_LONG -> T_SHORT */ {JOpcode.L2I, JOpcode.I2S},
- /* T_LONG -> T_INT */ {JOpcode.L2I},
- /* T_LONG -> T_LONG */ nothingToDo
- }
- };
-
- public JExtendedCode(FJBGContext context,
- JClass clazz,
- JMethod owner) {
- super(context, clazz, owner);
- }
-
- public void emitPUSH(boolean value) { emitPUSH(value ? 1 : 0); }
- public void emitPUSH(Boolean value) { emitPUSH(value.booleanValue()); }
-
- public void emitPUSH(byte value) {
- switch (value) {
- case -1: emitICONST_M1(); break;
- case 0: emitICONST_0(); break;
- case 1: emitICONST_1(); break;
- case 2: emitICONST_2(); break;
- case 3: emitICONST_3(); break;
- case 4: emitICONST_4(); break;
- case 5: emitICONST_5(); break;
- default:
- emitBIPUSH(value);
- }
- }
- public void emitPUSH(Byte value) { emitPUSH(value.byteValue()); }
-
- public void emitPUSH(short value) {
- switch (value) {
- case -1: emitICONST_M1(); break;
- case 0: emitICONST_0(); break;
- case 1: emitICONST_1(); break;
- case 2: emitICONST_2(); break;
- case 3: emitICONST_3(); break;
- case 4: emitICONST_4(); break;
- case 5: emitICONST_5(); break;
- default:
- if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
- emitBIPUSH((byte)value);
- else
- emitSIPUSH(value);
- }
- }
- public void emitPUSH(Short value) { emitPUSH(value.shortValue()); }
-
- // TODO check that we do the right thing here
- public void emitPUSH(char value) { emitPUSH((int)value); }
- public void emitPUSH(Character value) { emitPUSH(value.charValue()); }
-
- public void emitPUSH(int value) {
- switch (value) {
- case -1: emitICONST_M1(); break;
- case 0: emitICONST_0(); break;
- case 1: emitICONST_1(); break;
- case 2: emitICONST_2(); break;
- case 3: emitICONST_3(); break;
- case 4: emitICONST_4(); break;
- case 5: emitICONST_5(); break;
- default:
- if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
- emitBIPUSH((byte)value);
- else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
- emitSIPUSH((short)value);
- else
- emitPUSH_index(pool.addInteger(value));
- break;
- }
- }
- public void emitPUSH(Integer value) { emitPUSH(value.intValue()); }
-
- public void emitPUSH(long value) {
- if (value == 0L)
- emitLCONST_0();
- else if (value == 1L)
- emitLCONST_1();
- else
- emitLDC2_W(value);
- }
- public void emitPUSH(Long value) { emitPUSH(value.longValue()); }
-
- private static final Float ZEROF = Float.valueOf(0f);
- private static final Float ONEF = Float.valueOf(1f);
- private static final Float TWOF = Float.valueOf(2f);
- public void emitPUSH(Float value) {
- if (ZEROF.equals(value))
- emitFCONST_0();
- else if (ONEF.equals(value))
- emitFCONST_1();
- else if (TWOF.equals(value))
- emitFCONST_2();
- else
- emitPUSH_index(pool.addFloat(value.floatValue()));
- }
- public void emitPUSH(float value) { emitPUSH(Float.valueOf(value)); }
-
- private static final Double ZEROD = Double.valueOf(0d);
- private static final Double ONED = Double.valueOf(1d);
- public void emitPUSH(Double value) {
- if (ZEROD.equals(value))
- emitDCONST_0();
- else if (ONED.equals(value))
- emitDCONST_1();
- else
- emitLDC2_W(value.doubleValue());
- }
- public void emitPUSH(double value) { emitPUSH(Double.valueOf(value)); }
-
- public void emitPUSH(String s) {
- emitPUSH_index(pool.addString(s));
- }
-
- /** Pushes a class literal on the stack */
- public void emitPUSH(JReferenceType type) {
- assert owner.owner.major >= 49;
- emitPUSH_index(pool.addClass(type.getDescriptor()));
- }
-
- protected void emitPUSH_index(int index) {
- if (index <= 0xFF)
- emitU1(JOpcode.LDC, index);
- else
- emitU2(JOpcode.LDC_W, index);
- }
-
- public void emitLOAD(int index, JType type) {
- JOpcode opcode;
-
- switch (type.getTag()) {
- case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR:
- case JType.T_SHORT: case JType.T_INT:
- switch (index) {
- case 0: emitILOAD_0(); return;
- case 1: emitILOAD_1(); return;
- case 2: emitILOAD_2(); return;
- case 3: emitILOAD_3(); return;
- default: opcode = JOpcode.ILOAD;
- } break;
- case JType.T_FLOAT:
- switch (index) {
- case 0: emitFLOAD_0(); return;
- case 1: emitFLOAD_1(); return;
- case 2: emitFLOAD_2(); return;
- case 3: emitFLOAD_3(); return;
- default: opcode = JOpcode.FLOAD;
- } break;
- case JType.T_LONG:
- switch (index) {
- case 0: emitLLOAD_0(); return;
- case 1: emitLLOAD_1(); return;
- case 2: emitLLOAD_2(); return;
- case 3: emitLLOAD_3(); return;
- default: opcode = JOpcode.LLOAD;
- } break;
- case JType.T_DOUBLE:
- switch (index) {
- case 0: emitDLOAD_0(); return;
- case 1: emitDLOAD_1(); return;
- case 2: emitDLOAD_2(); return;
- case 3: emitDLOAD_3(); return;
- default: opcode = JOpcode.DLOAD;
- } break;
- case JType.T_ARRAY: case JType.T_OBJECT:
- switch (index) {
- case 0: emitALOAD_0(); return;
- case 1: emitALOAD_1(); return;
- case 2: emitALOAD_2(); return;
- case 3: emitALOAD_3(); return;
- default: opcode = JOpcode.ALOAD;
- } break;
- default:
- throw new IllegalArgumentException("invalid type for load "+type);
- }
-
- if (index > 0xFF)
- emitWIDE(opcode, index);
- else
- emitU1(opcode, index);
- }
- public void emitLOAD(JLocalVariable var) {
- emitLOAD(var.index, var.type);
- }
-
- public void emitSTORE(int index, JType type) {
- JOpcode opcode;
-
- switch (type.getTag()) {
- case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR:
- case JType.T_SHORT: case JType.T_INT:
- switch (index) {
- case 0: emitISTORE_0(); return;
- case 1: emitISTORE_1(); return;
- case 2: emitISTORE_2(); return;
- case 3: emitISTORE_3(); return;
- default: opcode = JOpcode.ISTORE;
- } break;
- case JType.T_FLOAT:
- switch (index) {
- case 0: emitFSTORE_0(); return;
- case 1: emitFSTORE_1(); return;
- case 2: emitFSTORE_2(); return;
- case 3: emitFSTORE_3(); return;
- default: opcode = JOpcode.FSTORE;
- } break;
- case JType.T_LONG:
- switch (index) {
- case 0: emitLSTORE_0(); return;
- case 1: emitLSTORE_1(); return;
- case 2: emitLSTORE_2(); return;
- case 3: emitLSTORE_3(); return;
- default: opcode = JOpcode.LSTORE;
- } break;
- case JType.T_DOUBLE:
- switch (index) {
- case 0: emitDSTORE_0(); return;
- case 1: emitDSTORE_1(); return;
- case 2: emitDSTORE_2(); return;
- case 3: emitDSTORE_3(); return;
- default: opcode = JOpcode.DSTORE;
- } break;
- case JType.T_ARRAY: case JType.T_OBJECT: case JType.T_ADDRESS:
- switch (index) {
- case 0: emitASTORE_0(); return;
- case 1: emitASTORE_1(); return;
- case 2: emitASTORE_2(); return;
- case 3: emitASTORE_3(); return;
- default: opcode = JOpcode.ASTORE;
- } break;
- default:
- throw new IllegalArgumentException("invalid type for store "+type);
- }
-
- if (index > 0xFF)
- emitWIDE(opcode, index);
- else
- emitU1(opcode, index);
- }
- public void emitSTORE(JLocalVariable var) {
- emitSTORE(var.index, var.type);
- }
-
- public void emitALOAD(JType type) {
- switch (type.getTag()) {
- case JType.T_BOOLEAN:
- case JType.T_BYTE:
- emitBALOAD();
- break;
- case JType.T_CHAR:
- emitCALOAD();
- break;
- case JType.T_SHORT:
- emitSALOAD();
- break;
- case JType.T_INT:
- emitIALOAD();
- break;
- case JType.T_FLOAT:
- emitFALOAD();
- break;
- case JType.T_LONG:
- emitLALOAD();
- break;
- case JType.T_DOUBLE:
- emitDALOAD();
- break;
- case JType.T_ARRAY:
- case JType.T_OBJECT:
- emitAALOAD();
- break;
- default:
- throw new IllegalArgumentException("invalid type for aload " + type);
- }
- }
-
- public void emitASTORE(JType type) {
- switch (type.getTag()) {
- case JType.T_BOOLEAN:
- case JType.T_BYTE:
- emitBASTORE();
- break;
- case JType.T_CHAR:
- emitCASTORE();
- break;
- case JType.T_SHORT:
- emitSASTORE();
- break;
- case JType.T_INT:
- emitIASTORE();
- break;
- case JType.T_FLOAT:
- emitFASTORE();
- break;
- case JType.T_LONG:
- emitLASTORE();
- break;
- case JType.T_DOUBLE:
- emitDASTORE();
- break;
- case JType.T_ARRAY:
- case JType.T_OBJECT:
- emitAASTORE();
- break;
- default:
- throw new IllegalArgumentException("invalid type for astore " + type);
- }
- }
-
- public void emitRETURN(JType type) {
- if (type.isValueType()) {
- switch (type.getTag()) {
- case JType.T_BOOLEAN:
- case JType.T_BYTE:
- case JType.T_CHAR:
- case JType.T_SHORT:
- case JType.T_INT:
- emitIRETURN();
- break;
- case JType.T_FLOAT:
- emitFRETURN();
- break;
- case JType.T_LONG:
- emitLRETURN();
- break;
- case JType.T_DOUBLE:
- emitDRETURN();
- break;
- }
- } else if (type.isArrayType() || type.isObjectType())
- emitARETURN();
- else if (type == JType.VOID)
- emitRETURN();
- else
- throw new IllegalArgumentException("invalid type for RETURN " + type);
- }
-
- public void emitADD(JType type) {
- switch (type.getTag()) {
- case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR:
- case JType.T_SHORT: case JType.T_INT:
- emitIADD(); break;
- case JType.T_FLOAT:
- emitFADD(); break;
- case JType.T_LONG:
- emitLADD(); break;
- case JType.T_DOUBLE:
- emitDADD(); break;
- }
- }
-
- /**
- * Emits a basic type conversion instruction choosen according to the
- * types given in parameter.
- *
- * @param fromType The type of the value to be cast into another type.
- * @param toType The type the value will be cast into.
- */
- public void emitT2T(JType fromType, JType toType) {
- assert fromType.getTag() >= JType.T_BOOLEAN
- && fromType.getTag() <= JType.T_LONG
- && toType.getTag() >= JType.T_BOOLEAN
- && toType.getTag() <= JType.T_LONG;
-
- JOpcode[] conv = typeConversions[fromType.getTag() - 4][toType.getTag() - 4];
- if (conv == forbidden) {
- throw new Error("inconvertible types : " + fromType.toString()
- + " -> " + toType.toString());
- } else if (conv != nothingToDo) {
- for (int i = 0; i < conv.length; i++) {
- emit(conv[i]);
- }
- }
- }
-
- public void emitIF(int cond, Label label) throws OffsetTooBigException {
- assert cond >= COND_EQ && cond <= COND_LE;
- emitU2(JOpcode.OPCODES[153 + cond], label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitIF(int cond, int targetPC) throws OffsetTooBigException {
- int offset = targetPC - getPC();
- emitU2(JOpcode.OPCODES[153 + cond], offset);
- }
- public void emitIF(int cond) throws OffsetTooBigException {
- emitIF(cond, 0);
- }
-
- public void emitIF_ICMP(int cond, Label label) throws OffsetTooBigException {
- assert cond >= COND_EQ && cond <= COND_LE;
- emitU2(JOpcode.OPCODES[159 + cond], label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitIF_ICMP(int cond, int targetPC) throws OffsetTooBigException {
- int offset = targetPC - getPC();
- emitU2(JOpcode.OPCODES[159 + cond], offset);
- }
- public void emitIF_ICMP(int cond) throws OffsetTooBigException {
- emitIF_ICMP(cond, 0);
- }
-
- public void emitIF_ACMP(int cond, Label label) throws OffsetTooBigException {
- assert cond == COND_EQ || cond == COND_NE;
- emitU2(JOpcode.OPCODES[165 + cond], label.getOffset16(getPC() + 1, getPC()));
- }
- public void emitIF_ACMP(int cond, int targetPC) throws OffsetTooBigException {
- int offset = targetPC - getPC();
- emitU2(JOpcode.OPCODES[165 + cond], offset);
- }
- public void emitIF_ACMP(int cond) throws OffsetTooBigException {
- emitIF_ACMP(cond, 0);
- }
-
- public void emitGOTO_maybe_W(Label label, boolean defaultToWide) {
- if (label.anchored)
- emitGOTO_maybe_W(label.targetPC);
- else {
- if (defaultToWide)
- emitGOTO_W(label);
- else {
- try {
- emitGOTO(label);
- } catch (OffsetTooBigException e) {
- throw new Error(e);
- }
- }
- }
- }
-
- public void emitGOTO_maybe_W(int targetPC) {
- int offset = targetPC - (getPC() + 1);
- if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE)
- emitGOTO_W(targetPC);
- else {
- try {
- emitGOTO(targetPC);
- } catch (OffsetTooBigException e) {
- throw new Error(e);
- }
- }
- }
-
- /**
- * Emits a switch instruction choosen according to the caracteristics
- * of the given list of keys and a default maxRate.
- *
- * @param keySets The array of all keys that must be compared to the
- * value on stack.
- * @param branches The labels representing the jump addresses linked
- * with the corresponding keys.
- * @param defaultBranch The label representing the default branch
- * address.
- */
- public void emitSWITCH(int[][] keySets,
- Label[] branches,
- Label defaultBranch,
- double minDensity) {
- assert keySets.length == branches.length;
-
- int flatSize = 0;
- for (int i = 0; i < keySets.length; ++i)
- flatSize += keySets[i].length;
-
- int[] flatKeys = new int[flatSize];
- Label[] flatBranches = new Label[flatSize];
- int flatI = 0;
- for (int i = 0; i < keySets.length; ++i) {
- Label branch = branches[i];
- int[] keys = keySets[i];
- for (int j = 0; j < keys.length; ++j) {
- flatKeys[flatI] = keys[j];
- flatBranches[flatI] = branch;
- }
- ++flatI;
- }
- assert flatI == flatSize;
- emitSWITCH(flatKeys, flatBranches, defaultBranch, minDensity);
- }
-
- /**
- * Emits a switch instruction choosen according to the caracteristics
- * of the given list of keys and a given maxRate.
- *
- * @param keys The array of all keys that must be compared to the
- * value on stack.
- * @param branches The labels representing the jump addresses linked
- * with the corresponding keys.
- * @param defaultBranch The label representing the default branch
- * address.
- * @param minDensity The minimum density to use for TABLESWITCH.
- */
- public void emitSWITCH(int[] keys,
- Label[] branches,
- Label defaultBranch,
- double minDensity) {
- assert keys.length == branches.length;
-
- //The special case for empty keys. It makes sense to allow
- //empty keys and generate LOOKUPSWITCH with defaultBranch
- //only. This is exactly what javac does for switch statement
- //that has only a default case.
- if (keys.length == 0) {
- emitLOOKUPSWITCH(keys, branches, defaultBranch);
- return;
- }
- //the rest of the code assumes that keys.length > 0
-
- // sorting the tables
- // FIXME use quicksort
- for (int i = 1; i < keys.length; i++) {
- for (int j = 1; j <= keys.length - i; j++) {
- if (keys[j] < keys[j - 1]) {
- int tmp = keys[j];
- keys[j] = keys[j - 1];
- keys[j - 1] = tmp;
-
- Label tmp_l = branches[j];
- branches[j] = branches[j - 1];
- branches[j - 1] = tmp_l;
- }
- }
- }
-
- int keyMin = keys[0], keyMax = keys[keys.length - 1];
- /** Calculate in long to guard against overflow. */
- long keyRange = (long)keyMax - keyMin + 1;
- if ((double)keys.length / (double)keyRange >= minDensity) {
- // Keys are dense enough, use a table in which holes are
- // filled with defaultBranch.
- int[] newKeys = new int[(int)keyRange];
- Label[] newBranches = new Label[(int)keyRange];
- int oldPos = 0;
- for (int i = 0; i < keyRange; ++i) {
- int key = keyMin + i;
- newKeys[i] = key;
- if (keys[oldPos] == key) {
- newBranches[i] = branches[oldPos];
- ++oldPos;
- } else
- newBranches[i] = defaultBranch;
- }
- assert oldPos == keys.length;
- emitTABLESWITCH(newKeys, newBranches, defaultBranch);
- } else
- emitLOOKUPSWITCH(keys, branches, defaultBranch);
- }
-
- /**
- * Emits a method invocation instruction choosen according to
- * the caracteristics of the given method.
- *
- * @param method The method to be invoked.
- */
- public void emitINVOKE(JMethod method) {
- String mName = method.getName();
- String cName = method.getOwner().getName();
- JMethodType mType = (JMethodType)method.getType();
- if (method.isStatic())
- emitINVOKESTATIC(cName, mName, mType);
- else if (method.getOwner().isInterface())
- emitINVOKEINTERFACE(cName, mName, mType);
- else
- emitINVOKEVIRTUAL(cName, mName, mType);
- }
-
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JField.java b/src/fjbg/ch/epfl/lamp/fjbg/JField.java
deleted file mode 100644
index 29d826ba99..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JField.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-
-/**
- * Java class field.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JField extends JFieldOrMethod {
-
- protected JField(FJBGContext context,
- JClass owner,
- int accessFlags,
- String name,
- JType type) {
- super(context, owner, accessFlags, name, type);
- }
-
- protected JField(FJBGContext context,
- JClass owner,
- DataInputStream stream)
- throws IOException {
- super(context, owner, stream);
- }
-
- // Follows javap output format for fields.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(flagsToString());
- buf.append(toExternalName(getType()));
- buf.append(" ");
- buf.append(getName());
- buf.append(";\n");
- java.util.Iterator attrsIt = attributes.iterator();
- while (attrsIt.hasNext()) {
- JAttribute attrs = (JAttribute)attrsIt.next();
- buf.append(attrs);
- }
- return buf.toString();
- }
-
- private String flagsToString() {
- StringBuffer buf = new StringBuffer();
- if (isPublic()) buf.append("public ");
- else if (isProtected()) buf.append("protected ");
- else if (isPrivate()) buf.append("private ");
- if (isStatic()) buf.append("static ");
- else if (isTransient()) buf.append("transient ");
- else if (isVolatile()) buf.append("volatile ");
- if (isAbstract()) buf.append("abstract ");
- else if (isFinal()) buf.append("final ");
- return buf.toString();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java
deleted file mode 100644
index 794c0f13b5..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Abstract superclass for a Java field or method.
- *
- * No two methods of fields in one class file may have the same name and
- * descriptor. See sections 4.6 and 4.7 of the JVM specification.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-abstract public class JFieldOrMethod extends JMember {
-
- protected final JClass owner;
- protected final JType type;
-
- protected final int nameIndex, signatureIndex;
-
- protected JFieldOrMethod(FJBGContext context,
- JClass owner,
- int accessFlags,
- String name,
- JType type) {
- super(context, accessFlags, name);
- this.owner = owner;
- this.type = type;
-
- nameIndex = owner.pool.addUtf8(name);
- signatureIndex = owner.pool.addUtf8(type.getSignature());
- }
-
- protected JFieldOrMethod(FJBGContext context,
- JClass owner,
- DataInputStream stream)
- throws IOException {
- super(context);
- this.owner = owner;
- this.accessFlags = stream.readShort();
- this.nameIndex = stream.readShort();
- this.name = owner.pool.lookupUtf8(nameIndex);
- this.signatureIndex = stream.readShort();
- this.type = JType.parseSignature(owner.pool.lookupUtf8(signatureIndex));
- this.attributes.addAll(JAttribute.readFrom(context, owner, this, stream));
- }
-
- public void freeze() throws JCode.OffsetTooBigException {
- assert !frozen;
- frozen = true;
- }
-
- public JClass getOwner() { return owner; }
-
- public JType getType() { return type; }
-
- public JClass getJClass() { return owner; }
-
- public boolean isPublic() {
- return (accessFlags & JAccessFlags.ACC_PUBLIC) != 0;
- }
-
- public boolean isPrivate() {
- return (accessFlags & JAccessFlags.ACC_PRIVATE) != 0;
- }
-
- public boolean isProtected() {
- return (accessFlags & JAccessFlags.ACC_PROTECTED) != 0;
- }
-
- public boolean isStatic() {
- return (accessFlags & JAccessFlags.ACC_STATIC) != 0;
- }
-
- public boolean isFinal() {
- return (accessFlags & JAccessFlags.ACC_FINAL) != 0;
- }
-
- public boolean isSuper() {
- return (accessFlags & JAccessFlags.ACC_SUPER) != 0;
- }
-
- public boolean isVolatile() {
- return (accessFlags & JAccessFlags.ACC_VOLATILE) != 0;
- }
-
- public boolean isTransient() {
- return (accessFlags & JAccessFlags.ACC_TRANSIENT) != 0;
- }
-
- public boolean isNative() {
- return (accessFlags & JAccessFlags.ACC_NATIVE) != 0;
- }
-
- public boolean isInterface() {
- return (accessFlags & JAccessFlags.ACC_INTERFACE) != 0;
- }
-
- public boolean isAbstract() {
- return (accessFlags & JAccessFlags.ACC_ABSTRACT) != 0;
- }
-
- public boolean isStrict() {
- return (accessFlags & JAccessFlags.ACC_STRICT) != 0;
- }
-
- // 1.5 specifics
- public boolean isBridge() {
- return (accessFlags & JAccessFlags.ACC_BRIDGE) != 0;
- }
-
- public boolean hasVarargs() {
- return (accessFlags & JAccessFlags.ACC_VARARGS) != 0;
- }
-
- public void writeTo(DataOutputStream stream) throws IOException {
- if (! frozen) {
- try {
- freeze();
- }
- catch (JCode.OffsetTooBigException e) {
- throw new Error(e);
- }
- }
- stream.writeShort(accessFlags);
- stream.writeShort(nameIndex);
- stream.writeShort(signatureIndex);
- JAttribute.writeTo(getAttributes(), stream);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java
deleted file mode 100644
index 1c1ced500d..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * InnerClasses attribute.
- *
- * The ClassFile structure of a class/interface C must have exactly one
- * InnerClasses attribute in its attributes table if the constant pool of C
- * contains a CONSTANT_Class_info entry which represents a class or interface
- * that is not a member of a package. See section 4.8.5 of the JVM Specification.
- *
- * @author Iulian Dragos, Stephane Micheloud
- * @version 1.1
- */
-public class JInnerClassesAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- /** InnerClass entries */
- private Map/*<String, Entry>*/ entries = new LinkedHashMap();
-
- public JInnerClassesAttribute(FJBGContext context, JClass clazz) {
- super(context, clazz);
- this.pool = clazz.pool;
- }
-
- public JInnerClassesAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- String inner = null;
- int count = stream.readShort();
- for (int i = 0; i < count; ++i) {
- int innerIdx = stream.readShort();
- int outerIdx = stream.readShort();
- int nameIdx = stream.readShort();
- int flags = stream.readShort();
- inner = pool.lookupClass(innerIdx);
- entries.put(inner, new Entry(innerIdx, outerIdx, nameIdx, flags));
- }
-
- assert name.equals(getName());
- }
-
- public void addEntry(String inner, String outer, String name, int flags) {
- int innerIdx = pool.addClass(inner);
- int outerIdx = 0;
- if (outer != null) outerIdx = pool.addClass(outer);
- int nameIdx = 0;
- if (name != null) nameIdx = pool.addUtf8(name);
-
- Entry e = new Entry(innerIdx, outerIdx, nameIdx, flags);
-
- if (entries.containsKey(inner)) {
- Entry other = (Entry) entries.get(inner);
- assert other.outerInfo == e.outerInfo && other.originalName == e.originalName && other.innerFlags == e.innerFlags
- : inner + " already declared as " + other;
- } else
- entries.put(inner, e);
- }
-
- public String getName() { return "InnerClasses"; }
-
- // Follows javap output format for the InnerClass attribute.
- /*@Override*/ public String toString() {
- // Here we intentionally use "InnerClass" as javap :-(
- StringBuffer buf = new StringBuffer(" InnerClass: ");
- for (Iterator it = entries.values().iterator(); it.hasNext(); ) {
- Entry e = (Entry)it.next();
- buf.append("\n ");
- buf.append(e.innerFlagsToString());
- buf.append("#");
- if (e.originalName != 0) {
- buf.append(e.originalName);
- buf.append("= #");
- }
- buf.append(e.innerInfo);
- if (e.outerInfo != 0) {
- buf.append(" of #");
- buf.append(e.outerInfo);
- }
- buf.append("; //");
- if (e.originalName != 0) {
- buf.append(pool.lookupUtf8(e.originalName));
- buf.append("=");
- }
- buf.append("class ");
- buf.append(pool.lookupClass(e.innerInfo));
- if (e.outerInfo != 0) {
- buf.append(" of class ");
- buf.append(pool.lookupClass(e.outerInfo));
- }
- }
- buf.append("\n");
- return buf.toString();
- }
-
- protected int getSize() {
- return 2 + entries.size() * 8;
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(entries.size());
- for (Iterator it = entries.values().iterator(); it.hasNext(); ) {
- Entry e = (Entry)it.next();
- stream.writeShort(e.innerInfo);
- stream.writeShort(e.outerInfo);
- stream.writeShort(e.originalName);
- stream.writeShort(e.innerFlags);
- }
- }
-
- /** An entry in the InnerClasses attribute, as defined by the JVM Spec. */
- private class Entry {
- /** CONSTANT_Class_info index in the pool for the inner class (mangled). */
- int innerInfo;
-
- /** CONSTANT_Class_info index in the pool for the outer class (mangled). */
- int outerInfo;
-
- /** CONSTANT_Utf8_info index in the pool for the original name of the inner class. */
- int originalName;
-
- /** Short int for modifier flags. */
- int innerFlags;
-
- public Entry(int iI, int oI, int oN, int f) {
- this.innerInfo = iI;
- this.outerInfo = oI;
- this.originalName = oN;
- this.innerFlags = f;
- }
-
- public Entry(String innerClass, String outerClass, String name, int flags) {
- this(pool.addClass(innerClass), pool.addClass(outerClass), pool.addUtf8(name), flags);
- }
-
- /** Two entries are equal if they refer to the same inner class.
- * innerInfo represents a unique name (mangled).
- */
- public boolean equals(Object other) {
- if (other instanceof Entry) {
- Entry otherEntry = (Entry) other;
- return otherEntry.innerInfo == this.innerInfo;
- }
- return false;
- }
-
- public String innerFlagsToString() {
- StringBuffer buf = new StringBuffer();
- if (isPublic()) buf.append("public ");
- else if (isProtected()) buf.append("protected ");
- else if (isPrivate()) buf.append("private ");
- //if (isStatic()) buf.append("static "); // as javap
- if (isAbstract()) buf.append("abstract ");
- else if (isFinal()) buf.append("final ");
- return buf.toString();
- }
-
- private boolean isPublic() {
- return (innerFlags & JAccessFlags.ACC_PUBLIC) != 0;
- }
-
- private boolean isPrivate() {
- return (innerFlags & JAccessFlags.ACC_PRIVATE) != 0;
- }
-
- private boolean isProtected() {
- return (innerFlags & JAccessFlags.ACC_PROTECTED) != 0;
- }
-
- private boolean isStatic() {
- return (innerFlags & JAccessFlags.ACC_STATIC) != 0;
- }
-
- private boolean isFinal() {
- return (innerFlags & JAccessFlags.ACC_FINAL) != 0;
- }
-
- private boolean isAbstract() {
- return (innerFlags & JAccessFlags.ACC_ABSTRACT) != 0;
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java b/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java
deleted file mode 100644
index 96f3b4ebef..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Labels which can be attached to instructions.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JLabel {
- public final static int UNDEFINED_ANCHOR = -1;
- protected int anchor = UNDEFINED_ANCHOR;
-
- public boolean isAnchored() { return anchor != UNDEFINED_ANCHOR; }
-
- public int getAnchor() {
- assert isAnchored();
- return anchor;
- }
-
- public void setAnchor(int anchor) {
- assert !isAnchored();
- this.anchor = anchor;
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java
deleted file mode 100644
index f8c09b8ef8..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Attribute storing correspondance between instructions and source
- * line numbers.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JLineNumberTableAttribute extends JAttribute {
- protected final JCode code;
-
- public JLineNumberTableAttribute(FJBGContext context,
- JClass clazz,
- JCode owner) {
- super(context, clazz);
- this.code = owner;
-
- assert owner.getOwner().getOwner() == clazz;
- }
-
- public JLineNumberTableAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.code = (JCode)owner;
-
- int[] mapping = new int[code.getSize()];
-
- int count = stream.readShort();
- for (int i = 0; i < count; ++i) {
- int startPC = stream.readShort();
- int lineNum = stream.readShort();
- mapping[startPC] = lineNum;
- }
-
- // Avoids duplication of LineNumberTable attribute
- // (see method ensureLineNumberCapacity in class JCode).
- assert code.lineNumbers == null;
- code.lineNumbers = new int[0];
-
- int lineNum = 0;
- for (int pc = 0; pc < mapping.length; ++pc) {
- if (mapping[pc] != 0) lineNum = mapping[pc];
- if (lineNum != 0) code.setLineNumber(pc, lineNum);
- }
-
- assert name.equals(getName());
- }
-
- public String getName() { return "LineNumberTable"; }
-
- // Follows javap output format for LineNumberTable attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" LineNumberTable: ");
- int[] encoding = encode();
- for (int i = 0; i < encoding.length/2; ++i) {
- buf.append("\n line ");
- buf.append(encoding[i * 2 + 1]);
- buf.append(": ");
- buf.append(encoding[i * 2]);
- }
- buf.append("\n");
- return buf.toString();
- }
-
- protected int[] encoding;
- protected int[] encode() {
- if (encoding == null) {
- int[] lineNumbers = code.getLineNumbers();
- int[] preEncoding = new int[lineNumbers.length * 2];
- int prevLineNum = 0;
-
- int i = 0;
- for (int pc = 0; pc < lineNumbers.length; ++pc) {
- int lineNum = lineNumbers[pc];
- if (lineNum != 0 & lineNum != prevLineNum) {
- preEncoding[i++] = pc;
- preEncoding[i++] = lineNum;
- prevLineNum = lineNum;
- }
- }
- if (i == preEncoding.length)
- encoding = preEncoding;
- else {
- encoding = new int[i];
- System.arraycopy(preEncoding, 0, encoding, 0, i);
- }
- }
- return encoding;
- }
-
- protected int getSize() {
- int[] encoding = encode();
- return 2 + encoding.length * 2;
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- int[] encoding = encode();
- int entries = encoding.length / 2;
- stream.writeShort(entries);
- for (int i = 0; i < entries; ++i) {
- stream.writeShort(encoding[i * 2]);
- stream.writeShort(encoding[i * 2 + 1]);
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java b/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java
deleted file mode 100644
index af7980656f..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Representation of a local variable or method argument.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JLocalVariable {
- protected final JMethod owner;
- protected final JType type;
- protected final String name;
- protected final int index;
-
- protected JLocalVariable(FJBGContext context,
- JMethod owner,
- JType type,
- String name,
- int index) {
- this.owner = owner;
- this.type = type;
- this.name = name;
- this.index = index;
-
- assert index < 0xFFFF : "index too big for local variable: " + index;
- }
-
- public JMethod getOwner() { return owner; }
- public int getIndex() { return index; }
- public String getName() { return name; }
- public JType getType() { return type; }
-
- /*@Override*/ public String toString() {
- return "0\t"+type.getSize()+"\t"+index+"\t"+name+"\t"+type;
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java
deleted file mode 100644
index b277cc71c0..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import ch.epfl.lamp.fjbg.JConstantPool.*;
-
-/**
- * Attribute storing local variables.
- *
- * @author Stephane Micheloud
- * @version 1.0
- */
-
-public class JLocalVariableTableAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- protected final LinkedList/*<Entry>*/ entries = new LinkedList();
- protected int localVariableIndex = 0;
-
- public JLocalVariableTableAttribute(FJBGContext context,
- JClass clazz,
- JCode code) {
- super(context, clazz);
- this.pool = clazz.pool;
-
- assert code.getOwner().getOwner() == clazz;
- }
-
- public JLocalVariableTableAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- int count = stream.readShort();
- for (int i = 0; i < count; ++i) {
- int startPc = stream.readShort();
- int length = stream.readShort();
- int nameIndex = stream.readShort();
- int descIndex = stream.readShort();
- int index = stream.readShort();
- addEntry(startPc, length, nameIndex, descIndex, index);
- }
-
- assert name.equals(getName());
- }
-
- public void addEntry(int startPc, int length, int nameIndex,
- int descIndex, int index) {
- entries.add(new Entry(startPc, length, nameIndex, descIndex, index));
- }
-
- public void addEntry(int startPc, int length, String name,
- String desc, int index) {
- Entry e = new Entry(startPc, length, name, desc, index);
- Entry other = getEntry(index);
- if (other != null) {
- assert other.nameIndex == e.nameIndex && other.descIndex == e.descIndex
- : e + " already declared as " + other;
- } else
- entries.add(e);
- }
-
- public void addEntry(int startPc, int length, String name, String desc) {
- entries.add(new Entry(startPc, length, name, desc));
- }
-
- public String getName() { return "LocalVariableTable"; }
-
- // Follows javap output format for LocalVariableTable attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" LocalVariableTable: ");
- buf.append("\n Start Length Slot Name Signature");
- for (Iterator it = entries.iterator(); it.hasNext(); ) {
- buf.append("\n ");
- Entry e = (Entry)it.next();
- Utf8Entry name = (Utf8Entry)pool.lookupEntry(e.nameIndex);
- Utf8Entry sig = (Utf8Entry)pool.lookupEntry(e.descIndex);
- buf.append(e.startPc);
- buf.append(" ");
- buf.append(e.length);
- buf.append(" ");
- buf.append(e.index);
- buf.append(" ");
- buf.append(name.getValue());
- buf.append(" ");
- buf.append(sig.getValue());
- }
- buf.append("\n");
- return buf.toString();
- }
-
- public int getMaxLocals() {
- return localVariableIndex;
- }
-
- public int getSize() {
- return 2 + entries.size() * 10;
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(entries.size());
- for (Iterator it = entries.iterator(); it.hasNext(); ) {
- Entry e = (Entry)it.next();
- stream.writeShort(e.startPc);
- stream.writeShort(e.length);
- stream.writeShort(e.nameIndex);
- stream.writeShort(e.descIndex);
- stream.writeShort(e.index);
- }
- }
-
- private Entry getEntry(int index) {
- Entry e = null;
- try { e = (Entry)entries.get(index); } catch (Exception ex) {}
- return e;
- }
-
- private class Entry {
- int startPc;
- int length;
- int nameIndex;
- int descIndex;
- int index;
-
- public Entry(int startPc, int length, int nameIndex, int descIndex, int index) {
- this.startPc = startPc;
- this.length = length;
- this.nameIndex = nameIndex;
- this.descIndex = descIndex;
- this.index = index;
- localVariableIndex += length;
- }
-
- public Entry(int startPc, int length, String name, String desc, int index) {
- this(startPc, length, pool.addUtf8(name), pool.addUtf8(desc), index);
- }
-
- public Entry(int startPc, int length, String name, String desc) {
- this(startPc, length, pool.addUtf8(name), pool.addUtf8(desc), localVariableIndex);
- }
-
- /** Two entries are equal if they refer to the same index.
- */
- public boolean equals(Object other) {
- if (other instanceof Entry) {
- Entry otherEntry = (Entry) other;
- return otherEntry.index == this.index;
- }
- return false;
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMember.java b/src/fjbg/ch/epfl/lamp/fjbg/JMember.java
deleted file mode 100644
index 6356cc874d..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JMember.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Abstract superclass for a Java class, field or method.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-
-abstract public class JMember {
-
- protected boolean frozen = false;
-
- protected final FJBGContext context;
-
- protected String name;
-
- protected int accessFlags;
-
- protected final List/*<JAttribute>*/ attributes = new LinkedList();
-
- protected JMember(FJBGContext context) { this.context = context; }
-
- protected JMember(FJBGContext context, int accessFlags, String name) {
- this(context);
- this.name = name;
- this.accessFlags = accessFlags;
- }
-
- /**
- * Gets the access flags of the class.
- * @return The int representing the access flags of the class.
- */
- public int getAccessFlags() { return accessFlags; }
-
- /**
- * Gets the name of the member.
- * @return The string representing the name of the member.
- */
- public String getName() { return name; }
-
- /**
- * Gets the type of the objects that are instances of the class.
- * @return The type of the instances of the class.
- */
- public abstract JType getType();
-
- /**
- * Gets the class corresponding to/owning this member
- * @return The class owning this member or the class itself.
- */
- public abstract JClass getJClass();
-
- /**
- * Gets the constant pool of the class.
- * @return The constant pool of the class.
- */
- public JConstantPool getConstantPool() { return getJClass().getConstantPool(); }
-
- public FJBGContext getContext() { return context; }
-
- /**
- * Adds an attribute to the class.
- * @param attr The attribute to be added.
- */
- public void addAttribute(JAttribute attr) {
- assert !frozen;
- attributes.add(attr);
- }
-
- /**
- * Gets the list of all attributes of the class.
- * @return The list of the attributes of the class representation.
- */
- public List/*<JAttribute>*/ getAttributes() {
- return attributes;
- }
-
- /**
- * Get the attribute with the given name, or null if it doesn't
- * exist.
- */
- public JAttribute getAttribute(String name) {
- Iterator attrIt = getAttributes().iterator();
- while (attrIt.hasNext()) {
- JAttribute attr = (JAttribute)attrIt.next();
- if (attr.getName().equals(name))
- return attr;
- }
- return null;
- }
-
- protected static String toExternalName(String name) {
- return name.replace('/', '.');
- }
-
- protected static String toExternalName(JType tpe) {
- return tpe.toString().replace(':', '.');
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
deleted file mode 100644
index 01d58a45c7..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Representation of a Java method.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JMethod extends JFieldOrMethod {
- public final static String CLASS_CONSTRUCTOR_NAME = "<clinit>";
- public final static String INSTANCE_CONSTRUCTOR_NAME = "<init>";
-
- protected /*final*/ JCode code;
- protected final String[] argNames;
-
- protected final LinkedList/*<JLocalVariable>*/ localVariables =
- new LinkedList();
- protected int localVariableIndex = 0;
-
-
- protected JMethod(FJBGContext context,
- JClass owner,
- int accessFlags,
- String name,
- JType returnType,
- JType[] argTypes,
- String[] argNames) {
- super(context,
- owner,
- accessFlags,
- name,
- new JMethodType(returnType, argTypes));
- this.argNames = argNames;
-
- assert argTypes.length == argNames.length;
-
- if (isAbstract() || isNative()) {
- code = null;
- } else {
- code = context.JCode(owner, this);
- addAttribute(context.JCodeAttribute(owner, this));
-
- if (!isStatic())
- addNewLocalVariable(owner.getType(), "this");
-
- for (int i = 0; i < argTypes.length; ++i)
- addNewLocalVariable(argTypes[i], argNames[i]);
- }
- }
-
- protected JMethod(FJBGContext context,
- JClass owner,
- DataInputStream stream)
- throws IOException {
- super(context, owner, stream);
-
- assert isAbstract() || isNative() || code != null;
-
- int n = 0;
- if (code != null) {
- for (Iterator it = code.getAttributes().iterator(); it.hasNext(); ) {
- JAttribute attr = (JAttribute)it.next();
- if (attr instanceof JLocalVariableTableAttribute)
- n = ((JLocalVariableTableAttribute)attr).getMaxLocals();
- }
- }
- this.localVariableIndex = n;
-
-
- JType[] argTypes = ((JMethodType)getType()).getArgumentTypes();
- argNames = new String[argTypes.length]; // TODO get from attribute
- for (int i = 0; i < argNames.length; ++i)
- argNames[i] = "v"+i;
- }
-
- public void freeze() throws JCode.OffsetTooBigException {
- if (code != null) code.freeze();
- super.freeze();
- }
-
- public JType getReturnType() {
- return ((JMethodType)type).getReturnType();
- }
-
- public JType[] getArgumentTypes() {
- return ((JMethodType)type).getArgumentTypes();
- }
-
- public int getArgsSize() {
- int size = ((JMethodType)type).getArgsSize();
- if (!isStatic()) size += 1; // for this
- return size;
- }
-
- public String[] getArgumentNames() {
- return argNames;
- }
-
- public JCode getCode() {
- assert !isAbstract();
- return code;
- }
-
- // Invoked by the JCode constructor
- protected void setCode(JCode code) {
- assert null == this.code;
- this.code = code;
- }
-
- public JCodeIterator codeIterator() {
- return new JCodeIterator(code);
- }
-
- // Local variables
- // FIXME : find a better management method for local variables
- public JLocalVariable addNewLocalVariable(JType type, String name) {
- assert !frozen;
- JLocalVariable var =
- context.JLocalVariable(this, type, name, localVariableIndex);
- localVariableIndex += type.getSize();
- localVariables.add(var);
- return var;
- }
-
- public JLocalVariable getLocalVariable(int index) {
- for (int i = 0; i < localVariables.size(); i++) {
- if (((JLocalVariable)localVariables.get(i)).index == index)
- return (JLocalVariable)localVariables.get(i);
- }
- return null;
- }
-
- public JLocalVariable[] getLocalVariables() {
- return (JLocalVariable[])localVariables
- .toArray(new JLocalVariable[localVariables.size()]);
- }
-
-
- public int getMaxLocals() {
- return localVariableIndex;
- }
-
- // Follows javap output format for methods.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(flagsToString());
- String name = getName();
- if (CLASS_CONSTRUCTOR_NAME.equals(name))
- buf.append("{}");
- else {
- if (INSTANCE_CONSTRUCTOR_NAME.equals(name))
- name = getOwner().getName();
- else {
- buf.append(toExternalName(getReturnType()));
- buf.append(" ");
- }
- buf.append(toExternalName(name));
- buf.append("(");
- JType[] ts = getArgumentTypes();
- for (int i = 0; i < ts.length; ++i) {
- if (i > 0) buf.append(", ");
- buf.append(toExternalName(ts[i]));
- }
- buf.append(")");
- }
- buf.append(";\n");
- Iterator it = attributes.iterator();
- while(it.hasNext()) {
- JAttribute attr = (JAttribute)it.next();
- buf.append(attr);
- }
- return buf.toString();
- }
-
- private String flagsToString() {
- StringBuffer buf = new StringBuffer();
- if (isPublic()) buf.append("public ");
- else if (isProtected()) buf.append("protected ");
- else if (isPrivate()) buf.append("private ");
- if (isBridge()) buf.append("<bridge> ");
- if (hasVarargs()) buf.append("<varargs> ");
- if (isStatic()) buf.append("static ");
- else if (isNative()) buf.append("native ");
- if (isAbstract()) buf.append("abstract ");
- else if (isFinal()) buf.append("final ");
- return buf.toString();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java
deleted file mode 100644
index cd3d71fd9c..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Type for Java methods. These types do not really exist in Java, but
- * are provided here because they are useful in several places.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JMethodType extends JType {
- protected final JType returnType;
- protected final JType[] argTypes;
- protected String signature = null;
-
- public final static JMethodType ARGLESS_VOID_FUNCTION =
- new JMethodType(JType.VOID, JType.EMPTY_ARRAY);
-
- public JMethodType(JType returnType, JType[] argTypes) {
- this.returnType = returnType;
- this.argTypes = argTypes;
- }
-
- public JType getReturnType() { return returnType; }
- public JType[] getArgumentTypes() { return argTypes; }
-
- public int getSize() {
- throw new UnsupportedOperationException();
- }
-
- public String getSignature() {
- if (signature == null) {
- StringBuffer buf = new StringBuffer();
- buf.append('(');
- for (int i = 0; i < argTypes.length; ++i)
- buf.append(argTypes[i].getSignature());
- buf.append(')');
- buf.append(returnType.getSignature());
- signature = buf.toString();
- }
- return signature;
- }
-
- public int getTag() { return T_UNKNOWN; }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append('(');
- for (int i = 0; i < argTypes.length; ++i)
- buf.append(argTypes[i].toString());
- buf.append(')');
- buf.append(returnType.toString());
- return buf.toString();
- }
-
- public int getArgsSize() {
- int size = 0;
- for (int i = 0; i < argTypes.length; ++i)
- size += argTypes[i].getSize();
- return size;
- }
-
- public int getProducedStack() {
- return returnType.getSize() - getArgsSize();
- }
-
- public boolean isCompatibleWith(JType other) {
- return false;
- }
- public boolean equals(Object o) {
- if (o instanceof JMethodType)
- return ((JMethodType)o).getSignature().equals(this.getSignature());
- else
- return false;
- }
- public int hashCode() {
- if (signature == null)
- return 0;
- else
- return signature.hashCode();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java b/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java
deleted file mode 100644
index 06db5b115a..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Types for Java objects.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JObjectType extends JReferenceType {
- protected final String name;
- protected String signature = null;
-
- public final static JObjectType JAVA_LANG_OBJECT =
- new JObjectType("java.lang.Object");
- public final static JObjectType JAVA_LANG_STRING =
- new JObjectType("java.lang.String");
- public final static JObjectType CLONEABLE =
- new JObjectType("Cloneable");
- public final static JObjectType JAVA_IO_SERIALIZABLE =
- new JObjectType("java.io.Serializable");
-
- public JObjectType(String name) {
- this.name = name;
- }
-
- public int getSize() { return 1; }
-
- public String getName() { return name; }
-
- public String getSignature() {
- if (signature == null)
- signature = "L" + name.replace('.','/') + ";";
- return signature;
- }
-
- public String getDescriptor() {
- return name.replace('.','/');
- }
-
- public int getTag() { return T_OBJECT; }
-
- public String toString() { return name; }
-
- public boolean isObjectType() { return true; }
-
- public boolean isCompatibleWith(JType other) {
- return other instanceof JObjectType
- || other == JType.REFERENCE;
- }
- public boolean equals(Object o) {
- if (o instanceof JObjectType)
- return ((JObjectType)o).getSignature().equals(this.getSignature());
- else
- return false;
- }
- public int hashCode() {
- return name.hashCode();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java b/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java
deleted file mode 100644
index cc68681a96..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java
+++ /dev/null
@@ -1,1267 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Definition of opcodes for the JVM.
- *
- * @author Michel Schinz, Thomas Friedli
- * @version 1.0
- */
-
-public class JOpcode {
- public final String name;
- public final int code;
-
- // The following attributes can be (statically) unknown for some
- // instructions, and are therefore not public. To know their value,
- // functions have to be used (see JCodeIterator).
- protected final int size;
- protected final JType[] producedDataTypes;
- protected final JType[] consumedDataTypes;
- protected final int jumpKind;
- protected final int successorCount;
-
- protected final static int UNKNOWN = Integer.MIN_VALUE;
-
- protected final static int JMP_NONE = 0;
- protected final static int JMP_NEXT = 1;
- protected final static int JMP_ALWAYS_S2_OFFSET = 2;
- protected final static int JMP_ALWAYS_S4_OFFSET = 3;
- protected final static int JMP_MAYBE_S2_OFFSET = 4;
- protected final static int JMP_TABLE = 5;
- protected final static int JMP_LOOKUP = 6;
-
- protected final static JType[] NO_DATA = new JType[0];
-
- protected final static JType[] INT_TYPE =
- new JType[] { JType.INT };
- protected final static JType[] FLOAT_TYPE =
- new JType[] { JType.FLOAT };
- protected final static JType[] LONG_TYPE =
- new JType[] { JType.LONG };
- protected final static JType[] DOUBLE_TYPE =
- new JType[] { JType.DOUBLE };
- protected final static JType[] OBJECT_REF_TYPE =
- new JType[] { JObjectType.JAVA_LANG_OBJECT };
- protected final static JType[] ARRAY_REF_TYPE =
- new JType[] { new JArrayType(JType.VOID) };
- protected final static JType[] REFERENCE_TYPE =
- new JType[] { JType.REFERENCE };
- protected final static JType[] ADDRESS_TYPE =
- new JType[] { JType.ADDRESS };
- protected final static JType[] UNKNOWN_TYPE =
- new JType[] { JType.UNKNOWN };
-
- /// Instruction codes
- public final static int cNOP = 0;
- public final static int cACONST_NULL = 1;
- public final static int cICONST_M1 = 2;
- public final static int cICONST_0 = 3;
- public final static int cICONST_1 = 4;
- public final static int cICONST_2 = 5;
- public final static int cICONST_3 = 6;
- public final static int cICONST_4 = 7;
- public final static int cICONST_5 = 8;
- public final static int cLCONST_0 = 9;
- public final static int cLCONST_1 = 10;
- public final static int cFCONST_0 = 11;
- public final static int cFCONST_1 = 12;
- public final static int cFCONST_2 = 13;
- public final static int cDCONST_0 = 14;
- public final static int cDCONST_1 = 15;
- public final static int cBIPUSH = 16;
- public final static int cSIPUSH = 17;
- public final static int cLDC = 18;
- public final static int cLDC_W = 19;
- public final static int cLDC2_W = 20;
- public final static int cILOAD = 21;
- public final static int cLLOAD = 22;
- public final static int cFLOAD = 23;
- public final static int cDLOAD = 24;
- public final static int cALOAD = 25;
- public final static int cILOAD_0 = 26;
- public final static int cILOAD_1 = 27;
- public final static int cILOAD_2 = 28;
- public final static int cILOAD_3 = 29;
- public final static int cLLOAD_0 = 30;
- public final static int cLLOAD_1 = 31;
- public final static int cLLOAD_2 = 32;
- public final static int cLLOAD_3 = 33;
- public final static int cFLOAD_0 = 34;
- public final static int cFLOAD_1 = 35;
- public final static int cFLOAD_2 = 36;
- public final static int cFLOAD_3 = 37;
- public final static int cDLOAD_0 = 38;
- public final static int cDLOAD_1 = 39;
- public final static int cDLOAD_2 = 40;
- public final static int cDLOAD_3 = 41;
- public final static int cALOAD_0 = 42;
- public final static int cALOAD_1 = 43;
- public final static int cALOAD_2 = 44;
- public final static int cALOAD_3 = 45;
- public final static int cIALOAD = 46;
- public final static int cLALOAD = 47;
- public final static int cFALOAD = 48;
- public final static int cDALOAD = 49;
- public final static int cAALOAD = 50;
- public final static int cBALOAD = 51;
- public final static int cCALOAD = 52;
- public final static int cSALOAD = 53;
- public final static int cISTORE = 54;
- public final static int cLSTORE = 55;
- public final static int cFSTORE = 56;
- public final static int cDSTORE = 57;
- public final static int cASTORE = 58;
- public final static int cISTORE_0 = 59;
- public final static int cISTORE_1 = 60;
- public final static int cISTORE_2 = 61;
- public final static int cISTORE_3 = 62;
- public final static int cLSTORE_0 = 63;
- public final static int cLSTORE_1 = 64;
- public final static int cLSTORE_2 = 65;
- public final static int cLSTORE_3 = 66;
- public final static int cFSTORE_0 = 67;
- public final static int cFSTORE_1 = 68;
- public final static int cFSTORE_2 = 69;
- public final static int cFSTORE_3 = 70;
- public final static int cDSTORE_0 = 71;
- public final static int cDSTORE_1 = 72;
- public final static int cDSTORE_2 = 73;
- public final static int cDSTORE_3 = 74;
- public final static int cASTORE_0 = 75;
- public final static int cASTORE_1 = 76;
- public final static int cASTORE_2 = 77;
- public final static int cASTORE_3 = 78;
- public final static int cIASTORE = 79;
- public final static int cLASTORE = 80;
- public final static int cFASTORE = 81;
- public final static int cDASTORE = 82;
- public final static int cAASTORE = 83;
- public final static int cBASTORE = 84;
- public final static int cCASTORE = 85;
- public final static int cSASTORE = 86;
- public final static int cPOP = 87;
- public final static int cPOP2 = 88;
- public final static int cDUP = 89;
- public final static int cDUP_X1 = 90;
- public final static int cDUP_X2 = 91;
- public final static int cDUP2 = 92;
- public final static int cDUP2_X1 = 93;
- public final static int cDUP2_X2 = 94;
- public final static int cSWAP = 95;
- public final static int cIADD = 96;
- public final static int cLADD = 97;
- public final static int cFADD = 98;
- public final static int cDADD = 99;
- public final static int cISUB = 100;
- public final static int cLSUB = 101;
- public final static int cFSUB = 102;
- public final static int cDSUB = 103;
- public final static int cIMUL = 104;
- public final static int cLMUL = 105;
- public final static int cFMUL = 106;
- public final static int cDMUL = 107;
- public final static int cIDIV = 108;
- public final static int cLDIV = 109;
- public final static int cFDIV = 110;
- public final static int cDDIV = 111;
- public final static int cIREM = 112;
- public final static int cLREM = 113;
- public final static int cFREM = 114;
- public final static int cDREM = 115;
- public final static int cINEG = 116;
- public final static int cLNEG = 117;
- public final static int cFNEG = 118;
- public final static int cDNEG = 119;
- public final static int cISHL = 120;
- public final static int cLSHL = 121;
- public final static int cISHR = 122;
- public final static int cLSHR = 123;
- public final static int cIUSHR = 124;
- public final static int cLUSHR = 125;
- public final static int cIAND = 126;
- public final static int cLAND = 127;
- public final static int cIOR = 128;
- public final static int cLOR = 129;
- public final static int cIXOR = 130;
- public final static int cLXOR = 131;
- public final static int cIINC = 132;
- public final static int cI2L = 133;
- public final static int cI2F = 134;
- public final static int cI2D = 135;
- public final static int cL2I = 136;
- public final static int cL2F = 137;
- public final static int cL2D = 138;
- public final static int cF2I = 139;
- public final static int cF2L = 140;
- public final static int cF2D = 141;
- public final static int cD2I = 142;
- public final static int cD2L = 143;
- public final static int cD2F = 144;
- public final static int cI2B = 145;
- public final static int cI2C = 146;
- public final static int cI2S = 147;
- public final static int cLCMP = 148;
- public final static int cFCMPL = 149;
- public final static int cFCMPG = 150;
- public final static int cDCMPL = 151;
- public final static int cDCMPG = 152;
- public final static int cIFEQ = 153;
- public final static int cIFNE = 154;
- public final static int cIFLT = 155;
- public final static int cIFGE = 156;
- public final static int cIFGT = 157;
- public final static int cIFLE = 158;
- public final static int cIF_ICMPEQ = 159;
- public final static int cIF_ICMPNE = 160;
- public final static int cIF_ICMPLT = 161;
- public final static int cIF_ICMPGE = 162;
- public final static int cIF_ICMPGT = 163;
- public final static int cIF_ICMPLE = 164;
- public final static int cIF_ACMPEQ = 165;
- public final static int cIF_ACMPNE = 166;
- public final static int cGOTO = 167;
- public final static int cJSR = 168;
- public final static int cRET = 169;
- public final static int cTABLESWITCH = 170;
- public final static int cLOOKUPSWITCH = 171;
- public final static int cIRETURN = 172;
- public final static int cLRETURN = 173;
- public final static int cFRETURN = 174;
- public final static int cDRETURN = 175;
- public final static int cARETURN = 176;
- public final static int cRETURN = 177;
- public final static int cGETSTATIC = 178;
- public final static int cPUTSTATIC = 179;
- public final static int cGETFIELD = 180;
- public final static int cPUTFIELD = 181;
- public final static int cINVOKEVIRTUAL = 182;
- public final static int cINVOKESPECIAL = 183;
- public final static int cINVOKESTATIC = 184;
- public final static int cINVOKEINTERFACE = 185;
- public final static int cNEW = 187;
- public final static int cNEWARRAY = 188;
- public final static int cANEWARRAY = 189;
- public final static int cARRAYLENGTH = 190;
- public final static int cATHROW = 191;
- public final static int cCHECKCAST = 192;
- public final static int cINSTANCEOF = 193;
- public final static int cMONITORENTER = 194;
- public final static int cMONITOREXIT = 195;
- public final static int cWIDE = 196;
- public final static int cMULTIANEWARRAY = 197;
- public final static int cIFNULL = 198;
- public final static int cIFNONNULL = 199;
- public final static int cGOTO_W = 200;
- public final static int cJSR_W = 201;
-
- // Objects representing instructions
- public final static JOpcode NOP =
- new JOpcode("NOP", cNOP, 1, NO_DATA, NO_DATA, JMP_NEXT);
- public final static JOpcode ACONST_NULL = new JOpcode("ACONST_NULL",
- cACONST_NULL,
- 1,
- REFERENCE_TYPE,
- NO_DATA,
- JMP_NEXT);
- public final static JOpcode ICONST_M1 =
- new JOpcode("ICONST_M1", cICONST_M1, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_0 =
- new JOpcode("ICONST_0", cICONST_0, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_1 =
- new JOpcode("ICONST_1", cICONST_1, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_2 =
- new JOpcode("ICONST_2", cICONST_2, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_3 =
- new JOpcode("ICONST_3", cICONST_3, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_4 =
- new JOpcode("ICONST_4", cICONST_4, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ICONST_5 =
- new JOpcode("ICONST_5", cICONST_5, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LCONST_0 =
- new JOpcode("LCONST_0", cLCONST_0, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LCONST_1 =
- new JOpcode("LCONST_1", cLCONST_1, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FCONST_0 =
- new JOpcode("FCONST_0", cFCONST_0, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FCONST_1 =
- new JOpcode("FCONST_1", cFCONST_1, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FCONST_2 =
- new JOpcode("FCONST_2", cFCONST_2, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DCONST_0 =
- new JOpcode("DCONST_0", cDCONST_0, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DCONST_1 =
- new JOpcode("DCONST_1", cDCONST_1, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode BIPUSH =
- new JOpcode("BIPUSH", cBIPUSH, 2, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode SIPUSH =
- new JOpcode("SIPUSH", cSIPUSH, 3, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LDC =
- new JOpcode("LDC", cLDC, 2, UNKNOWN_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LDC_W =
- new JOpcode("LDC_W", cLDC_W, 3, UNKNOWN_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LDC2_W =
- new JOpcode("LDC2_W", cLDC2_W, 3, UNKNOWN_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ILOAD =
- new JOpcode("ILOAD", cILOAD, 2, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LLOAD =
- new JOpcode("LLOAD", cLLOAD, 2, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FLOAD =
- new JOpcode("FLOAD", cFLOAD, 2, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DLOAD =
- new JOpcode("DLOAD", cDLOAD, 2, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ALOAD =
- new JOpcode("ALOAD", cALOAD, 2, REFERENCE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ILOAD_0 =
- new JOpcode("ILOAD_0", cILOAD_0, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ILOAD_1 =
- new JOpcode("ILOAD_1", cILOAD_1, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ILOAD_2 =
- new JOpcode("ILOAD_2", cILOAD_2, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ILOAD_3 =
- new JOpcode("ILOAD_3", cILOAD_3, 1, INT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LLOAD_0 =
- new JOpcode("LLOAD_0", cLLOAD_0, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LLOAD_1 =
- new JOpcode("LLOAD_1", cLLOAD_1, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LLOAD_2 =
- new JOpcode("LLOAD_2", cLLOAD_2, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode LLOAD_3 =
- new JOpcode("LLOAD_3", cLLOAD_3, 1, LONG_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FLOAD_0 =
- new JOpcode("FLOAD_0", cFLOAD_0, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FLOAD_1 =
- new JOpcode("FLOAD_1", cFLOAD_1, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FLOAD_2 =
- new JOpcode("FLOAD_2", cFLOAD_2, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode FLOAD_3 =
- new JOpcode("FLOAD_3", cFLOAD_3, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DLOAD_0 =
- new JOpcode("DLOAD_0", cDLOAD_0, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DLOAD_1 =
- new JOpcode("DLOAD_1", cDLOAD_1, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DLOAD_2 =
- new JOpcode("DLOAD_2", cDLOAD_2, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode DLOAD_3 =
- new JOpcode("DLOAD_3", cDLOAD_3, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ALOAD_0 =
- new JOpcode("ALOAD_0", cALOAD_0, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ALOAD_1 =
- new JOpcode("ALOAD_1", cALOAD_1, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ALOAD_2 =
- new JOpcode("ALOAD_2", cALOAD_2, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode ALOAD_3 =
- new JOpcode("ALOAD_3", cALOAD_3, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode IALOAD =
- new JOpcode("IALOAD",
- cIALOAD,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JArrayType.INT},
- JMP_NEXT);
- public final static JOpcode LALOAD =
- new JOpcode("LALOAD",
- cLALOAD,
- 1,
- LONG_TYPE,
- new JType[] {JType.INT, JArrayType.LONG},
- JMP_NEXT);
- public final static JOpcode FALOAD =
- new JOpcode("FALOAD",
- cFALOAD,
- 1,
- FLOAT_TYPE,
- new JType[] {JType.INT, JArrayType.FLOAT},
- JMP_NEXT);
- public final static JOpcode DALOAD =
- new JOpcode("DALOAD",
- cDALOAD,
- 1,
- DOUBLE_TYPE,
- new JType[] {JType.INT, JArrayType.DOUBLE},
- JMP_NEXT);
- public final static JOpcode AALOAD =
- new JOpcode("AALOAD",
- cAALOAD,
- 1,
- REFERENCE_TYPE,
- new JType[] {JType.INT, JArrayType.REFERENCE},
- JMP_NEXT);
- public final static JOpcode BALOAD =
- new JOpcode("BALOAD",
- cBALOAD,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, new JArrayType(JType.UNKNOWN)},
- JMP_NEXT);
- public final static JOpcode CALOAD =
- new JOpcode("CALOAD",
- cCALOAD,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JArrayType.CHAR},
- JMP_NEXT);
- public final static JOpcode SALOAD =
- new JOpcode("SALOAD",
- cSALOAD,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JArrayType.SHORT},
- JMP_NEXT);
- public final static JOpcode ISTORE =
- new JOpcode("ISTORE", cISTORE, 2, NO_DATA, INT_TYPE, JMP_NEXT);
- public final static JOpcode LSTORE =
- new JOpcode("LSTORE", cLSTORE, 2, NO_DATA, LONG_TYPE, JMP_NEXT);
- public final static JOpcode FSTORE =
- new JOpcode("FSTORE", cFSTORE, 2, NO_DATA, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode DSTORE =
- new JOpcode("DSTORE", cDSTORE, 2, NO_DATA, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode ASTORE =
- new JOpcode("ASTORE", cASTORE, 2, NO_DATA, REFERENCE_TYPE, JMP_NEXT);
- public final static JOpcode ISTORE_0 =
- new JOpcode("ISTORE_0", cISTORE_0, 1, NO_DATA, INT_TYPE, JMP_NEXT);
- public final static JOpcode ISTORE_1 =
- new JOpcode("ISTORE_1", cISTORE_1, 1, NO_DATA, INT_TYPE, JMP_NEXT);
- public final static JOpcode ISTORE_2 =
- new JOpcode("ISTORE_2", cISTORE_2, 1, NO_DATA, INT_TYPE, JMP_NEXT);
- public final static JOpcode ISTORE_3 =
- new JOpcode("ISTORE_3", cISTORE_3, 1, NO_DATA, INT_TYPE, JMP_NEXT);
- public final static JOpcode LSTORE_0 =
- new JOpcode("LSTORE_0", cLSTORE_0, 1, NO_DATA, LONG_TYPE, JMP_NEXT);
- public final static JOpcode LSTORE_1 =
- new JOpcode("LSTORE_1", cLSTORE_1, 1, NO_DATA, LONG_TYPE, JMP_NEXT);
- public final static JOpcode LSTORE_2 =
- new JOpcode("LSTORE_2", cLSTORE_2, 1, NO_DATA, LONG_TYPE, JMP_NEXT);
- public final static JOpcode LSTORE_3 =
- new JOpcode("LSTORE_3", cLSTORE_3, 1, NO_DATA, LONG_TYPE, JMP_NEXT);
- public final static JOpcode FSTORE_0 =
- new JOpcode("FSTORE_0", cFSTORE_0, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode FSTORE_1 =
- new JOpcode("FSTORE_1", cFSTORE_1, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode FSTORE_2 =
- new JOpcode("FSTORE_2", cFSTORE_2, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode FSTORE_3 =
- new JOpcode("FSTORE_3", cFSTORE_3, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode DSTORE_0 =
- new JOpcode("DSTORE_0", cDSTORE_0, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode DSTORE_1 =
- new JOpcode("DSTORE_1", cDSTORE_1, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode DSTORE_2 =
- new JOpcode("DSTORE_2", cDSTORE_2, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode DSTORE_3 =
- new JOpcode("DSTORE_3", cDSTORE_3, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode ASTORE_0 = new JOpcode("ASTORE_0",
- cASTORE_0,
- 1,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_NEXT);
- public final static JOpcode ASTORE_1 = new JOpcode("ASTORE_1",
- cASTORE_1,
- 1,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_NEXT);
- public final static JOpcode ASTORE_2 = new JOpcode("ASTORE_2",
- cASTORE_2,
- 1,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_NEXT);
- public final static JOpcode ASTORE_3 = new JOpcode("ASTORE_3",
- cASTORE_3,
- 1,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_NEXT);
- public final static JOpcode IASTORE =
- new JOpcode("IASTORE",
- cIASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.INT,
- JType.INT,
- JArrayType.INT},
- JMP_NEXT);
- public final static JOpcode LASTORE =
- new JOpcode("LASTORE",
- cLASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.LONG,
- JType.INT,
- JArrayType.LONG},
- JMP_NEXT);
- public final static JOpcode FASTORE =
- new JOpcode("FASTORE",
- cFASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.FLOAT,
- JType.INT,
- JArrayType.FLOAT},
- JMP_NEXT);
- public final static JOpcode DASTORE =
- new JOpcode("DASTORE",
- cDASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.DOUBLE,
- JType.INT,
- JArrayType.DOUBLE},
- JMP_NEXT);
- public final static JOpcode AASTORE =
- new JOpcode("AASTORE",
- cAASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.REFERENCE,
- JType.INT,
- JArrayType.REFERENCE},
- JMP_NEXT);
- public final static JOpcode BASTORE =
- new JOpcode("BASTORE",
- cBASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.INT,
- JType.INT,
- new JArrayType(JType.UNKNOWN)},
- JMP_NEXT);
- public final static JOpcode CASTORE =
- new JOpcode("CASTORE",
- cCASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.INT,
- JType.INT,
- JArrayType.CHAR},
- JMP_NEXT);
- public final static JOpcode SASTORE =
- new JOpcode("SASTORE",
- cSASTORE,
- 1,
- NO_DATA,
- new JType[] { JType.INT,
- JType.INT,
- JArrayType.SHORT},
- JMP_NEXT);
- public final static JOpcode POP =
- new JOpcode("POP", cPOP, 1, NO_DATA, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode POP2 =
- new JOpcode("POP2", cPOP2, 1, NO_DATA, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode DUP =
- new JOpcode("DUP", cDUP, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode DUP_X1 = new JOpcode("DUP_X1",
- cDUP_X1,
- 1,
- UNKNOWN_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode DUP_X2 = new JOpcode("DUP_X2",
- cDUP_X2,
- 1,
- UNKNOWN_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode DUP2 =
- new JOpcode("DUP2", cDUP2, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode DUP2_X1 = new JOpcode("DUP2_X1",
- cDUP2_X1,
- 1,
- UNKNOWN_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode DUP2_X2 = new JOpcode("DUP2_X2",
- cDUP2_X2,
- 1,
- UNKNOWN_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode SWAP =
- new JOpcode("SWAP", cSWAP, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode IADD =
- new JOpcode("IADD",
- cIADD,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LADD =
- new JOpcode("LADD",
- cLADD,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FADD =
- new JOpcode("FADD",
- cFADD,
- 1,
- FLOAT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DADD =
- new JOpcode("DADD",
- cDADD,
- 1,
- DOUBLE_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode ISUB =
- new JOpcode("ISUB",
- cISUB,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LSUB =
- new JOpcode("LSUB",
- cLSUB,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FSUB =
- new JOpcode("FSUB",
- cFSUB,
- 1,
- FLOAT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DSUB =
- new JOpcode("DSUB",
- cDSUB,
- 1,
- DOUBLE_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode IMUL =
- new JOpcode("IMUL",
- cIMUL,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LMUL =
- new JOpcode("LMUL",
- cLMUL,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FMUL =
- new JOpcode("FMUL",
- cFMUL,
- 1,
- FLOAT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DMUL =
- new JOpcode("DMUL",
- cDMUL,
- 1,
- DOUBLE_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode IDIV =
- new JOpcode("IDIV",
- cIDIV,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LDIV =
- new JOpcode("LDIV",
- cLDIV,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FDIV =
- new JOpcode("FDIV",
- cFDIV,
- 1,
- FLOAT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DDIV =
- new JOpcode("DDIV",
- cDDIV,
- 1,
- DOUBLE_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode IREM =
- new JOpcode("IREM",
- cIREM,
- 1,
- INT_TYPE,
- new JType[] {JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LREM =
- new JOpcode("LREM",
- cLREM,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FREM =
- new JOpcode("FREM",
- cFREM,
- 1,
- FLOAT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DREM =
- new JOpcode("DREM",
- cDREM,
- 1,
- DOUBLE_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode INEG =
- new JOpcode("INEG", cINEG, 1, INT_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode LNEG =
- new JOpcode("LNEG", cLNEG, 1, LONG_TYPE, LONG_TYPE, JMP_NEXT);
- public final static JOpcode FNEG =
- new JOpcode("FNEG", cFNEG, 1, FLOAT_TYPE, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode DNEG =
- new JOpcode("DNEG", cDNEG, 1, DOUBLE_TYPE, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode ISHL =
- new JOpcode("ISHL", cISHL,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LSHL =
- new JOpcode("LSHL",
- cLSHL,
- 1,
- LONG_TYPE,
- new JType [] { JType.INT, JType.LONG },
- JMP_NEXT);
- public final static JOpcode ISHR =
- new JOpcode("ISHR",
- cISHR,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LSHR =
- new JOpcode("LSHR",
- cLSHR,
- 1,
- LONG_TYPE,
- new JType[] { JType.INT, JType.LONG },
- JMP_NEXT);
- public final static JOpcode IUSHR =
- new JOpcode("IUSHR",
- cIUSHR,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LUSHR =
- new JOpcode("LUSHR",
- cLUSHR,
- 1,
- LONG_TYPE,
- new JType[] { JType.INT, JType.LONG },
- JMP_NEXT);
- public final static JOpcode IAND =
- new JOpcode("IAND",
- cIAND,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LAND =
- new JOpcode("LAND",
- cLAND,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode IOR =
- new JOpcode("IOR",
- cIOR,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LOR =
- new JOpcode("LOR",
- cLOR,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode IXOR =
- new JOpcode("IXOR",
- cIXOR,
- 1,
- INT_TYPE,
- new JType[] { JType.INT, JType.INT },
- JMP_NEXT);
- public final static JOpcode LXOR =
- new JOpcode("LXOR",
- cLXOR,
- 1,
- LONG_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode IINC =
- new JOpcode("IINC", cIINC, 3, NO_DATA, NO_DATA, JMP_NEXT);
- public final static JOpcode I2L =
- new JOpcode("I2L", cI2L, 1, LONG_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode I2F =
- new JOpcode("I2F", cI2F, 1, FLOAT_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode I2D =
- new JOpcode("I2D", cI2D, 1, DOUBLE_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode L2I =
- new JOpcode("L2I", cL2I, 1, INT_TYPE, LONG_TYPE, JMP_NEXT);
- public final static JOpcode L2F =
- new JOpcode("L2F", cL2F, 1, FLOAT_TYPE, LONG_TYPE, JMP_NEXT);
- public final static JOpcode L2D =
- new JOpcode("L2D", cL2D, 1, DOUBLE_TYPE, LONG_TYPE, JMP_NEXT);
- public final static JOpcode F2I =
- new JOpcode("F2I", cF2I, 1, INT_TYPE, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode F2L =
- new JOpcode("F2L", cF2L, 1, LONG_TYPE, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode F2D =
- new JOpcode("F2D", cF2D, 1, DOUBLE_TYPE, FLOAT_TYPE, JMP_NEXT);
- public final static JOpcode D2I =
- new JOpcode("D2I", cD2I, 1, INT_TYPE, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode D2L =
- new JOpcode("D2L", cD2L, 1, LONG_TYPE, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode D2F =
- new JOpcode("D2F", cD2F, 1, FLOAT_TYPE, DOUBLE_TYPE, JMP_NEXT);
- public final static JOpcode I2B =
- new JOpcode("I2B", cI2B, 1, INT_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode I2C =
- new JOpcode("I2C", cI2C, 1, INT_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode I2S =
- new JOpcode("I2S", cI2S, 1, INT_TYPE, INT_TYPE, JMP_NEXT);
- public final static JOpcode LCMP =
- new JOpcode("LCMP",
- cLCMP,
- 1,
- INT_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode FCMPL =
- new JOpcode("FCMPL",
- cFCMPL,
- 1,
- INT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode FCMPG =
- new JOpcode("FCMPG",
- cFCMPG,
- 1,
- INT_TYPE,
- new JType[] { JType.FLOAT, JType.FLOAT },
- JMP_NEXT);
- public final static JOpcode DCMPL =
- new JOpcode("DCMPL",
- cDCMPL,
- 1,
- INT_TYPE,
- new JType[] { JType.LONG, JType.LONG },
- JMP_NEXT);
- public final static JOpcode DCMPG =
- new JOpcode("DCMPG",
- cDCMPG,
- 1,
- INT_TYPE,
- new JType[] { JType.DOUBLE, JType.DOUBLE },
- JMP_NEXT);
- public final static JOpcode IFEQ =
- new JOpcode("IFEQ", cIFEQ, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFNE =
- new JOpcode("IFNE", cIFNE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFLT =
- new JOpcode("IFLT", cIFLT, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFGE =
- new JOpcode("IFGE", cIFGE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFGT =
- new JOpcode("IFGT", cIFGT, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFLE =
- new JOpcode("IFLE", cIFLE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPEQ =
- new JOpcode("IF_ICMPEQ",
- cIF_ICMPEQ,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPNE =
- new JOpcode("IF_ICMPNE",
- cIF_ICMPNE,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPLT =
- new JOpcode("IF_ICMPLT",
- cIF_ICMPLT,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPGE =
- new JOpcode("IF_ICMPGE",
- cIF_ICMPGE,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPGT =
- new JOpcode("IF_ICMPGT",
- cIF_ICMPGT,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ICMPLE =
- new JOpcode("IF_ICMPLE",
- cIF_ICMPLE,
- 3,
- NO_DATA,
- new JType[] { JType.INT, JType.INT },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ACMPEQ =
- new JOpcode("IF_ACMPEQ",
- cIF_ACMPEQ,
- 3,
- NO_DATA,
- new JType[] { JType.REFERENCE, JType.REFERENCE },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IF_ACMPNE =
- new JOpcode("IF_ACMPNE",
- cIF_ACMPNE,
- 3,
- NO_DATA,
- new JType[] { JType.REFERENCE, JType.REFERENCE },
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode GOTO =
- new JOpcode("GOTO", cGOTO, 3, NO_DATA, NO_DATA, JMP_ALWAYS_S2_OFFSET);
- public final static JOpcode JSR =
- new JOpcode("JSR", cJSR, 3, ADDRESS_TYPE, NO_DATA, JMP_ALWAYS_S2_OFFSET);
- public final static JOpcode RET =
- new JOpcode("RET", cRET, 2, NO_DATA, NO_DATA, JMP_NONE);
- public final static JOpcode TABLESWITCH = new JOpcode("TABLESWITCH",
- cTABLESWITCH,
- UNKNOWN,
- NO_DATA,
- INT_TYPE,
- JMP_TABLE);
- public final static JOpcode LOOKUPSWITCH = new JOpcode("LOOKUPSWITCH",
- cLOOKUPSWITCH,
- UNKNOWN,
- NO_DATA,
- INT_TYPE,
- JMP_LOOKUP);
- public final static JOpcode IRETURN =
- new JOpcode("IRETURN", cIRETURN, 1, NO_DATA, INT_TYPE, JMP_NONE);
- public final static JOpcode LRETURN =
- new JOpcode("LRETURN", cLRETURN, 1, NO_DATA, LONG_TYPE, JMP_NONE);
- public final static JOpcode FRETURN =
- new JOpcode("FRETURN", cFRETURN, 1, NO_DATA, FLOAT_TYPE, JMP_NONE);
- public final static JOpcode DRETURN =
- new JOpcode("DRETURN", cDRETURN, 1, NO_DATA, DOUBLE_TYPE, JMP_NONE);
- public final static JOpcode ARETURN = new JOpcode("ARETURN",
- cARETURN,
- 1,
- NO_DATA,
- OBJECT_REF_TYPE,
- JMP_NONE);
- public final static JOpcode RETURN =
- new JOpcode("RETURN", cRETURN, 1, NO_DATA, NO_DATA, JMP_NONE);
- public final static JOpcode GETSTATIC = new JOpcode("GETSTATIC",
- cGETSTATIC,
- 3,
- UNKNOWN_TYPE,
- NO_DATA,
- JMP_NEXT);
- public final static JOpcode PUTSTATIC = new JOpcode("PUTSTATIC",
- cPUTSTATIC,
- 3,
- NO_DATA,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode GETFIELD = new JOpcode("GETFIELD",
- cGETFIELD,
- 3,
- UNKNOWN_TYPE,
- OBJECT_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode PUTFIELD =
- new JOpcode("PUTFIELD", cPUTFIELD, 3, NO_DATA, UNKNOWN_TYPE, JMP_NEXT);
- public final static JOpcode INVOKEVIRTUAL = new JOpcode("INVOKEVIRTUAL",
- cINVOKEVIRTUAL,
- 3,
- NO_DATA,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode INVOKESPECIAL = new JOpcode("INVOKESPECIAL",
- cINVOKESPECIAL,
- 3,
- NO_DATA,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode INVOKESTATIC = new JOpcode("INVOKESTATIC",
- cINVOKESTATIC,
- 3,
- NO_DATA,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode INVOKEINTERFACE =
- new JOpcode("INVOKEINTERFACE",
- cINVOKEINTERFACE,
- 5,
- NO_DATA,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode NEW =
- new JOpcode("NEW", cNEW, 3, OBJECT_REF_TYPE, NO_DATA, JMP_NEXT);
- public final static JOpcode NEWARRAY =
- new JOpcode("NEWARRAY",
- cNEWARRAY,
- 2,
- ARRAY_REF_TYPE,
- INT_TYPE,
- JMP_NEXT);
- public final static JOpcode ANEWARRAY =
- new JOpcode("ANEWARRAY",
- cANEWARRAY,
- 3,
- ARRAY_REF_TYPE,
- INT_TYPE,
- JMP_NEXT);
- public final static JOpcode ARRAYLENGTH = new JOpcode("ARRAYLENGTH",
- cARRAYLENGTH,
- 1,
- INT_TYPE,
- ARRAY_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode ATHROW = new JOpcode("ATHROW",
- cATHROW,
- 1,
- OBJECT_REF_TYPE,
- OBJECT_REF_TYPE,
- JMP_NONE);
- public final static JOpcode CHECKCAST = new JOpcode("CHECKCAST",
- cCHECKCAST,
- 3,
- OBJECT_REF_TYPE,
- OBJECT_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode INSTANCEOF = new JOpcode("INSTANCEOF",
- cINSTANCEOF,
- 3,
- INT_TYPE,
- OBJECT_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode MONITORENTER = new JOpcode("MONITORENTER",
- cMONITORENTER,
- 1,
- NO_DATA,
- OBJECT_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode MONITOREXIT = new JOpcode("MONITOREXIT",
- cMONITOREXIT,
- 1,
- NO_DATA,
- OBJECT_REF_TYPE,
- JMP_NEXT);
- public final static JOpcode WIDE = new JOpcode("WIDE",
- cWIDE,
- UNKNOWN,
- UNKNOWN_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode MULTIANEWARRAY = new JOpcode("MULTIANEWARRAY",
- cMULTIANEWARRAY,
- 4,
- ARRAY_REF_TYPE,
- UNKNOWN_TYPE,
- JMP_NEXT);
- public final static JOpcode IFNULL = new JOpcode("IFNULL",
- cIFNULL,
- 3,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode IFNONNULL = new JOpcode("IFNONNULL",
- cIFNONNULL,
- 3,
- NO_DATA,
- REFERENCE_TYPE,
- JMP_MAYBE_S2_OFFSET);
- public final static JOpcode GOTO_W = new JOpcode("GOTO_W",
- cGOTO_W,
- 5,
- NO_DATA,
- NO_DATA,
- JMP_ALWAYS_S4_OFFSET);
- public final static JOpcode JSR_W =
- new JOpcode("JSR_W", cJSR_W, 5, ADDRESS_TYPE, NO_DATA, JMP_NEXT);
-
- public final static JOpcode[] OPCODES = {
- NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
- ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0,
- LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
- DCONST_1, BIPUSH, SIPUSH, LDC, LDC_W,
- LDC2_W, ILOAD, LLOAD, FLOAD, DLOAD,
- ALOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3,
- LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, FLOAD_0,
- FLOAD_1, FLOAD_2, FLOAD_3, DLOAD_0, DLOAD_1,
- DLOAD_2, DLOAD_3, ALOAD_0, ALOAD_1, ALOAD_2,
- ALOAD_3, IALOAD, LALOAD, FALOAD, DALOAD,
- AALOAD, BALOAD, CALOAD, SALOAD, ISTORE,
- LSTORE, FSTORE, DSTORE, ASTORE, ISTORE_0,
- ISTORE_1, ISTORE_2, ISTORE_3, LSTORE_0, LSTORE_1,
- LSTORE_2, LSTORE_3, FSTORE_0, FSTORE_1, FSTORE_2,
- FSTORE_3, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3,
- ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, IASTORE,
- LASTORE, FASTORE, DASTORE, AASTORE, BASTORE,
- CASTORE, SASTORE, POP, POP2, DUP,
- DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
- SWAP, IADD, LADD, FADD, DADD,
- ISUB, LSUB, FSUB, DSUB, IMUL,
- LMUL, FMUL, DMUL, IDIV, LDIV,
- FDIV, DDIV, IREM, LREM, FREM,
- DREM, INEG, LNEG, FNEG, DNEG,
- ISHL, LSHL, ISHR, LSHR, IUSHR,
- LUSHR, IAND, LAND, IOR, LOR,
- IXOR, LXOR, IINC, I2L, I2F,
- I2D, L2I, L2F, L2D, F2I,
- F2L, F2D, D2I, D2L, D2F,
- I2B, I2C, I2S, LCMP, FCMPL,
- FCMPG, DCMPL, DCMPG, IFEQ, IFNE,
- IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
- IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
- IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, RET,
- TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN,
- DRETURN, ARETURN, RETURN, GETSTATIC, PUTSTATIC,
- GETFIELD, PUTFIELD, INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC,
- INVOKEINTERFACE, null, NEW, NEWARRAY, ANEWARRAY,
- ARRAYLENGTH, ATHROW, CHECKCAST, INSTANCEOF, MONITORENTER,
- MONITOREXIT, WIDE, MULTIANEWARRAY, IFNULL, IFNONNULL,
- GOTO_W, JSR_W
- };
-
- protected JOpcode(String name,
- int code,
- int size,
- JType[] producedDataTypes,
- JType[] consumedDataTypes,
- int jumpKind) {
- this.name = name;
- this.code = code;
- this.size = size;
- this.producedDataTypes = producedDataTypes;
- this.consumedDataTypes = consumedDataTypes;
- this.jumpKind = jumpKind;
- switch (jumpKind) {
- case JMP_NONE: successorCount = 0; break;
- case JMP_NEXT: successorCount = 1; break;
- case JMP_ALWAYS_S2_OFFSET: successorCount = 1; break;
- case JMP_ALWAYS_S4_OFFSET: successorCount = 1; break;
- case JMP_MAYBE_S2_OFFSET: successorCount = 2; break;
- case JMP_TABLE: successorCount = UNKNOWN; break;
- case JMP_LOOKUP: successorCount = UNKNOWN; break;
- default: successorCount = UNKNOWN; break;
- }
- }
-
- public String toString() { return name; }
- protected int getSize() { return size; }
- protected JType[] getProducedDataTypes() { return producedDataTypes; }
- protected JType[] getConsumedDataTypes() { return consumedDataTypes; }
-
- protected int getProducedDataSize() {
- if (producedDataTypes != UNKNOWN_TYPE)
- return JType.getTotalSize(producedDataTypes);
- else {
- switch (code) {
- case cLDC: case cLDC_W: case cBALOAD:
- return 1;
- case cLDC2_W: case cDUP: case cSWAP:
- return 2;
- case cDUP_X1:
- return 3;
- case cDUP_X2: case cDUP2:
- return 4;
- case cDUP2_X1:
- return 5;
- case cDUP2_X2:
- return 6;
- default:
- throw new Error(this.toString());
- }
- }
- }
-
- protected int getConsumedDataSize() {
- if (consumedDataTypes != UNKNOWN_TYPE)
- return JType.getTotalSize(consumedDataTypes);
- else {
- switch (code) {
- case cPOP: case cDUP:
- return 1;
- case cPOP2: case cDUP_X1: case cDUP2: case cSWAP:
- return 2;
- case cDUP_X2: case cDUP2_X1:
- return 3;
- case cDUP2_X2:
- return 4;
- default:
- throw new Error(this.toString());
- }
- }
- }
-
- protected int getProducedDataTypesNumber() {
- if (producedDataTypes != UNKNOWN_TYPE)
- return producedDataTypes.length;
- else {
- switch (code) {
- case cLDC: case cLDC_W: case cLDC2_W: case cBALOAD:
- case cGETSTATIC: case cGETFIELD:
- return 1;
- case cDUP: case cSWAP:
- return 2;
- case cDUP_X2: case cDUP2: case cDUP2_X1: case cDUP2_X2:
- return 2;
- case cDUP_X1:
- return 3;
- default:
- throw new Error(this.toString());
- }
- }
- }
-
- protected int getConsumedDataTypesNumber() {
- if (consumedDataTypes != UNKNOWN_TYPE)
- return consumedDataTypes.length;
- else {
- switch (code) {
- case cPOP: case cDUP: case cPUTSTATIC:
- return 1;
- case cPUTFIELD: case cDUP_X1: case cDUP_X2:
- case cDUP2: case cDUP2_X1: case cPOP2: case cSWAP:
- return 2;
- default:
- throw new Error(this.toString());
- }
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java
deleted file mode 100644
index 50aa9d3636..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Attributes which are unknown to the JVM (or at least to this library).
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JOtherAttribute extends JAttribute {
- protected final String name;
- protected final byte[] contents;
- protected final int length;
-
- public JOtherAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- byte[] contents,
- int length) {
- super(context, clazz, name);
- this.name = name;
- this.contents = contents;
- this.length = length;
- }
-
- public JOtherAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.name = name;
- this.contents = new byte[size];
- this.length = size;
-
- stream.read(contents, 0, length);
- }
-
- public String getName() { return name; }
-
- // Follows javap output format for user-defined attributes.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" ");
- buf.append(name);
- buf.append(": length = 0x");
- buf.append(Integer.toHexString(length).toUpperCase());
- for (int i = 0; i < length; ++i) {
- if (i % 16 == 0) buf.append("\n ");
- buf.append(hexString(contents[i]));
- buf.append(" ");
- }
- buf.append("\n");
- return buf.toString();
- }
-
- protected int getSize() { return length; }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.write(contents, 0, length);
- }
-
- private static final String hexString(int i) {
- return ((0 <= i && i < 16) ? "0" : "")+Integer.toHexString(i).toUpperCase();
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java b/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java
deleted file mode 100644
index 73d1026c04..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-/**
- * Types for Java references, i.e. arrays and objects.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-abstract public class JReferenceType extends JType {
- public boolean isReferenceType() { return true; }
-
- abstract public String getDescriptor();
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java
deleted file mode 100644
index 3a17cb2c44..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Sourcefile attribute, which can be attached to class files to
- * associate them with their source file.
- *
- * There can be no more than one SourceFile attribute in the attributes table
- * of a given ClassFile structure. See section 4.8.9 of the JVM specification.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class JSourceFileAttribute extends JAttribute {
- protected final String sourceFileName;
- protected final int sourceFileIndex;
-
- public JSourceFileAttribute(FJBGContext context,
- JClass clazz,
- String sourceFileName) {
- super(context, clazz);
- this.sourceFileName = sourceFileName;
- this.sourceFileIndex = clazz.getConstantPool().addUtf8(sourceFileName);
- }
-
- public JSourceFileAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
-
- this.sourceFileIndex = stream.readShort();
- this.sourceFileName = clazz.getConstantPool().lookupUtf8(sourceFileIndex);
-
- assert name.equals(getName());
- }
-
- public String getName() { return "SourceFile"; }
-
- public String getFileName() { return sourceFileName; }
-
- // Follows javap output format for SourceFile attribute.
- /*@Override*/ public String toString() {
- StringBuffer buf = new StringBuffer(" SourceFile: \"");
- buf.append(sourceFileName);
- buf.append("\"\n");
- return buf.toString();
- }
-
- protected int getSize() {
- return 2; // Short.SIZE
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(sourceFileIndex);
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java
deleted file mode 100644
index 72a5484d40..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- *
- * @author Stephane Micheloud
- * @version 1.0
- */
-
-public class JStackMapTableAttribute extends JAttribute {
- /** Constant pool of the current classfile. */
- private JConstantPool pool;
-
- /** StackMapTable entries */
- protected final List/*<Frame>*/ entries = new ArrayList();
- protected int entriesSize = 0;
- protected boolean usesU2;
-
- public JStackMapTableAttribute(FJBGContext context,
- JClass clazz,
- JCode code) {
- super(context, clazz);
- this.pool = clazz.pool;
-
- assert code.getOwner().getOwner() == clazz;
- }
-
- public JStackMapTableAttribute(FJBGContext context,
- JClass clazz,
- Object owner,
- String name,
- int size,
- DataInputStream stream)
- throws IOException {
- super(context, clazz, name);
- this.pool = clazz.pool;
-
- int count = stream.readShort();
- this.usesU2 = count < 65536;
- for (int i = 0; i < count; ++i)
- this.entries.add(new Frame(stream));
- this.entriesSize = computeSize();
-
- assert name.equals(getName());
- }
-
- public String getName() { return "StackMapTable"; }
-
- // Follows javap output format for StackMapTable attribute.
- /*@Override*/ public String toString() {
- Frame frame = null;
- StringBuffer buf = new StringBuffer(" StackMapTable: number_of_entries = ");
- buf.append(entries.size());
- Iterator it = entries.iterator();
- while (it.hasNext()) {
- frame = (Frame)it.next();
- buf.append("\n frame_type = ");
- buf.append(frame.tag);
- buf.append(" /* ");
- buf.append(getFrameType(frame.tag));
- buf.append(" */");
- if (frame.offsetDelta != -1)
- buf.append("\n offset_delta = "+frame.offsetDelta);
- if (frame.locals != null)
- appendTypeInfoArray(buf, "locals", frame.locals);
- if (frame.stackItems != null)
- appendTypeInfoArray(buf, "stack", frame.stackItems);
- }
- buf.append("\n");
- return buf.toString();
- }
-
- protected int getSize() {
- return entriesSize;
- }
-
- protected void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeShort(entriesSize);
- Iterator it = entries.iterator();
- while (it.hasNext()) {
- Frame frame = (Frame)it.next();
- frame.writeContentsTo(stream);
- }
- }
-
- private class TypeInfo {
- final int tag;
- final int poolIndexOrOffset; // tag == 7 => poolIndex, tag = 8 => offset
- private int bytes;
- TypeInfo(DataInputStream stream) throws IOException {
- int size = 1;
- this.tag = stream.readByte();
- if (tag == 7) { // ITEM_Object; // 7
- poolIndexOrOffset = stream.readShort();
- size += 2;
- } else if (tag == 8) { // ITEM_Uninitialized // 8
- poolIndexOrOffset = (usesU2) ? stream.readShort() : stream.readInt();
- size += (usesU2) ? 2 : 4;
- } else
- poolIndexOrOffset = -1;
- this.bytes += size;
- }
- int getSize() { return bytes; }
- void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeByte(tag);
- if (tag == 7) { // ITEM_Object; // 7
- stream.writeShort(poolIndexOrOffset);
- } else if (tag == 8) { // ITEM_Uninitialized // 8
- if (usesU2) stream.writeShort(poolIndexOrOffset);
- else stream.writeInt(poolIndexOrOffset);
- }
- }
- /*@Override*/ public String toString() {
- switch (tag) {
- case 0: // ITEM_Top
- return "<top>";
- case 1: // ITEM_Integer
- return "int";
- case 2: // ITEM_Float
- return "float";
- case 3: // ITEM_Double
- return "double";
- case 4: // ITEM_Long
- return "long";
- case 5: // ITEM_Null
- return "null";
- case 6: // ITEM_UninializedThis
- return "this";
- case 7: // ITEM_Object
- String name = pool.lookupClass(poolIndexOrOffset);
- if (name.startsWith("[")) name = "\""+name+"\"";
- return "class "+name;
- case 8: // ITEM_Uninitialized
- return "<uninitialized>";
- default:
- return String.valueOf(tag);
- }
- }
- }
-
- private class Frame {
- final int tag;
- int offsetDelta = -1;
- TypeInfo[] stackItems = null;
- TypeInfo[] locals = null;
- private int bytes;
- Frame(DataInputStream stream) throws IOException {
- // The stack_map_frame structure consists of a one-byte tag
- // followed by zero or more bytes.
- this.tag = stream.readUnsignedByte();
- if (tag < 64) { // SAME; // 0-63
- //done
- } else if (tag < 128) { // SAME_LOCALS_1_STACK_ITEM; // 64-127
- this.offsetDelta = tag - 64;
- readStackItems(stream, 1);
- } else if (tag < 248) { // reserved for future use.
- assert false : "Tags in the range [128-247] are reserved for future use.";
- } else if (tag < 251) { // CHOP; // 248-250
- int k = 251 - tag;
- readOffsetDelta(stream);
- } else if (tag == 251) { // SAME_FRAME_EXTENDED
- readOffsetDelta(stream);
- } else if (tag < 255) { // APPEND; // 252-254
- readOffsetDelta(stream);
- readLocals(stream, tag - 251);
- } else { // FULL_FRAME; // 255
- readOffsetDelta(stream);
- readLocals(stream);
- readStackItems(stream);
- }
- }
- int getSize() { return bytes; }
- void readOffsetDelta(DataInputStream stream) throws IOException {
- this.offsetDelta = (usesU2) ? stream.readShort() : stream.readInt();
- this.bytes += (usesU2) ? 2 : 4;
- }
- int getOffsetDelta() { return offsetDelta; }
- void readStackItems(DataInputStream stream, int k) throws IOException {
- this.stackItems = new TypeInfo[k];
- for (int i = 0; i < k; ++i) {
- stackItems[i] = new TypeInfo(stream);
- this.bytes += stackItems[i].getSize();
- }
- }
- void readStackItems(DataInputStream stream) throws IOException {
- int k = (usesU2) ? stream.readShort() : stream.readInt();
- this.bytes += (usesU2) ? 2 : 4;
- readStackItems(stream, k);
- }
- void readLocals(DataInputStream stream, int k) throws IOException {
- this.locals = new TypeInfo[k];
- for (int i = 0; i < k; ++i) {
- locals[i] = new TypeInfo(stream);
- this.bytes += locals[i].getSize();
- }
- }
- void readLocals(DataInputStream stream) throws IOException {
- int k = (usesU2) ? stream.readShort() : stream.readInt();
- this.bytes += (usesU2) ? 2 : 4;
- readLocals(stream, k);
- }
- void writeContentsTo(DataOutputStream stream) throws IOException {
- stream.writeByte(tag);
- if (tag < 64) {
- //done
- } else if (tag < 128) { // SAME; // 0-63
- assert stackItems.length == 1;
- stackItems[0].writeContentsTo(stream);
- } else if (tag < 248) {
- assert false : "Tags in the range [128-247] are reserved for future use.";
- } else if (tag < 251) {
- if (usesU2) stream.writeShort(offsetDelta);
- else stream.writeInt(offsetDelta);
- } else if (tag == 251) {
- if (usesU2) stream.writeShort(offsetDelta);
- else stream.writeInt(offsetDelta);
- } else if (tag < 255) { // APPEND; // 252-254
- if (usesU2) stream.writeShort(offsetDelta);
- else stream.writeInt(offsetDelta);
- for (int i = 0; i < locals.length; ++i)
- locals[i].writeContentsTo(stream);
- } else {
- if (usesU2) stream.writeShort(offsetDelta);
- else stream.writeInt(offsetDelta);
- for (int i = 0; i < locals.length; ++i)
- locals[i].writeContentsTo(stream);
- for (int i = 0; i < stackItems.length; ++i)
- stackItems[i].writeContentsTo(stream);
- }
- }
- }
-
- private int computeSize() {
- int size = (usesU2) ? 2 : 4; // number of frames
- Iterator it = entries.iterator();
- while (it.hasNext()) {
- Frame frame = (Frame)it.next();
- size += frame.getSize();
- }
- return size;
- }
-
- private static final String getFrameType(int tag) {
- if (tag < 64) return "same";
- else if (tag < 128) return "same locals 1 stack item";
- else if (tag < 248) return "<reserved>";
- else if (tag < 251) return "chop";
- else if (tag == 251) return "same frame extended";
- else if (tag < 255) return "append";
- else return "full frame";
- }
-
- private static StringBuffer appendTypeInfoArray(StringBuffer buf,
- String s, TypeInfo[] a) {
- buf.append("\n ");
- buf.append(s);
- buf.append(" = ");
- if (a.length > 0) {
- buf.append("[ ");
- for (int i = 0; i < a.length; ++i) {
- if (i > 0) buf.append(", ");
- buf.append(a[i]);
- }
- buf.append(" ]");
- }
- else
- buf.append("[]");
- return buf;
- }
-
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JType.java b/src/fjbg/ch/epfl/lamp/fjbg/JType.java
deleted file mode 100644
index 298a2b0565..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/JType.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-
-/**
- * Representation of Java types.
- *
- * @version 1.0
- * @author Michel Schinz
- */
-
-abstract public class JType {
- abstract public int getSize();
- abstract public String getSignature();
- abstract public int getTag();
- abstract public String toString();
- abstract public boolean isCompatibleWith(JType other);
-
- public boolean isValueType() { return false; }
- public boolean isObjectType() { return false; }
- public boolean isArrayType() { return false; }
- public boolean isReferenceType() { return false; }
-
- // Tags for types. Taken from BCEL.
- public static final int T_BOOLEAN = 4;
- public static final int T_CHAR = 5;
- public static final int T_FLOAT = 6;
- public static final int T_DOUBLE = 7;
- public static final int T_BYTE = 8;
- public static final int T_SHORT = 9;
- public static final int T_INT = 10;
- public static final int T_LONG = 11;
- public static final int T_VOID = 12; // Non-standard
- public static final int T_ARRAY = 13;
- public static final int T_OBJECT = 14;
- public static final int T_UNKNOWN = 15;
- public static final int T_ADDRESS = 16;
-
- public static final int T_REFERENCE = 17; // type compatible with references
-
- public static final JType[] EMPTY_ARRAY = new JType[0];
-
- protected static JType parseSig(StringReader s) throws IOException {
- int nextChar = s.read();
- if (nextChar == -1) throw new IllegalArgumentException();
-
- switch ((char)nextChar) {
- case 'V' : return VOID;
- case 'Z' : return BOOLEAN;
- case 'B' : return BYTE;
- case 'C' : return CHAR;
- case 'S' : return SHORT;
- case 'I' : return INT;
- case 'F' : return FLOAT;
- case 'J' : return LONG;
- case 'D' : return DOUBLE;
- case 'L': {
- StringBuffer className = new StringBuffer();
- for (;;) {
- nextChar = s.read();
- if (nextChar == -1 || nextChar == ';') break;
- className.append(nextChar == '/' ? ':' : ((char)nextChar));
- }
- if (nextChar != ';') throw new IllegalArgumentException();
- return new JObjectType(className.toString());
- }
- case '[': {
- JType elemType = parseSig(s);
- return new JArrayType(elemType);
- }
- case '(': {
- ArrayList argTps = new ArrayList();
- for (;;) {
- s.mark(1);
- nextChar = s.read();
- if (nextChar == -1 || nextChar == ')') break;
- s.reset();
- argTps.add(parseSig(s));
- }
- if (nextChar != ')') throw new IllegalArgumentException("a");
- JType[] argTpsA = (JType[])argTps.toArray(new JType[argTps.size()]);
- JType returnType = parseSig(s);
- return new JMethodType(returnType, argTpsA);
- }
- default:
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * A signature is a string representing the generic type of a field or
- * method, or generic type information for a class declaration.
- * See section 4.4.4 of the JVM specification.
- */
- public static JType parseSignature(String signature) {
- try {
- StringReader sigReader = new StringReader(signature);
- JType parsed = parseSig(sigReader);
- if (sigReader.read() != -1)
- throw new IllegalArgumentException();
- return parsed;
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("invalid signature " + signature);
- } catch (IOException e) {
- throw new Error(e);
- }
- }
-
- public static int getTotalSize(JType[] types) {
- int size = 0;
- for (int i = 0; i < types.length; ++i)
- size += types[i].getSize();
- return size;
- }
-
- protected JType() {}
-
- public static JType VOID = new JType() {
- public int getSize() { return 0; }
- public String getSignature() { return "V"; }
- public int getTag() { return T_VOID; }
- public String toString() { return "void"; }
- public boolean isCompatibleWith(JType other) {
- throw new UnsupportedOperationException("type VOID is no real "
- + "data type therefore "
- + "cannot be assigned to "
- + other.toString());
- }
- };
-
- public static JType BOOLEAN = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "Z"; }
- public int getTag() { return T_BOOLEAN; }
- public String toString() { return "boolean"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == BOOLEAN
- || other == INT
- || other == BYTE
- || other == CHAR
- || other == SHORT;
- }
- };
-
- public static JType BYTE = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "B"; }
- public int getTag() { return T_BYTE; }
- public String toString() { return "byte"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == BOOLEAN
- || other == INT
- || other == BYTE
- || other == CHAR
- || other == SHORT;
- }
- };
-
- public static JType CHAR = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "C"; }
- public int getTag() { return T_CHAR; }
- public String toString() { return "char"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == BOOLEAN
- || other == INT
- || other == BYTE
- || other == CHAR
- || other == SHORT;
- }
- };
-
- public static JType SHORT = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "S"; }
- public int getTag() { return T_SHORT; }
- public String toString() { return "short"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == BOOLEAN
- || other == INT
- || other == BYTE
- || other == CHAR
- || other == SHORT;
- }
- };
-
- public static JType INT = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "I"; }
- public int getTag() { return T_INT; }
- public String toString() { return "int"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == BOOLEAN
- || other == INT
- || other == BYTE
- || other == CHAR
- || other == SHORT;
- }
- };
-
- public static JType FLOAT = new JType() {
- public int getSize() { return 1; }
- public String getSignature() { return "F"; }
- public int getTag() { return T_FLOAT; }
- public String toString() { return "float"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == FLOAT;
- }
- };
-
- public static JType LONG = new JType() {
- public int getSize() { return 2; }
- public String getSignature() { return "J"; }
- public int getTag() { return T_LONG; }
- public String toString() { return "long"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == LONG;
- }
- };
-
- public static JType DOUBLE = new JType() {
- public int getSize() { return 2; }
- public String getSignature() { return "D"; }
- public int getTag() { return T_DOUBLE; }
- public String toString() { return "double"; }
- public boolean isValueType() { return true; }
- public boolean isCompatibleWith(JType other) {
- return other == DOUBLE;
- }
- };
-
- public static JType REFERENCE = new JType() {
- public int getSize() { return 1; }
- public String getSignature() {
- throw new UnsupportedOperationException("type REFERENCE is no real "
- + "data type and therefore "
- + "has no signature");
- }
- public int getTag() { return T_REFERENCE; }
- public String toString() { return "<reference>"; }
- public boolean isCompatibleWith(JType other) {
- throw new UnsupportedOperationException("type REFERENCE is no real "
- + "data type and therefore "
- + "cannot be assigned to "
- + other.toString());
- }
- };
-
- public static JType ADDRESS = new JType() {
- public int getSize() { return 1; }
- public String getSignature() {
- throw new UnsupportedOperationException("type ADDRESS is no usable "
- + "data type and therefore "
- + "has no signature");
- }
- public int getTag() { return T_ADDRESS; }
- public String toString() { return "<address>"; }
- public boolean isCompatibleWith(JType other) {
- return other == ADDRESS;
- }
- };
-
- public static JType UNKNOWN = new JType() {
- public int getSize() {
- throw new UnsupportedOperationException("type UNKNOWN is no real "
- + "data type and therefore "
- + "has no size");
- }
- public String getSignature() {
- throw new UnsupportedOperationException("type UNKNOWN is no real "
- + "data type and therefore "
- + "has no signature");
- }
- public int getTag() { return T_UNKNOWN; }
- public String toString() { return "<unknown>"; }
- public boolean isCompatibleWith(JType other) {
- throw new UnsupportedOperationException("type UNKNOWN is no real "
- + "data type and therefore "
- + "cannot be assigned to "
- + other.toString());
- }
- };
-
- protected static String tagToString(int tag) {
- switch (tag) {
- case T_BOOLEAN : return "boolean";
- case T_CHAR : return "char";
- case T_FLOAT : return "float";
- case T_DOUBLE : return "double";
- case T_BYTE : return "byte";
- case T_SHORT : return "short";
- case T_INT : return "int";
- case T_LONG : return "long";
- case T_VOID : return "void"; // Non-standard
- case T_ARRAY : return "[]";
- case T_OBJECT : return "Object";
- case T_UNKNOWN : return "<unknown>";
- case T_ADDRESS : return "<address>";
- default: return String.valueOf(tag);
- }
- }
-}
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/Main.java b/src/fjbg/ch/epfl/lamp/fjbg/Main.java
deleted file mode 100644
index 810ee7c400..0000000000
--- a/src/fjbg/ch/epfl/lamp/fjbg/Main.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.fjbg;
-
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-
-/**
- * Main program entry to execute the FJBG reader from the command line.
- *
- * The reader prints out the decoded data in the same output format as
- * javap, the Java bytecode disassembler of the Sun J2SE SDK.
- *
- * @author Stephane Micheloud
- * @version 1.1
- */
-
-public class Main {
- private static final String PRODUCT_STRING = "Fast Java Bytecode Generator";
- private static final String VERSION_STRING = "version 1.1";
-
- private static final int ACTION_USAGE = 0;
- private static final int ACTION_DONE = 1;
- private static final int ACTION_PROCEED = 2;
-
- private static String classPath = ".";
- private static String[] classNames = null;
-
- public static void main(String[] args) {
- switch (parseArgs(args)) {
- case ACTION_USAGE: printUsage(); break;
- case ACTION_PROCEED: processClasses(); break;
- default:
- }
- }
-
- private static void processClasses() {
- FJBGContext fjbgContext = new FJBGContext(49, 0);
- if (classNames.length > 0)
- try {
- for (int i = 0; i < classNames.length; ++i)
- processClass(fjbgContext, classNames[i]);
- } catch (IOException e) {
- System.err.println(e.getMessage());
- }
- else
- System.err.println(
- "No classes were specified on the command line. Try -help.");
- }
-
- private static void processClass(FJBGContext fjbgContext, String className)
- throws IOException {
- InputStream in = getInputStream(className);
- JClass jclass = fjbgContext.JClass(new DataInputStream(in));
- System.out.println(jclass);
- in.close();
- }
-
- private static InputStream getInputStream(String className) throws IOException {
- String name = null;
- String[] paths = classPath.split(File.pathSeparator);
- for (int i = 0; i < paths.length; ++i) {
- File parent = new File(paths[i]);
- if (parent.isDirectory()) {
- name = className.replace('.', File.separatorChar)+".class";
- File f = new File(parent, name);
- if (f.isFile()) return new FileInputStream(f);
- } else if (paths[i].endsWith(".jar")) {
- JarFile f = new JarFile(parent);
- name = className.replace('.', '/')+".class";
- ZipEntry e = f.getEntry(name);
- if (e != null) return f.getInputStream(e);
- }
- }
- throw new IOException("ERROR:Could not find "+className);
- }
-
- private static int parseArgs(String[] args) {
- ArrayList/*<String>*/ classes = new ArrayList();
- String arg = null;
- int action = ACTION_USAGE;
- int i = 0, n = args.length;
- while (i < n) {
- arg = args[i];
- if (arg.equals("-classpath") && (i+1) < n) {
- classPath = args[i+1]; i += 2;
- } else if (arg.equals("-cp") && (i+1) < n) {
- classPath = args[i+1]; i += 2;
- } else if (arg.equals("-help")) {
- i = n+1;
- //} else if (arg.equals("-v")) {
- // verbose = true; i += 1;
- } else if (arg.equals("-version")) {
- System.err.println(PRODUCT_STRING+" "+VERSION_STRING);
- action = ACTION_DONE; i = n+1;
- } else if (arg.startsWith("-")) {
- System.err.println("invalid flag: "+arg);
- i = n+1;
- } else {
- classes.add(arg); i += 1;
- }
- }
- if (i == n && i > 0) {
- classNames = (String[])classes.toArray(new String[classes.size()]);
- action = ACTION_PROCEED;
- }
- return action;
- }
-
- private static void printUsage() {
- System.out.println("Usage: fjbg <options> <classes>");
- System.out.println();
- System.out.println("where possible options include:");
- System.out.println(" -cp <path> Specify where to find user class files");
- System.out.println(" -classpath <path> Specify where to find user class files");
- System.out.println(" -help Print a synopsis of standard options");
- System.out.println(" -version Version information");
- System.out.println();
- System.exit(1);
- }
-}
-
diff --git a/src/fjbg/ch/epfl/lamp/util/ByteArray.java b/src/fjbg/ch/epfl/lamp/util/ByteArray.java
deleted file mode 100644
index b852e1ac1f..0000000000
--- a/src/fjbg/ch/epfl/lamp/util/ByteArray.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/* FJBG -- Fast Java Bytecode Generator
- * Copyright 2002-2013 LAMP/EPFL
- * @author Michel Schinz
- */
-
-package ch.epfl.lamp.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Array of bytes.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class ByteArray {
- protected final static int BYTE_BLOCK_BITS = 8;
- protected final static int BYTE_BLOCK_SIZE = 1 << BYTE_BLOCK_BITS;
- protected final static int BYTE_BLOCK_MASK = BYTE_BLOCK_SIZE - 1;
-
- protected byte[][] data = new byte[][] { new byte[BYTE_BLOCK_SIZE] };
- protected int pos = 0; // The next free position.
-
- protected boolean frozen = false;
-
- public ByteArray() { }
-
- public ByteArray(InputStream stream, int size) throws IOException {
- pos = size;
- for (int i = 0; size > 0; ++i) {
- int sizeToRead = Math.min(BYTE_BLOCK_SIZE, size);
- stream.read(data[i], 0, sizeToRead);
-
- size -= sizeToRead;
- if (size > 0) addNewBlock();
- }
- }
-
- public void freeze() { frozen = true; }
-
- public int nextBytePosition() {
- return pos;
- }
-
- public int getSize() {
- return pos;
- }
-
- protected void addNewBlock() {
- int nextBlockPos = pos >>> BYTE_BLOCK_BITS;
- if (nextBlockPos == data.length) {
- byte[][] newData = new byte[data.length * 2][];
- System.arraycopy(data, 0, newData, 0, data.length);
- data = newData;
- }
- assert data[nextBlockPos] == null : pos + " " + nextBlockPos;
- data[nextBlockPos] = new byte[BYTE_BLOCK_SIZE];
- }
-
- protected void addByte(int b) {
- assert !frozen;
-
- if ((pos & BYTE_BLOCK_MASK) == 0 && pos > 0)
- addNewBlock();
- int currPos = pos++;
- data[currPos >>> BYTE_BLOCK_BITS][currPos & BYTE_BLOCK_MASK] = (byte)b;
- }
-
- public void addU1(int i) {
- assert i <= 0xFF : i;
- addByte(i);
- }
-
- public void addU2(int i) {
- assert i <= 0xFFFF : i;
-
- addByte(i >>> 8);
- addByte(i & 0xFF);
- }
-
- public void addU4(int i) {
- addByte(i >>> 24);
- addByte((i >>> 16) & 0xFF);
- addByte((i >>> 8) & 0xFF);
- addByte(i & 0xFF);
- }
-
- public void putByte(int targetPos, int b) {
- assert !frozen;
- assert targetPos < pos : targetPos + " >= " + pos;
-
- data[targetPos >>> BYTE_BLOCK_BITS][targetPos & BYTE_BLOCK_MASK] = (byte)b;
- }
-
- public void putU2(int targetPos, int i) {
- assert i < 0xFFFF : i;
- putByte(targetPos, i >>> 8);
- putByte(targetPos + 1, i & 0xFF);
- }
-
- public void putU4(int targetPos, int i) {
- putByte(targetPos, i >>> 24);
- putByte(targetPos + 1, (i >>> 16) & 0xFF);
- putByte(targetPos + 2, (i >>> 8) & 0xFF);
- putByte(targetPos + 3, i & 0xFF);
- }
-
- public int getU1(int sourcePos) {
- assert sourcePos < pos : sourcePos + " >= " + pos;
- return data[sourcePos >>> BYTE_BLOCK_BITS][sourcePos & BYTE_BLOCK_MASK] & 0xFF;
- }
-
- public int getU2(int sourcePos) {
- return (getU1(sourcePos) << 8) | getU1(sourcePos + 1);
- }
-
- public int getU4(int sourcePos) {
- return (getU2(sourcePos) << 16) | getU2(sourcePos + 2);
- }
-
- public int getS1(int sourcePos) {
- assert sourcePos < pos : sourcePos + " >= " + pos;
- return data[sourcePos >>> BYTE_BLOCK_BITS][sourcePos & BYTE_BLOCK_MASK];
- }
-
- public int getS2(int sourcePos) {
- return (getS1(sourcePos) << 8) | getU1(sourcePos + 1);
- }
-
- public int getS4(int sourcePos) {
- return (getS2(sourcePos) << 16) | getU2(sourcePos + 2);
- }
-
- public void writeTo(OutputStream stream) throws IOException {
- if (!frozen) freeze();
-
- for (int i = 0; i < data.length && data[i] != null; ++i) {
- int len = Math.min(BYTE_BLOCK_SIZE, pos - (i << BYTE_BLOCK_BITS));
- stream.write(data[i], 0, len);
- }
- }
-}
diff --git a/src/intellij/compiler.iml.SAMPLE b/src/intellij/compiler.iml.SAMPLE
index 696c347b7b..f8b1f31327 100644
--- a/src/intellij/compiler.iml.SAMPLE
+++ b/src/intellij/compiler.iml.SAMPLE
@@ -20,8 +20,6 @@
<orderEntry type="module" module-name="library" />
<orderEntry type="module" module-name="reflect" />
<orderEntry type="module" module-name="asm" />
- <orderEntry type="module" module-name="fjbg" />
- <orderEntry type="module" module-name="msil" />
<orderEntry type="library" name="ant" level="application" />
<orderEntry type="library" name="jline" level="project" />
</component>
diff --git a/src/intellij/fjbg.iml.SAMPLE b/src/intellij/fjbg.iml.SAMPLE
deleted file mode 100644
index 03eca69246..0000000000
--- a/src/intellij/fjbg.iml.SAMPLE
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$/../fjbg">
- <sourceFolder url="file://$MODULE_DIR$/../fjbg" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- </component>
-</module>
-
diff --git a/src/intellij/msil.iml.SAMPLE b/src/intellij/msil.iml.SAMPLE
deleted file mode 100644
index 56f794785f..0000000000
--- a/src/intellij/msil.iml.SAMPLE
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="FacetManager">
- <facet type="scala" name="Scala">
- <configuration>
- <option name="compilerLibraryLevel" value="Project" />
- <option name="compilerLibraryName" value="compiler-locker" />
- <option name="maximumHeapSize" value="1536" />
- <option name="vmOptions" value="-Xms1536m -Xss1m -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedOops -XX:+UseParallelGC" />
- </configuration>
- </facet>
- </component>
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$/../msil">
- <sourceFolder url="file://$MODULE_DIR$/../msil" isTestSource="false" />
- <excludeFolder url="file://$MODULE_DIR$/../msil/ch/epfl/lamp/compiler/msil/tests" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="library" />
- </component>
-</module>
-
diff --git a/src/intellij/scala-lang.ipr.SAMPLE b/src/intellij/scala-lang.ipr.SAMPLE
index 37307c2029..a8cb5eacc1 100644
--- a/src/intellij/scala-lang.ipr.SAMPLE
+++ b/src/intellij/scala-lang.ipr.SAMPLE
@@ -198,11 +198,9 @@
<module fileurl="file://$PROJECT_DIR$/actors.iml" filepath="$PROJECT_DIR$/actors.iml" />
<module fileurl="file://$PROJECT_DIR$/asm.iml" filepath="$PROJECT_DIR$/asm.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler.iml" filepath="$PROJECT_DIR$/compiler.iml" />
- <module fileurl="file://$PROJECT_DIR$/fjbg.iml" filepath="$PROJECT_DIR$/fjbg.iml" />
<module fileurl="file://$PROJECT_DIR$/forkjoin.iml" filepath="$PROJECT_DIR$/forkjoin.iml" />
<module fileurl="file://$PROJECT_DIR$/library.iml" filepath="$PROJECT_DIR$/library.iml" />
<module fileurl="file://$PROJECT_DIR$/manual.iml" filepath="$PROJECT_DIR$/manual.iml" />
- <module fileurl="file://$PROJECT_DIR$/msil.iml" filepath="$PROJECT_DIR$/msil.iml" />
<module fileurl="file://$PROJECT_DIR$/partest.iml" filepath="$PROJECT_DIR$/partest.iml" />
<module fileurl="file://$PROJECT_DIR$/reflect.iml" filepath="$PROJECT_DIR$/reflect.iml" />
<module fileurl="file://$PROJECT_DIR$/scala.iml" filepath="$PROJECT_DIR$/scala.iml" />
@@ -230,7 +228,6 @@
<root url="file://$PROJECT_DIR$/../../build/locker/classes/library" />
<root url="file://$PROJECT_DIR$/../../build/locker/classes/compiler" />
<root url="file://$PROJECT_DIR$/../../build/locker/classes/reflect" />
- <root url="file://$PROJECT_DIR$/../../build/libs/classes/fjbg" />
<root url="file://$PROJECT_DIR$/../../build/asm/classes" />
</CLASSES>
<JAVADOC />
diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE
index 112fec428f..3ce369be05 100644
--- a/src/intellij/test.iml.SAMPLE
+++ b/src/intellij/test.iml.SAMPLE
@@ -12,9 +12,7 @@
<orderEntry type="module" module-name="swing" />
<orderEntry type="module" module-name="partest" />
<orderEntry type="module" module-name="asm" />
- <orderEntry type="module" module-name="fjbg" />
<orderEntry type="module" module-name="forkjoin" />
- <orderEntry type="module" module-name="msil" />
</component>
</module>
diff --git a/src/library/scala/SerialVersionUID.scala b/src/library/scala/SerialVersionUID.scala
index 1f7d047060..77094f0bbf 100644
--- a/src/library/scala/SerialVersionUID.scala
+++ b/src/library/scala/SerialVersionUID.scala
@@ -12,4 +12,4 @@ package scala
* Annotation for specifying the `static SerialVersionUID` field
* of a serializable class.
*/
-class SerialVersionUID(uid: Long) extends scala.annotation.StaticAnnotation
+class SerialVersionUID(value: Long) extends scala.annotation.ClassfileAnnotation
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 8be0cb1619..1b5fd6c8d3 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -100,8 +100,8 @@ case class StringContext(parts: String*) {
* ''Note:'' Even when using the raw interpolator, Scala will preprocess unicode escapes.
* For example:
* {{{
- * scala> raw"\u0123"
- * res0: String = ģ
+ * scala> raw"\u005cu0025"
+ * res0: String = #
* }}}
*
* @param `args` The arguments to be inserted into the resulting string.
@@ -191,7 +191,7 @@ object StringContext {
var cur = 0
var idx = 0
def output(ch: Char) = {
- bldr append str.substring (start, cur)
+ bldr.append(str, start, cur)
bldr append ch
start = idx
}
@@ -199,14 +199,15 @@ object StringContext {
cur = idx
if (str(idx) == '\\') {
idx += 1
+ if (idx >= len) throw new InvalidEscapeException(str, cur)
if ('0' <= str(idx) && str(idx) <= '7') {
val leadch = str(idx)
var oct = leadch - '0'
idx += 1
- if ('0' <= str(idx) && str(idx) <= '7') {
+ if (idx < len && '0' <= str(idx) && str(idx) <= '7') {
oct = oct * 8 + str(idx) - '0'
idx += 1
- if (leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
+ if (idx < len && leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
oct = oct * 8 + str(idx) - '0'
idx += 1
}
@@ -234,6 +235,6 @@ object StringContext {
}
}
if (start == 0) str
- else (bldr append str.substring(start, idx)).toString
+ else bldr.append(str, start, idx).toString
}
}
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 723c05a30c..4fead7a50c 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -69,6 +69,11 @@ private[scala] abstract class UniquenessCache[K, V >: Null]
val res = cached()
if (res != null) res
else {
+ // If we don't remove the old String key from the map, we can
+ // wind up with one String as the key and a different String as
+ // as the name field in the Symbol, which can lead to surprising
+ // GC behavior and duplicate Symbols. See SI-6706.
+ map remove name
val sym = valueFromKey(name)
map.put(name, new WeakReference(sym))
sym
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index 603e0b6497..955ebce6bd 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -22,7 +22,7 @@ import scala.math.{ min, max, Ordering }
* Sequences are special cases of iterable collections of class `Iterable`.
* Unlike iterables, sequences always have a defined order of elements.
* Sequences provide a method `apply` for indexing. Indices range from `0` up to the `length` of
- * a sequence. Sequences support a number to find occurrences of elements or subsequences, including
+ * a sequence. Sequences support a number of methods to find occurrences of elements or subsequences, including
* `segmentLength`, `prefixLength`, `indexWhere`, `indexOf`, `lastIndexWhere`, `lastIndexOf`,
* `startsWith`, `endsWith`, `indexOfSlice`.
*
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index 9115b9e5fb..5e6126a7cf 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -10,10 +10,11 @@ package scala.collection
package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
-import Wrappers._
import scala.language.implicitConversions
trait WrapAsJava {
+ import Wrappers._
+
/**
* Implicitly converts a Scala Iterator to a Java Iterator.
* The returned Java Iterator is backed by the provided Scala
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index 5a5d204ece..ffcca62291 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -10,11 +10,13 @@ package scala.collection
package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
-import Wrappers._
import scala.language.implicitConversions
trait LowPriorityWrapAsScala {
this: WrapAsScala =>
+
+ import Wrappers._
+
/**
* Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
* The returned Scala ConcurrentMap is backed by the provided Java
@@ -34,6 +36,7 @@ trait LowPriorityWrapAsScala {
}
trait WrapAsScala extends LowPriorityWrapAsScala {
+ import Wrappers._
/**
* Implicitly converts a Java `Iterator` to a Scala `Iterator`.
*
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index e1aba20fdb..02c10700b1 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -33,7 +33,6 @@ import scala.collection.parallel.immutable.ParRange
* @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#ranges "Scala's Collection Library overview"]]
* section on `Ranges` for more information.
*
- * @define Coll Range
* @define coll range
* @define mayNotTerminateInf
* @define willNotTerminateInf
diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala
index 94242260a1..7ab99fcda2 100644
--- a/src/library/scala/collection/mutable/FlatHashTable.scala
+++ b/src/library/scala/collection/mutable/FlatHashTable.scala
@@ -110,24 +110,23 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] {
/** Finds an entry in the hash table if such an element exists. */
protected def findEntry(elem: A): Option[A] = {
- var h = index(elemHashCode(elem))
- var entry = table(h)
- while (null != entry && entry != elem) {
- h = (h + 1) % table.length
- entry = table(h)
- }
+ val entry = findEntryImpl(elem)
if (null == entry) None else Some(entry.asInstanceOf[A])
}
/** Checks whether an element is contained in the hash table. */
protected def containsEntry(elem: A): Boolean = {
+ null != findEntryImpl(elem)
+ }
+
+ private def findEntryImpl(elem: A): AnyRef = {
var h = index(elemHashCode(elem))
var entry = table(h)
while (null != entry && entry != elem) {
h = (h + 1) % table.length
entry = table(h)
}
- null != entry
+ entry
}
/** Add entry if not yet in table.
diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala
index 183de5b727..fd92d2e555 100644
--- a/src/library/scala/collection/mutable/MutableList.scala
+++ b/src/library/scala/collection/mutable/MutableList.scala
@@ -56,12 +56,16 @@ extends AbstractSeq[A]
/** Returns the rest of this list
*/
override def tail: MutableList[A] = {
- require(nonEmpty, "tail of empty list")
val tl = new MutableList[A]
+ tailImpl(tl)
+ tl
+ }
+
+ protected final def tailImpl(tl: MutableList[A]) {
+ require(nonEmpty, "tail of empty list")
tl.first0 = first0.tail
- tl.last0 = last0
tl.len = len - 1
- tl
+ tl.last0 = if (tl.len == 0) tl.first0 else last0
}
/** Prepends a single element to this list. This operation takes constant
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index 5ea012eb9f..b947fa3cca 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -66,7 +66,7 @@ extends MutableList[A]
else {
val res = first0.elem
first0 = first0.next
- len -= 1
+ decrementLength()
res
}
@@ -82,11 +82,11 @@ extends MutableList[A]
else if (p(first0.elem)) {
val res: Option[A] = Some(first0.elem)
first0 = first0.next
- len -= 1
+ decrementLength()
res
} else {
val optElem = removeFromList(p)
- if (optElem != None) len -= 1
+ if (optElem != None) decrementLength()
optElem
}
@@ -119,7 +119,7 @@ extends MutableList[A]
while ((first0.nonEmpty) && p(first0.elem)) {
res += first0.elem
first0 = first0.next
- len -= 1
+ decrementLength()
}
if (first0.isEmpty) res
else removeAllFromList(p, res)
@@ -130,10 +130,10 @@ extends MutableList[A]
var leftlst = first0
while (leftlst.next.nonEmpty) {
if (p(leftlst.next.elem)) {
- res += leftlst.next.elem
- if (leftlst.next eq last0) last0 = leftlst
- leftlst.next = leftlst.next.next
- len -= 1
+ res += leftlst.next.elem
+ if (leftlst.next eq last0) last0 = leftlst
+ leftlst.next = leftlst.next.next
+ decrementLength()
} else leftlst = leftlst.next
}
res
@@ -154,7 +154,7 @@ extends MutableList[A]
else {
val res: Option[LinkedList[A]] = Some(cell.next)
cell.next = cell.next.next
- len -= 1
+ decrementLength()
res
}
}
@@ -170,11 +170,8 @@ extends MutableList[A]
// TODO - Don't override this just for new to create appropriate type....
override def tail: Queue[A] = {
- require(nonEmpty, "tail of empty list")
val tl = new Queue[A]
- tl.first0 = first0.tail
- tl.last0 = last0
- tl.len = len - 1
+ tailImpl(tl)
tl
}
@@ -183,6 +180,11 @@ extends MutableList[A]
bf ++= seq
bf.result
}
+
+ private[this] def decrementLength() {
+ len -= 1
+ if (len == 0) last0 = first0
+ }
}
diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala
index 24c4cd7a32..2b11594f66 100644
--- a/src/library/scala/util/Random.scala
+++ b/src/library/scala/util/Random.scala
@@ -17,7 +17,7 @@ import scala.language.{implicitConversions, higherKinds}
* @author Stephane Micheloud
*
*/
-class Random(val self: java.util.Random) {
+class Random(val self: java.util.Random) extends AnyRef with Serializable {
/** Creates a new random number generator using a single long seed. */
def this(seed: Long) = this(new java.util.Random(seed))
diff --git a/src/manual/scala/man1/scalac.scala b/src/manual/scala/man1/scalac.scala
index 13b1fd58e0..1c0c7c4a96 100644
--- a/src/manual/scala/man1/scalac.scala
+++ b/src/manual/scala/man1/scalac.scala
@@ -146,13 +146,6 @@ object scalac extends Command {
CmdOption("sourcepath", Argument("path")),
"Specify location(s) of source files."),
Definition(
- CmdOptionBound("target:", Argument("target")),
- SeqPara(
- "Specify which backend to use (" & Mono("jvm-1.5," &
- "msil") & ").",
- "The default value is " & Mono("\"jvm-1.5\"") & " (was " &
- Mono("\"jvm-1.4\"") & " up to Scala version 2.6.1).")),
- Definition(
CmdOption("toolcp", Argument("path")),
"Add to the runner classpath."),
Definition(
@@ -182,19 +175,6 @@ object scalac extends Command {
Section("Advanced Options",
DefinitionList(
Definition(
- CmdOption("Xassem-extdirs", Argument("dirs")),
- "(Requires " & Mono("-target:msil") &
- ") List of directories containing assemblies." &
- " default:" & Mono("lib") & "."),
- Definition(
- CmdOption("Xassem-name", Argument("file")),
- "(Requires " & Mono("-target:msil") &
- ") Name of the output assembly."),
- Definition(
- CmdOption("Xassem-path", Argument("path")),
- "(Requires " & Mono("-target:msil") &
- ") List of assemblies referenced by the program."),
- Definition(
CmdOption("Xcheck-null"),
"Warn upon selection of nullable reference"),
Definition(
@@ -290,10 +270,6 @@ object scalac extends Command {
CmdOption("Xsource-reader", Argument("classname")),
"Specify a custom method for reading source files."),
Definition(
- CmdOption("Xsourcedir", Argument("path")),
- "(Requires " & Mono("-target:msil") &
- ") Mirror source folder structure in output directory.."),
- Definition(
CmdOption("Xverify"),
"Verify generic signatures in generated bytecode."),
Definition(
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java b/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java
deleted file mode 100644
index 59bbeee3a4..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/Assembly.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.Table;
-import ch.epfl.lamp.compiler.msil.util.Table.AssemblyDef;
-import ch.epfl.lamp.compiler.msil.util.Table.ModuleDef;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * Defines an Assembly, which is a reusable, versionable, and self-describing
- * building block of a common language runtime application.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class Assembly extends CustomAttributeProvider {
-
- //##########################################################################
- // static members
-
- // all the assemblies
- public static final HashMap assemblies = new HashMap();
-
- /** Loads an assembly from the specified path. */
- public static Assembly LoadFrom(String assemblyFileName) {
- File afile = new File(assemblyFileName);
- return LoadFrom(afile.getParentFile(), afile.getName());
- }
-
- /** Loads an assembly with the given name from the given directory. */
- public static Assembly LoadFrom(File dir, String name) {
- File file = null;
- PEFile pefile = null;
-// try {
-// if (dir == null)
-// dir = new File(".");
-// dir = dir.getCanonicalFile();
-// } catch (java.io.IOException e) {}
-
- if (name.toUpperCase().endsWith(".EXE") || name.toUpperCase().endsWith(".DLL")) {
- file = new File(dir, name);
- pefile = getPEFile(file);
- name = name.substring(0, name.length() - 4);
- }
-
- File adir = pefile == null ? new File(dir, name) : null;
-
- if (pefile == null) {
- file = new File(dir, name + ".dll");
- pefile = getPEFile(file);
- }
- if (pefile == null) {
- file = new File(dir, name + ".DLL");
- pefile = getPEFile(file);
- }
- if (pefile == null && adir.exists()) {
- file = new File(adir, name + ".dll");
- pefile = getPEFile(file);
- }
- if (pefile == null && adir.exists()) {
- file = new File(adir, name + ".DLL");
- pefile = getPEFile(file);
- }
-
- if (pefile == null) {
- file = new File(dir, name + ".exe");
- pefile = getPEFile(file);
- }
- if (pefile == null) {
- file = new File(dir, name + ".EXE");
- pefile = getPEFile(file);
- }
- if (pefile == null && adir.exists()) {
- file = new File(adir, name + ".exe");
- pefile = getPEFile(file);
- }
- if (pefile == null && adir.exists()) {
- file = new File(adir, name + ".EXE");
- pefile = getPEFile(file);
- }
-
- if (pefile == null)
- throw new RuntimeException("Cannot find assembly " + new File(dir, name));
- return getPEAssembly(pefile);
- }
-
- private static Assembly getPEAssembly(PEFile pefile) {
- AssemblyDef assem = pefile.AssemblyDef;
- if (assem == null)
- throw new RuntimeException("File " + pefile
- + " does not contain a manifest");
- assem.readRow(1);
- String name = pefile.getString(assem.Name);
- Assembly a = (Assembly) assemblies.get(name);
- if (a != null) {
- return a;
- }
-
- AssemblyName an = new AssemblyName();
- an.Name = pefile.getString(assem.Name);
- an.Version = new Version(assem.MajorVersion, assem.MinorVersion,
- assem.BuildNumber, assem.RevisionNumber);
- an.SetPublicKey(pefile.getBlob(assem.PublicKey));
- return new PEAssembly(pefile, an);
- }
-
- protected static PEFile getPEFile(File f) {
- PEFile pefile = null;
- try { pefile = new PEFile(f.getAbsolutePath()); }
- catch (FileNotFoundException e) {}
- catch (RuntimeException e) {
- java.lang.System.out.println("swallowed RuntimeException at getPEFile");
- }
- return pefile;
- }
-
- //##########################################################################
- // public fields
-
- /** The entry point of this assembly. */
- public MethodInfo EntryPoint;
-
- /** the display name of the assembly. */
- public final String FullName;
-
- //##########################################################################
- // constructor
-
- protected Assembly(AssemblyName an, boolean external) {
- assemblyName = an;
- FullName = an.toString();
- if(external) {
- assemblies.put(an.Name, this);
- }
- //System.out.println("assemblies after adding the current one: " + assemblies);
- }
-
- protected Assembly(AssemblyName an) {
- this(an, false);
- }
-
- protected static Assembly getAssembly(String name) {
- return (Assembly) assemblies.get(name);
- }
-
- //##########################################################################
- // instrumental methods
-
- /** @return the file from which this assembly was loaded. */
- public File getFile() {
- throw new RuntimeException("Not supported");
- }
-
- /** Gets the specified module in this assembly. Works on filenames. */
- public Module GetModule(String name) {
- initModules();
- return (Module)modulesMap.get(name);
- }
-
- /** Get all the modules of the assembly. */
- public Module[] GetModules() {
- initModules();
- return (Module[])modulesMap.values().
- toArray(new Module[modulesMap.size()]);
- }
-
- /** Get the corresponding type. */
- public Type GetType(String name) {
- initModules();
- Iterator modules = modulesMap.values().iterator();
- Type t = null;
- while (t == null && modules.hasNext()) {
- t = ((Module)modules.next()).GetType(name);
- }
- return t;
- }
-
- /** @return an array of all types defined in the assembly. */
- public synchronized Type[] GetTypes() {
- if (types != null)
- return (Type[])types.clone();
- initModules();
-
- Iterator modules = modulesMap.values().iterator();
- Type[] newTypes = ((Module)modules.next()).GetTypes();
- while (modules.hasNext()) {
- Module module = (Module)modules.next();
- Type[] mtypes = module.GetTypes();
- Type[] oldTypes = newTypes;
- newTypes = new Type[oldTypes.length + mtypes.length];
- System.arraycopy(oldTypes, 0, newTypes, 0, oldTypes.length);
- System.arraycopy(mtypes, 0, newTypes, oldTypes.length, mtypes.length);
- }
- types = newTypes;
- return (Type[]) types.clone();
- }
-
- public AssemblyName GetName() {
- return assemblyName;
- }
-
- public String toString() {
- return FullName;
- }
-
- //##########################################################################
- // protected members
-
- // the assembly name
- protected final AssemblyName assemblyName;
-
- // all the types exported by the assembly
- protected Type[] types = null;
-
- // the module defined in this assembly (only one right now)
- private final HashMap/*<String, Module>*/ modulesMap = new HashMap();
-
- protected void addType(Type type) {
- Type.addType(type);
- }
-
- protected void addModule(String name, Module module) {
- modulesMap.put(name, module);
- }
-
- private boolean initModules = true;
- protected final void initModules() {
- if (initModules) {
- loadModules();
- initModules = false;
- }
- }
-
- /** used for lazy construction of the Assembly. */
- protected abstract void loadModules();
-
- void dumpTypes() {
- Type[] types = GetTypes();
- for (int i = 0; i < types.length; i++)
- System.out.println(types[i]);
- }
-
- //##########################################################################
-
-} // class Assembly
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/AssemblyName.java b/src/msil/ch/epfl/lamp/compiler/msil/AssemblyName.java
deleted file mode 100644
index acdcb32e33..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/AssemblyName.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import javax.crypto.Mac;
-
-import java.security.MessageDigest;
-
-import ch.epfl.lamp.compiler.msil.util.Table;
-
-/**
- * Fully describes an assembly's unique identity.
- * Right now it's only the name
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class AssemblyName {
-
- //##########################################################################
- // public interface
-
- /** The simple, unencrypted name of the assembly. */
- public String Name;
-
- /**
- * Gets or sets the major, minor, revision, and build numbers
- * of the assembly.
- */
- public Version Version;
-
- /**
- * Gets a strong name consisting of a public key, a given name,
- * and version parts.
- */
- public byte[] GetPublicKeyToken() {
- return publicKeyToken == null ? null : (byte[]) publicKeyToken.clone();
- }
-
- /**
- * Sets a strong name consisting of a public key, a given name,
- * and version parts.
- */
- public void SetPublicKeyToken(byte[] key) {
- this.publicKeyToken = key.length == 0 ? null : (byte[]) key.clone();
- }
-
- /**
- * Returns the public key identifying the originator of the assembly.
- */
- public byte[] GetPublicKey() {
- return publicKey == null ? null : (byte[]) publicKey.clone();
- }
-
- /**
- * Sets the public key identifying the originator of the assembly.
- */
- public void SetPublicKey(byte[] key) {
- if (key.length > 0) {
- this.publicKey = (byte[]) key.clone();
- byte[] hash = sha.digest(key);
- byte[] keyToken = new byte[8];
- for (int i = 0; i < keyToken.length; i++)
- keyToken[i] = hash[hash.length - 1 - i];
- this.publicKeyToken = keyToken;
- //System.out.println("Pubic key and key token of assembly " + this + ":");
- //System.out.println("\tPublic key = " + Table.bytes2hex(key));
- //System.out.println("\tKey token = " + Table.bytes2hex(keyToken));
- }
- }
-
- public String toString() {
- return Name + ", Version=" + Version;
- }
-
- //##########################################################################
-
- private byte[] publicKeyToken;
-
- private byte[] publicKey;
-
- private static final MessageDigest sha;
- static {
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("SHA");
- } catch (java.security.NoSuchAlgorithmException e) {}
- sha = md;
- }
-
- //##########################################################################
-
-} // class AssemblyName
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java b/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java
deleted file mode 100644
index 0f2c4e6764..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.Signature;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Iterator;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Describes custom attribute instances.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class Attribute {
-
- //##########################################################################
-
- private final ConstructorInfo constr;
-
- private final byte[] value;
-
- Attribute(ConstructorInfo constr, byte[] value) {
- assert constr != null;
- this.constr = constr;
- assert value != null : constr.toString();
- this.value = value;
- }
-
- //##########################################################################
- // public interface
-
- /** @return the type (class) of the attribute. */
- public Type GetType() { return constr.DeclaringType; }
-
- /** @return the constructor of this attribute. */
- public ConstructorInfo getConstructor() {
- return constr;
- }
-
- /** @return the Blob with serialized constructor & named arguments. */
- public byte[] getValue() {
- byte[] value = new byte[this.value.length];
- System.arraycopy(this.value, 0, value, 0, value.length);
- return value;
- }
-
- /**@return an array with the arguments to the attribute's constructor. */
- public Object[] getConstructorArguments() {
- parseBlob();
- Object[] cas = new Object[constrArgs.length];
- System.arraycopy(constrArgs, 0, cas, 0, cas.length);
- return cas;
- }
-
- /** @return the named argument with the given name. */
- public NamedArgument getNamedArgument(String name) {
- return (NamedArgument)namedArgs.get(name);
- }
-
- /** @return an array of all named arguments for this attribute. */
- public NamedArgument[] getNamedArguments() {
- NamedArgument[] nargs =
- (NamedArgument[])namedArgs.values().toArray(NamedArgument.EMPTY);
- return nargs;
- }
-
- /** @return a string representation of this attribute. */
- public String toString() {
- parseBlob();
- ParameterInfo[] params = constr.GetParameters();
- assert params.length == constrArgs.length : this.constr;
- StringBuffer str = new StringBuffer();
- str.append('[');
- str.append(constr.DeclaringType.FullName);
- str.append('(');
- for (int i = 0; i < constrArgs.length; i++) {
- if (i > 0)
- str.append(", ");
- Type t = params[i].ParameterType;
- if (t.IsEnum()) {
- str.append('(');
- str.append(t.FullName);
- str.append(')');
- }
- formatValue(str, constrArgs[i]);
- }
- NamedArgument[] nargs = getNamedArguments();
- for (int i = 0; i < nargs.length; i++) {
- str.append(", ").append(nargs[i]);
- }
- str.append(")]");
- return str.toString();
- }
-
- //#########################################################################
-
- private static final Map type2id = new HashMap();
- private static final Map id2type = new HashMap();
- static {
- map("Boolean", Signature.ELEMENT_TYPE_BOOLEAN);
- map("Char", Signature.ELEMENT_TYPE_CHAR);
- map("SByte", Signature.ELEMENT_TYPE_I1);
- map("Byte", Signature.ELEMENT_TYPE_U1);
- map("Int16", Signature.ELEMENT_TYPE_I2);
- map("UInt16", Signature.ELEMENT_TYPE_U2);
- map("Int32", Signature.ELEMENT_TYPE_I4);
- map("UInt32", Signature.ELEMENT_TYPE_U4);
- map("Int64", Signature.ELEMENT_TYPE_I8);
- map("UInt64", Signature.ELEMENT_TYPE_U8);
- map("Single", Signature.ELEMENT_TYPE_R4);
- map("Double", Signature.ELEMENT_TYPE_R8);
- map("String", Signature.ELEMENT_TYPE_STRING);
- map("Type", Signature.X_ELEMENT_TYPE_TYPE);
- map("Object", Signature.ELEMENT_TYPE_OBJECT);
- }
- private static void map(String type, int id) {
- Type t = Type.GetType("System." + type);
- assert type != null : type + " -> " + id;
- Integer i = new Integer(id);
- type2id.put(t, i);
- id2type.put(i, t);
- }
- private static int getTypeId(Type type) {
- Integer id = (Integer)type2id.get(type);
- assert id != null : type;
- return id.intValue();
- }
-
- private Object[] constrArgs;
- private Map namedArgs;
- private ByteBuffer buf;
-
- private void parseBlob() {
- try { parseBlob0(); }
- catch (RuntimeException e) {
- throw new RuntimeException(PEFile.bytes2hex(value), e);
- }
- }
-
- private void parseBlob0() {
- if (buf != null)
- return;
- buf = ByteBuffer.wrap(value); // Sec. 23.3 in Partition II of CLR Spec.
- buf.order(ByteOrder.LITTLE_ENDIAN);
-
- short sig = buf.getShort(); // Prolog
- assert sig == 1 : PEFile.bytes2hex(value);
- ParameterInfo[] params = constr.GetParameters();
- constrArgs = new Object[params.length];
- for (int i = 0; i < params.length; i++) {
- constrArgs[i] = parseFixedArg(params[i].ParameterType); // FixedArg
- }
-
- int ncount = buf.getShort(); // NumNamed
- namedArgs = new LinkedHashMap();
- for (int i = 0; i < ncount; i++) {
- int designator = buf.get(); // designator one of 0x53 (FIELD) or 0x54 (PROPERTY)
- assert designator == Signature.X_ELEMENT_KIND_FIELD
- || designator == Signature.X_ELEMENT_KIND_PROPERTY
- : "0x" + PEFile.byte2hex(designator);
- Type type = parseFieldOrPropTypeInNamedArg(); // FieldOrPropType
- String name = parseString(); // FieldOrPropName
- Object value = parseFixedArg(type); // FixedArg
- NamedArgument narg =
- new NamedArgument(designator, name, type, value);
- namedArgs.put(name, narg);
- }
- }
-
- private Object parseFixedArg(Type type) {
- if (type.IsArray())
- return parseArray(type.GetElementType());
- else
- return parseElem(type);
- }
-
- /* indicates whether the "simple" case (the other is "enum") of the first row
- in the Elem production should be taken. */
- private boolean isSimpleElem(Type type) {
- if(!type2id.containsKey(type)) return false;
- int id = getTypeId(type);
- switch(id){
- case Signature.ELEMENT_TYPE_STRING:
- case Signature.X_ELEMENT_TYPE_TYPE:
- case Signature.ELEMENT_TYPE_OBJECT:
- return false;
- default:
- return true;
- }
- }
-
- /* indicates whether the second row in the Elem production
- should be taken (and more specifically, "string" case within that row). */
- private boolean isStringElem(Type type) {
- if(!type2id.containsKey(type)) return false;
- int id = getTypeId(type);
- return id == Signature.ELEMENT_TYPE_STRING;
- }
-
- /* indicates whether the second row in the Elem production
- should be taken (and more specifically, "type" case within that row). */
- private boolean isTypeElem(Type type) {
- if(!type2id.containsKey(type)) return false;
- int id = getTypeId(type);
- return id == Signature.X_ELEMENT_TYPE_TYPE;
- }
-
- /* indicates whether the third row in the Elem production
- should be taken (and more specifically, "boxed" case within that row). */
- private boolean isSystemObject(Type type) {
- if(!type2id.containsKey(type)) return false;
- int id = getTypeId(type);
- return id == Signature.ELEMENT_TYPE_OBJECT;
- }
-
- private Object parseElem(Type type) {
- // simple or enum
- if (isSimpleElem(type)) return parseVal(getTypeId(type));
- if (type.IsEnum()) return parseVal(getTypeId(type.getUnderlyingType()));
- // string or type
- if (isStringElem(type)) return parseString();
- if (isTypeElem(type)) return getTypeFromSerString();
- // boxed valuetype, please notice that a "simple" boxed valuetype is preceded by 0x51
- if (isSystemObject(type)) {
- Type boxedT = parse0x51();
- if(boxedT.IsEnum()) {
- return new BoxedArgument(boxedT, parseVal(getTypeId(boxedT.getUnderlyingType())));
- } else {
- return new BoxedArgument(boxedT, parseVal(getTypeId(boxedT))); // TODO dead code?
- }
- } else {
- Type boxedT = parseType();
- return parseVal(getTypeId(boxedT));
- }
- }
-
- /* this does not parse an Elem, but a made-up production (Element). Don't read too much into this method name! */
- private Object parseVal(int id) {
- switch (id) {
- case Signature.ELEMENT_TYPE_BOOLEAN:
- return new Boolean(buf.get() == 0 ? false : true);
- case Signature.ELEMENT_TYPE_CHAR:
- return new Character(buf.getChar());
- case Signature.ELEMENT_TYPE_I1:
- case Signature.ELEMENT_TYPE_U1:
- return new Byte(buf.get()); // TODO U1 not the same as I1
- case Signature.ELEMENT_TYPE_I2:
- case Signature.ELEMENT_TYPE_U2:
- return new Short(buf.getShort()); // TODO U2 not the same as I2
- case Signature.ELEMENT_TYPE_I4:
- case Signature.ELEMENT_TYPE_U4:
- return new Integer(buf.getInt()); // TODO U4 not the same as I4
- case Signature.ELEMENT_TYPE_I8:
- case Signature.ELEMENT_TYPE_U8:
- return new Long(buf.getLong()); // TODO U8 not the same as I8
- case Signature.ELEMENT_TYPE_R4:
- return new Float(buf.getFloat());
- case Signature.ELEMENT_TYPE_R8:
- return new Double(buf.getDouble());
- case Signature.X_ELEMENT_TYPE_TYPE:
- return getTypeFromSerString();
- case Signature.ELEMENT_TYPE_STRING:
- return parseString();
- default:
- throw new RuntimeException("Shouldn't have called parseVal with: " + id);
- }
- }
-
- private Object parseArray(Type type) {
- if (type.IsEnum())
- return parseArray(type.getUnderlyingType());
- return parseArray(getTypeId(type));
- }
-
- private Object parseArray(int id) {
- switch (id) {
- case Signature.ELEMENT_TYPE_BOOLEAN:
- return parseBooleanArray();
- case Signature.ELEMENT_TYPE_CHAR:
- return parseCharArray();
- case Signature.ELEMENT_TYPE_I1:
- case Signature.ELEMENT_TYPE_U1: // TODO U1 not the same as I1
- return parseByteArray();
- case Signature.ELEMENT_TYPE_I2:
- case Signature.ELEMENT_TYPE_U2:
- return parseShortArray();
- case Signature.ELEMENT_TYPE_I4:
- case Signature.ELEMENT_TYPE_U4:
- return parseIntArray();
- case Signature.ELEMENT_TYPE_I8:
- case Signature.ELEMENT_TYPE_U8:
- return parseLongArray();
- case Signature.ELEMENT_TYPE_R4:
- return parseFloatArray();
- case Signature.ELEMENT_TYPE_R8:
- return parseDoubleArray();
- case Signature.ELEMENT_TYPE_STRING:
- return parseStringArray();
- case Signature.X_ELEMENT_TYPE_ENUM:
- return parseArray(getTypeFromSerString());
- default:
- throw new RuntimeException("Unknown type id: " + id);
- }
- }
-
- private Type parseType() { // FieldOrPropType, Sec. 23.3 in Partition II of CLR Spec.
- int id = buf.get();
- switch (id) {
- case Signature.ELEMENT_TYPE_SZARRAY:
- Type arrT = Type.mkArray(parseType(), 1);
- return arrT;
- case Signature.X_ELEMENT_TYPE_ENUM:
- String enumName = parseString();
- Type enumT = Type.getType(enumName);
- return enumT;
- default:
- Type t = (Type)id2type.get(new Integer(id));
- assert t != null : PEFile.byte2hex(id);
- return t;
- }
- }
-
- private Type parse0x51() {
- int id = buf.get();
- switch (id) {
- case 0x51:
- return parse0x51();
- case Signature.ELEMENT_TYPE_SZARRAY:
- Type arrT = Type.mkArray(parseType(), 1);
- return arrT;
- case Signature.X_ELEMENT_TYPE_ENUM:
- String enumName = parseString();
- Type enumT = Type.getType(enumName);
- return enumT;
- default:
- Type t = (Type)id2type.get(new Integer(id));
- assert t != null : PEFile.byte2hex(id);
- return t;
- }
- }
-
-
- private Type parseFieldOrPropTypeInNamedArg() { // FieldOrPropType, Sec. 23.3 in Partition II of CLR Spec.
- int id = buf.get();
- switch (id) {
- case 0x51:
- return (Type)(id2type.get(new Integer(Signature.ELEMENT_TYPE_OBJECT)));
- // TODO remove case Signature.ELEMENT_TYPE_SZARRAY:
- // Type arrT = Type.mkArray(parseType(), 1);
- // return arrT;
- case Signature.X_ELEMENT_TYPE_ENUM:
- String enumName = parseString();
- Type enumT = Type.getType(enumName); // TODO this "lookup" only covers already-loaded assemblies.
- return enumT; // TODO null as return value (due to the above) spells trouble later.
- default:
- Type t = (Type)id2type.get(new Integer(id));
- assert t != null : PEFile.byte2hex(id);
- return t;
- }
- }
-
- private Type getTypeFromSerString() {
- String typename = parseString();
- int i = typename.indexOf(',');
- /* fully qualified assembly name follows. Just strip it on the assumption that
- the assembly is referenced in the externs and the type will be found. */
- String name = (i < 0) ? typename : typename.substring(0, i);
- Type t = Type.GetType(name);
- if (t == null && i > 0) {
- int j = typename.indexOf(',', i + 1);
- if (j > 0) {
- String assemName = typename.substring(i + 1, j);
- try {
- Assembly.LoadFrom(assemName);
- } catch (Throwable e) {
- throw new RuntimeException(typename, e);
- }
- t = Type.GetType(name);
- }
- }
- assert t != null : typename;
- return t;
- }
-
- private boolean[] parseBooleanArray() {
- boolean[] arr = new boolean[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.get() == 0 ? false : true;
- return arr;
- }
-
- private char[] parseCharArray() {
- char[] arr = new char[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getChar();
- return arr;
- }
-
- private byte[] parseByteArray() {
- byte[] arr = new byte[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.get();
- return arr;
- }
-
- private short[] parseShortArray() {
- short[] arr = new short[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getShort();
- return arr;
- }
-
- private int[] parseIntArray() {
- int[] arr = new int[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getInt();
- return arr;
- }
-
- private long[] parseLongArray() {
- long[] arr = new long[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getLong();
- return arr;
- }
-
- private float[] parseFloatArray() {
- float[] arr = new float[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getFloat();
- return arr;
- }
-
- private double[] parseDoubleArray() {
- double[] arr = new double[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = buf.getDouble();
- return arr;
- }
-
- private String[] parseStringArray() {
- String[] arr = new String[buf.getInt()];
- for (int i = 0; i < arr.length; i++)
- arr[i] = parseString();
- return arr;
- }
-
- private String parseString() { // SerString convention
- String str = null;
- int length = parseLength();
- if (length < 0)
- return null;
- try { str = new String(value, buf.position(), length, "UTF-8" ); }
- catch (UnsupportedEncodingException e) { throw new Error(e); }
- buf.position(buf.position() + length);
- return str;
- }
-
- private int getByte() {
- return (buf.get() + 0x0100) & 0xff;
- }
-
- public int parseLength() {
- int length = getByte();
- // check for invalid length format: the first, second or third
- // most significant bits should be 0; if all are 1 the length is invalid.
- if ((length & 0xe0) == 0xe0)
- return -1;
- if ((length & 0x80) != 0) {
- length = ((length & 0x7f) << 8) | getByte();
- if ((length & 0x4000) != 0)
- length = ((length & 0x3fff) << 16) | (getByte()<<8) | getByte();
- }
- return length;
- }
-
- //##########################################################################
- private static void formatValue(StringBuffer str, Object o) {
- Class c = (o == null) ? null : o.getClass();
- if (c == null) {
- str.append("<null>");
- } else if (c == String.class) {
- str.append('"');
- str.append(o);
- str.append('"');
- } else if (c == Character.class) {
- str.append('\'');
- str.append(o);
- str.append('\'');
- } else if (c == boolean[].class) {
- str.append("new boolean[] {");
- boolean[] arr = (boolean[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == char[].class) {
- str.append("new short[] {");
- short[] arr = (short[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == byte[].class) {
- str.append("new byte[] {");
- byte[] arr = (byte[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == short[].class) {
- str.append("new short[] {");
- short[] arr = (short[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == int[].class) {
- str.append("new int[] {");
- int[] arr = (int[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == long[].class) {
- str.append("new long[] {");
- long[] arr = (long[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == float[].class) {
- str.append("new float[] {");
- float[] arr = (float[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == double[].class) {
- str.append("new double[] {");
- double[] arr = (double[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- str.append(arr[i]);
- }
- str.append('}');
- } else if (c == String[].class) {
- str.append("new String[] {");
- String[] arr = (String[])o;
- for (int i = 0; i < arr.length; i++) {
- if (i > 0) str.append(", ");
- formatValue(str, arr[i]);
- }
- str.append('}');
- } else if (o instanceof Type) {
- str.append("typeof(");
- str.append(o);
- str.append(")");
- } else
- str.append(o);
- }
-
- //##########################################################################
-
- /** Represents named arguments (assigned outside of the constructor)
- * of a custom attribute
- */
- public static class NamedArgument {
-
- /** Designates if the named argument corresponds to a field or property.
- * Possible values:
- * Signature.X_ELEMENT_KIND_FIELD = 0x53
- * Signature.X_ELEMENT_KIND_PROPERTY = 0x54
- */
- public final int designator;
-
- /** The name of the field/property. */
- public final String name;
-
- /** Type of the field/property. */
- public final Type type;
-
- /** The value for the field/property. */
- public final Object value;
-
- /** An empty array NamedArgument. */
- public static final NamedArgument[] EMPTY = new NamedArgument[0];
-
- public NamedArgument(int designator, String name,Type type,Object value)
- {
- this.designator = designator;
- this.name = name;
- this.type = type;
- this.value = value;
- }
-
- /** @return <b>true</b> if the named argument specifies a field;
- * <b>false<b> otherwise.
- */
- public boolean isField() {
- return designator == Signature.X_ELEMENT_KIND_FIELD;
- }
-
- /** @return <b>true</b> if the named argument specifies a property;
- * <b>false<b> otherwise.
- */
- public boolean isProperty() {
- return designator == Signature.X_ELEMENT_KIND_PROPERTY;
- }
-
- /** @return a string representation of the named argument. */
- public String toString() {
- StringBuffer str = new StringBuffer(name);
- str.append(" = ");
- if (type.IsEnum())
- str.append('(').append(type.FullName).append(')');
- formatValue(str, value);
- return str.toString();
- }
- }
-
- //##########################################################################
-
- public static class BoxedArgument {
- public final Type type;
- public final Object value;
- public BoxedArgument(Type type, Object value) {
- this.type = type; this.value = value;
- }
- public String toString() {
- return "(" + type.FullName + ")" + value;
- }
- }
-
- //##########################################################################
-
-} // class Attribute
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/BindingFlags.java b/src/msil/ch/epfl/lamp/compiler/msil/BindingFlags.java
deleted file mode 100644
index cac2319b50..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/BindingFlags.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Specifies flags that control binding and the way in which
- * the search for members and types is conducted by reflection.
- *
- * Note: You must specify Instance or Static along with Public or NonPublic
- * or no members will be returned.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class BindingFlags {
-
- //##########################################################################
-
- // disallows extending the class;
- private BindingFlags() {}
-
- /**
- * Specifies no binding flag.
- */
- public static final int Default = 0x0000;
-
- /**
- * Specifies that the case of the member name should not be considered
- * when binding.
- */
- public static final int IgnoreCase = 0x0001;
-
- /**
- * Specifies that only members declared at the level of the supplied type's
- * hierarchy should be considered. Inherited members are not considered.
- */
- public static final int DeclaredOnly = 0x0002;
-
- /**
- * Specifies that instance members are to be included in the search.
- */
- public static final int Instance = 0x0004;
-
- /**
- * Specifies that static members are to be included in the search.
- */
- public static final int Static = 0x0008;
-
- /**
- * Specifies that public members are to be included in the search.
- */
- public static final int Public = 0x0010;
-
- /**
- * Specifies that non-public members are to be included in the search.
- */
- public static final int NonPublic = 0x0020;
-
- /**
- * Specifies that static members up the hierarchy should be returned.
- * Static members include fields, methods, events, and properties.
- * Nested types are not returned.
- */
- public static final int FlattenHierarchy = 0x0040;
-
- /**
- * Specifies that a method is to be invoked. This may not be a constructor
- * or a type initializer.
- */
- public static final int InvokeMethod = 0x0100;
-
- /**
- * Specifies that Reflection should create an instance of
- * the specified type. Calls the constructor that matches
- * the given arguments. The supplied member name is ignored.
- * If the type of lookup is not specified, (Instance | Public)
- * will apply. It is not possible to call a type initializer.
- */
- public static final int CreateInstance = 0x0200;
-
- /**
- * Specifies that the value of the specified field should be returned.
- */
- public static final int GetField = 0x0400;
-
- /**
- * Specifies that the value of the specified field should be set.
- */
- public static final int SetField = 0x0800;
-
- /**
- * Specifies that the value of the specified property should be returned.
- */
- public static final int GetProperty = 0x1000;
-
- /**
- * Specifies that the value of the specified property should be set.
- * For COM properties, specifying this binding flag is equivalent to
- * specifying PutDispProperty and PutRefDispProperty.
- */
- public static final int SetProperty = 0x2000;
-
- /**
- * Specifies that the PROPPUT member on a COM object should be invoked.
- * PROPPUT specifies a property-setting function that uses a value.
- * Use PutDispProperty if a property has both PROPPUT and PROPPUTREF
- * and you need to distinguish which one is called.
- */
- public static final int PutDispProperty = 0x4000;
-
-
- /**
- * Specifies that the PROPPUTREF member on a COM object should be invoked.
- * PROPPUTREF specifies a property-setting function that uses a reference
- * instead of a value. Use PutRefDispProperty if a property has both
- * PROPPUT and PROPPUTREF and you need to distinguish which one is called.
- */
- public static final int PutRefDispProperty = 0x8000;
-
- /**
- * Specifies that types of the supplied arguments must exactly match
- * the types of the corresponding formal parameters. Reflection
- * throws an exception if the caller supplies a non-null Binder object,
- * since that implies that the caller is supplying BindToXXX
- * implementations that will pick the appropriate method.
- * Reflection models the accessibility rules of the common type system.
- * For example, if the caller is in the same assembly, the caller
- * does not need special permissions for internal members. Otherwise,
- * the caller needs ReflectionPermission. This is consistent with
- * lookup of members that are protected, private, and so on.
- * The general principle is that ChangeType should perform only
- * widening coercions, which never lose data. An example of a
- * widening coercion is coercing a value that is a 32-bit signed integer
- * to a value that is a 64-bit signed integer. This is distinguished
- * from a narrowing coercion, which may lose data. An example of
- * a narrowing coercion is coercing a 64-bit signed integer to
- * a 32-bit signed integer.
- * The default binder ignores this flag, while custom binders can
- * implement the semantics of this flag.
- */
- public static final int ExactBinding = 0x10000;
-
- /**
- * Used in COM interop to specify that the return value of the member
- * can be ignored.
- */
- public static final int IgnoreReturn = 0x100000 ;
-
- /**
- * Returns the set of members whose parameter count matches the number
- * of supplied arguments. This binding flag is used for methods with
- * parameters that have default values and methods with variable arguments
- * (varargs). This flag should only be used with Type.InvokeMember.
- * Parameters with default values are used only in calls where trailing
- * arguments are omitted. They must be the last arguments.
- */
- public static final int OptionalParamBinding = 0x40000;
-
- /**
- * Not implemented.
- */
- public static final int SuppressChangeType = 0x20000;
-
- //##########################################################################
-
-} // class BindingFlags
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/CallingConventions.java b/src/msil/ch/epfl/lamp/compiler/msil/CallingConventions.java
deleted file mode 100644
index 50bf9fb5d5..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/CallingConventions.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-
-/**
- * Calling conventions
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class CallingConventions {
-
- //########################################################################
-
- /**
- * Specifies the default calling convention as determined by the
- * common language runtime.
- */
- public static final short Standard = (short) 0x0001;
-
- /**
- * Specifies the calling convention for methods with variable arguments.
- */
- public static final short VarArgs = (short) 0x0002;
-
- /**
- * Specifies that either the Standard or the VarArgs calling
- * convention may be used.
- */
- public static final short Any = Standard | VarArgs;
-
- /**
- * Specifies an instance or virtual method (not a static method).
- * At run-time, the called method is passed a pointer to the target
- * object as its first argument (the this pointer). The signature
- * stored in metadata does not include the type of this first argument,
- * because the method is known and its owner class can be discovered
- * from metadata.
- */
- public static final short HasThis = (short) 0x0020;
-
- /**
- * Specifies that the signature is a function-pointer signature,
- * representing a call to an instance or virtual method (not a static
- * method). If ExplicitThis is set, HasThis must also be set. The first
- * argument passed to the called method is still a this pointer, but the
- * type of the first argument is now unknown. Therefore, a token that
- * describes the type (or class) of the this pointer is explicitly stored
- * into its metadata signature.
- */
- public static final short ExplicitThis = (short) 0x0040;
-
- //########################################################################
-
- private CallingConventions() {}
-
- public static String toString(int callConv) {
- StringBuffer s = new StringBuffer();
-
- if ((callConv & HasThis) != 0) {
- s.append("instance");
- if ((callConv & ExplicitThis) != 0)
- s.append(" explicit");
- }
-
- return s.toString();
- }
-
- //##########################################################################
-
-} // class CallingConventions
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/ConstructedType.java b/src/msil/ch/epfl/lamp/compiler/msil/ConstructedType.java
deleted file mode 100644
index 8c82cb4876..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/ConstructedType.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.Arrays;
-
-/* The only reason for ConstructedType to extend Type is complying with existing code
- (e.g., caseFieldBuilder in ILPrinterVisitor) expecting a Type.
- */
-public class ConstructedType extends Type {
-
- public final Type instantiatedType;
- public final Type[] typeArgs;
-
- public ConstructedType(Type instantiatedType, Type[] typeArgs) {
- super(instantiatedType.Module, instantiatedType.Attributes, "", null, null, null, instantiatedType.auxAttr /*AuxAttr.None*/ , null);
- this.instantiatedType = instantiatedType;
- this.typeArgs = typeArgs;
- }
-
- public String toString() {
- String res = instantiatedType.toString() + "[";
- for (int i = 0; i < typeArgs.length; i++) {
- res = res + typeArgs[i].toString();
- if(i + 1 < typeArgs.length) {
- res = res + ", ";
- }
- }
- return res + "]";
- }
-
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- ConstructedType that = (ConstructedType) o;
-
- if (!instantiatedType.equals(that.instantiatedType)) return false;
- if (!Arrays.equals(typeArgs, that.typeArgs)) return false;
-
- return true;
- }
-
- public int hashCode() {
- int result = instantiatedType.hashCode();
- result = 31 * result + Arrays.hashCode(typeArgs);
- return result;
- }
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/ConstructorInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/ConstructorInfo.java
deleted file mode 100644
index 69f5d6d32a..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/ConstructorInfo.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Discovers the attributes of a class constructor and provides
- * access to constructor metadata.
- * ConstructorInfo is used to discover the attributes of a constructor
- * as well as to invoke a constructor. Objects are created by invoking
- * either the GetConstructors or GetConstructor method of a Type object.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class ConstructorInfo extends MethodBase {
- //##########################################################################
-
- public final int MemberType() { return MemberTypes.Constructor; }
-
- public final boolean IsConstructor() { return true; }
-
- protected static final String CTOR = ".ctor";
- protected static final String CCTOR = ".cctor";
- protected static final ConstructorInfo[] EMPTY_ARRAY = new ConstructorInfo[0];
-
- protected static String getName(int attrs) {
- return (attrs & MethodAttributes.Static) == 0 ? CTOR : CCTOR;
- }
-
- /** Public constructors */
-
- public ConstructorInfo(Type declType, int attrs, Type[] paramTypes) {
- super(getName(attrs), declType, attrs, paramTypes);
- assert declType != null : "Owner can't be 'null' for a constructor!";
- }
-
- public ConstructorInfo(Type declType, int attrs, ParameterInfo[] params)
- {
- super(getName(attrs), declType, attrs, params);
- assert declType != null : "Owner can't be 'null' for a constructor!";
- }
-
-
- public String toString() {
- return MethodAttributes.toString(Attributes) + " " + Type.VOID() +
- " " + DeclaringType.FullName + "::" + Name + params2String();
- }
-
- //##########################################################################
-
-} // class ConstructorInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/CustomAttributeProvider.java b/src/msil/ch/epfl/lamp/compiler/msil/CustomAttributeProvider.java
deleted file mode 100644
index 0e58c18114..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/CustomAttributeProvider.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Iterator;
-
-/**
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class CustomAttributeProvider implements ICustomAttributeProvider {
-
- //##########################################################################
-
- protected List/*<Attribute>*/ custAttrs;
- private static final Object[] EMPTY = new Object[0];
-
- //TODO: take inherit into account
- public Object[] GetCustomAttributes(boolean inherit) {
- initAttributes(null);
- return custAttrs.size() == 0 ? EMPTY
- : custAttrs.toArray(new Attribute[custAttrs.size()]);
- }
-
- //TODO: take inherit into account
- public Object[] GetCustomAttributes(Type attributeType, boolean inherit) {
- initAttributes(attributeType);
- List tAttrs = null;
- if (constrType == attributeType)
- tAttrs = custAttrs;
- else {
- tAttrs = new LinkedList();
- for (Iterator attrs = custAttrs.iterator(); attrs.hasNext(); ) {
- Attribute a = (Attribute) attrs.next();
- if (a.GetType() == attributeType) tAttrs.add(a);
- }
- }
- return tAttrs.size() == 0 ? EMPTY
- : tAttrs.toArray(new Attribute[tAttrs.size()]);
- }
-
- //TODO: take inherit into account
- public boolean IsDefined(Type attributeType, boolean inherit) {
- initAttributes(attributeType);
- if (constrType == attributeType)
- return custAttrs.size() > 0;
- Iterator attrs = custAttrs.iterator();
- while (attrs.hasNext()) {
- if (((Attribute)attrs.next()).GetType() == attributeType)
- return true;
- }
- return false;
-// return inherit && (DeclaringClass.BaseType != null)
-// && DeclaringClass.BaseType.IsDefined(inherit);
- }
-
- protected void addCustomAttribute(ConstructorInfo constr, byte[] value) {
- Attribute attr = new Attribute(constr, value);
- assert constrType == null || constrType == attr.GetType();
- if (custAttrs == null)
- custAttrs = new LinkedList();
- custAttrs.add(attr);
- }
-
- private void initAttributes(Type atype) {
- if (custAttrs != null
- && (constrType == null || constrType == atype))
- return;
- custAttrs = new LinkedList();
- constrType = atype;
- loadCustomAttributes(atype);
- }
-
- protected void loadCustomAttributes(Type atype) {}
-
- private Type constrType;
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/CustomModifier.java b/src/msil/ch/epfl/lamp/compiler/msil/CustomModifier.java
deleted file mode 100644
index cf30008c60..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/CustomModifier.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Quoting from the CIL spec, Partition II, Sec. 7.1.1:
- *
- * Custom modifiers, defined using `modreq` (required modifier) and `modopt` (optional modifier), are
- * similar to custom attributes (Sec. 21) except that modifiers are part of a signature rather than being attached to a
- * declaration. Each modifer associates a type reference with an item in the signature.
- *
- */
-public class CustomModifier {
-
- public boolean isReqd;
- public Type marker;
-
- public CustomModifier(boolean isReqd, Type marker) {
- this.isReqd = isReqd;
- this.marker = marker;
- }
-
- public String toString() {
- String res = (isReqd ? "modreq( " : "modopt( ") + marker.toString() + " )";
- return res;
- }
-
- public static Type[] helperCustomMods(boolean isReqd, CustomModifier[] cmods) {
- if(cmods == null) return null;
- int count = 0;
- for (int idx = 0; idx < cmods.length; idx++) {
- if(cmods[idx].isReqd == isReqd) count++;
- }
- Type[] res = new Type[count];
- int residx = 0;
- for (int idx = 0; idx < cmods.length; idx++) {
- res[residx] = cmods[idx].marker;
- residx++;
- }
- return res;
- }
-
- public static Type VolatileMarker() {
- return Type.GetType("System.Runtime.CompilerServices.IsVolatile");
- }
-
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/EventAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/EventAttributes.java
deleted file mode 100644
index a183993cb9..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/EventAttributes.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Specifies flags that describe the attributes of a an event.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class EventAttributes {
-
- //##########################################################################
-
- /** Specifies that the event has no attributes. */
- public static final short None = 0x000;
-
- /** Specifies a reserved flag for CLR use only. */
- public static final short ReservedMask = 0x0400;
-
- /** Specifies that the event is special in a way described by the name. */
- public static final short SpecialName = 0x0200;
-
- /** Specifies the the CLR should check name encoding. */
- public static final short RTSpecialName = 0x0400;
-
- //##########################################################################
-
-} // class EventAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/EventInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/EventInfo.java
deleted file mode 100644
index 3ccba7900b..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/EventInfo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-
-/**
- * Discovers the attributes of an event
- * and provides access to event metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class EventInfo extends MemberInfo {
-
- //##########################################################################
-
- public final int MemberType() { return MemberTypes.Event; }
-
- /** Attributes associated with the event. */
- public final short Attributes;
-
- /** The Type object for the underlying event-handler delegate
- * associated with this event.
- */
- public final Type EventHandlerType;
-
- public MethodInfo GetAddMethod() { return addMethod; }
-
- public MethodInfo GetRemoveMethod() { return removeMethod; }
-
- public String toString() {
- return "" + EventHandlerType + " " + Name;
- }
-
- //##########################################################################
-
- protected static final EventInfo[] EMPTY_ARRAY = new EventInfo[0];
-
- protected MethodInfo addMethod;
-
- protected MethodInfo removeMethod;
-
- protected EventInfo(String name, Type declType, short attr,
- Type handlerType, MethodInfo add, MethodInfo remove)
- {
- super(name, declType);
- Attributes = attr;
- EventHandlerType = handlerType;
- this.addMethod = add;
- this.removeMethod = remove;
- }
-
- //##########################################################################
-
-} // class EventInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/FieldAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/FieldAttributes.java
deleted file mode 100644
index d7d1bb3d54..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/FieldAttributes.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Specifies flags that describe the attributes of a field.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class FieldAttributes {
-
- //##########################################################################
-
- /** Specifies the access level of a given field. */
- public static final short FieldAccessMask = 0x0007;
-
- /** Member not refereneceable. */
- public static final short CompilerControlled = 0x0000;
-
- /** Field is accessible only by the parent type. */
- public static final short Private = 0x0001;
-
- /** Field is accessible only by subtypes in this assembly. */
- public static final short FamANDAssem = 0x0002;
-
- /** Field is accessible throughout the assembly. */
- public static final short Assembly = 0x0003;
-
- /** Field is accessible only by type and subtypes. */
- public static final short Family = 0x0004;
-
- /** Field is accessible by subtypes anywhere,
- * as well as throughout this assembly. */
- public static final short FamORAssem = 0x0005;
-
- /** Specifies that the field is accessible by any member
- * for whom this scope is visible. */
- public static final short Public = 0x0006;
-
- //##########################################################################
- //
-
- /** Field represents the defined type, or else it is per-instance. */
- public static final short Static = 0x0010;
-
- /** Field is initialized only and cannot be written after initialization. */
- public static final short InitOnly = 0x0020;
-
- /** Value is compile-time constant. */
- public static final short Literal = 0x0040;
-
- /** Field does not have to be serialized when the type is remoted. */
- public static final short NotSerialized = 0x0080;
-
- /** Field is special. */
- public static final short SpecialName = 0x0200;
-
- //##########################################################################
- // Interop attributes
-
- /** Implementation is forwarded through PInvoke */
- public static final short PinvokeImpl = 0x2000;
-
-
- //##########################################################################
- // Additional flags
-
- /** CLI provides 'special' behavior depending upon the name of the field */
- public static final short RTSpecialName = 0x0400;
-
- /** Field has marshalling information. */
- public static final short HasFieldMarshal = 0x1000;
-
- /** Field has a default value. */
- public static final short HasDefault = (short)0x8000;
-
- /** Field has a Relative Virtual Address (RVA). The RVA is the location
- * of the method body in the current image, as an address relative
- * to the start of the image file in which it is located. */
- public static final short HasFieldRVA = 0x0100;
-
- //##########################################################################
- //
-
- public static String toString(short attrs) {
- StringBuffer str = new StringBuffer();
- switch (attrs & FieldAccessMask) {
- case CompilerControlled: str.append("compilercontrolled"); break;
- case Private: str.append("private"); break;
- case FamANDAssem: str.append("famandassem"); break;
- case Assembly: str.append("assembly"); break;
- case Family: str.append("family"); break;
- case FamORAssem: str.append("famorassem"); break;
- case Public: str.append("public"); break;
- }
- if ((attrs & Static) != 0) str.append(" static");
- if ((attrs & InitOnly) != 0) str.append(" initonly");
- if ((attrs & Literal) != 0) str.append(" literal");
- if ((attrs & NotSerialized) != 0) str.append(" notserialized");
- if ((attrs & SpecialName) != 0) str.append(" specialname");
- if ((attrs & PinvokeImpl) != 0) str.append("");
- if ((attrs & RTSpecialName) != 0) str.append(" rtspecialname");
- if ((attrs & HasFieldMarshal) != 0) str.append(" marshal(<native type>)");
- //if ((attrs & HasDefault) != 0) str.append(" default(???)");
- return str.toString();
- }
-
- //##########################################################################
-
- // makes the class uninstantiable
- private FieldAttributes() {}
-
- //##########################################################################
-
-} // class FieldAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/FieldInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/FieldInfo.java
deleted file mode 100644
index 536a67e9a8..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/FieldInfo.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.PECustomMod;
-
-/**
- * Discovers the attributes of a field and provides access to field metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class FieldInfo extends MemberInfo implements HasCustomModifiers {
-
- //##########################################################################
- // public interface
-
- public final int MemberType() { return MemberTypes.Field; }
-
- /** Attributes associated with this field. */
- public final short Attributes;
-
- /** Type of the field represented by this FieldInfo object. */
- public final Type FieldType;
-
- /** can be null */
- public final CustomModifier[] cmods;
-
- protected final Object value;
-
- public final boolean IsStatic() {
- return (Attributes & FieldAttributes.Static) != 0;
- }
-
- public final boolean IsInitOnly() {
- return (Attributes & FieldAttributes.InitOnly) != 0;
- }
-
- public final boolean IsLiteral() {
- return (Attributes & FieldAttributes.Literal) != 0;
-
- }
-
- public final boolean IsPublic() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.Public;
- }
-
- public final boolean IsPrivate() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.Private;
- }
-
- public final boolean IsFamily() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.Family;
- }
-
- public final boolean IsAssembly() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.Assembly;
- }
-
- public final boolean IsFamilyOrAssembly() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.FamORAssem;
- }
-
- public final boolean IsFamilyAndAssembly() {
- return (Attributes & FieldAttributes.FieldAccessMask)
- == FieldAttributes.FamANDAssem;
- }
- public final boolean IsSpecialName() {
- return (Attributes & FieldAttributes.SpecialName) != 0;
- }
-
- public final boolean IsPinvokeImpl() {
- return (Attributes & FieldAttributes.PinvokeImpl) != 0;
- }
-
- public final boolean IsNotSerialized() {
- return (Attributes & FieldAttributes.NotSerialized) != 0;
- }
-
- private boolean knownVolatile = false;
- private boolean cachedVolatile = false;
- public final boolean IsVolatile() {
- if(knownVolatile) return cachedVolatile;
- knownVolatile = true;
- if(cmods == null) {
- cachedVolatile = false;
- return cachedVolatile;
- }
- for (int idx = 0; idx < cmods.length; idx++) {
- if(cmods[idx].marker == CustomModifier.VolatileMarker()) {
- cachedVolatile = true;
- return cachedVolatile;
- }
- }
- cachedVolatile = false;
- return cachedVolatile;
- }
-
- public final Type[] GetOptionalCustomModifiers () {
- return CustomModifier.helperCustomMods(false, cmods);
- }
-
- public final Type[] GetRequiredCustomModifiers() {
- return CustomModifier.helperCustomMods(true, cmods);
- }
-
- public String toString() {
- return FieldAttributes.toString(Attributes) + " " +
- FieldType + " " + DeclaringType.FullName + "::" + Name;
- }
-
- //##########################################################################
-
- protected static final FieldInfo[] EMPTY_ARRAY = new FieldInfo[0];
-
- /** Initializes a new instance of the FieldInfo class. */
- protected FieldInfo(String name, Type declType,
- int attrs, PECustomMod fieldTypeWithMods, Object value)
- {
- super(name, declType);
- FieldType = fieldTypeWithMods.marked;
- cmods = fieldTypeWithMods.cmods;
- Attributes = (short) attrs;
- this.value = value;
- }
-
- /**
- */
- public Object getValue() { return value; }
-
- //##########################################################################
-
-} // class FieldInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/GenericParamAndConstraints.java b/src/msil/ch/epfl/lamp/compiler/msil/GenericParamAndConstraints.java
deleted file mode 100644
index 6237fbafee..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/GenericParamAndConstraints.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * @author Miguel Garcia
- */
-public class GenericParamAndConstraints {
-
- public GenericParamAndConstraints(int Number, String Name, Type[] Constraints,
- boolean isInvariant, boolean isCovariant, boolean isContravariant,
- boolean isReferenceType, boolean isValueType, boolean hasDefaultConstructor) {
- this.Number = Number;
- this.Name = Name;
- this.Constraints = Constraints; // TODO representation for the class and new() constraints missing
- this.isInvariant = isInvariant;
- this.isCovariant = isCovariant;
- this.isContravariant = isContravariant;
- this.isReferenceType = isReferenceType;
- this.isValueType = isValueType;
- this.hasDefaultConstructor = hasDefaultConstructor;
-
- }
-
- public final int Number;
- public final String Name; // can be null
- public final Type[] Constraints; // can be empty array
- public final boolean isInvariant; // only relevant for TVars, not for an MVar
- public final boolean isCovariant; // only relevant for TVars, not for an MVar
- public final boolean isContravariant; // only relevant for TVars, not for an MVar
- public final boolean isReferenceType;
- public final boolean isValueType;
- public final boolean hasDefaultConstructor;
-
- public String toString() {
- String res = Name == null ? "<NoName>" : (Name.equals("") ? "<NoName>" : Name);
- res = res + " <: " + Constraints;
- return res;
- }
-
-}
-
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/HasCustomModifiers.java b/src/msil/ch/epfl/lamp/compiler/msil/HasCustomModifiers.java
deleted file mode 100644
index 5ead087350..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/HasCustomModifiers.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package ch.epfl.lamp.compiler.msil;
-
-public interface HasCustomModifiers {
-
- public Type[] GetOptionalCustomModifiers();
-
- public Type[] GetRequiredCustomModifiers();
-
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/ICustomAttributeProvider.java b/src/msil/ch/epfl/lamp/compiler/msil/ICustomAttributeProvider.java
deleted file mode 100644
index 927185962c..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/ICustomAttributeProvider.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Provides custom attributes for reflection objects that support them.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public interface ICustomAttributeProvider {
-
- //##########################################################################
- // interface method definitions
-
- /** Returns an array of all of the custom attributes
- * defined on this member, excluding named attributes,
- * or an empty array if there are no custom attributes.
- *
- * @param inherit - When true, look up the hierarchy chain
- * for the inherited custom attribute.
- * @return - An array of Objects representing custom attributes,
- * or an empty array.
- */
- public Object[] GetCustomAttributes(boolean inherit);
-
-
- /** Returns an array of custom attributes defined on this member,
- * identified by type, or an empty array
- * if there are no custom attributes of that type.
- *
- * @param attributeType - The type of the custom attributes.
- * @param inherit - When true, look up the hierarchy chain
- * for the inherited custom attribute.
- * @return - An array of Objects representing custom attributes,
- * or an empty array.
- */
- public Object[] GetCustomAttributes(Type attributeType, boolean inherit);
-
-
- /** Indicates whether one or more instance of attributeType
- * is defined on this member
- *
- * @param attributeType - The type of the custom attributes
- * @param inherit - When true, look up the hierarchy chain
- * for the inherited custom attribute.
- * @return - true if the attributeType is defined on this member;
- * false otherwise.
- */
- public boolean IsDefined(Type attributeType, boolean inherit);
-
- //##########################################################################
-
-} // interface ICustomAttributeProvider
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MemberInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/MemberInfo.java
deleted file mode 100644
index 65ff1b290b..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MemberInfo.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * The root class of the Reflection hierarchy.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class MemberInfo extends CustomAttributeProvider {
-
- //##########################################################################
-
- /** The name of this member. */
- public final String Name;
-
- /**
- * The class that declares this member.
- * Note: if the MemberInfo object is a global member,
- * (that is, it was obtained from Module.GetMethods,
- * which returns global methods on a module), then DeclaringType
- * will be a null reference.
- */
- public final Type DeclaringType;
-
- /** An enumerated value from the MemberTypes class,
- * specifying a constructor, event, field, method,
- * property, type information, all, or custom. */
- public abstract int MemberType();
-
- //##########################################################################
- // protected members
-
- protected static final MemberInfo[] EMPTY_ARRAY = new MemberInfo[0];
-
- protected MemberInfo(String name, Type declType) {
- Name = name;
- DeclaringType = declType;
- }
-
- //########################################################################
-
-} // class MemberInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MemberTypes.java b/src/msil/ch/epfl/lamp/compiler/msil/MemberTypes.java
deleted file mode 100644
index 5f49ad3323..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MemberTypes.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Marks each type of member that is defined as a derived class of MemberInfo.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class MemberTypes {
-
- //##########################################################################
-
- /** Specifies that the member is a constructor,
- * representing a ConstructorInfo member. */
- public static final int Constructor = 0x01;
-
-
- /** Specifies that the member is an event,
- * representing an EventInfo member. */
- public static final int Event = 0x02;
-
-
- /** Specifies that the member is a field,
- * representing a FieldInfo member. */
- public static final int Field = 0x04;
-
-
- /** Specifies that the member is a method,
- * representing a MethodInfo member. */
- public static final int Method = 0x08;
-
-
- /** Specifies that the member is a property,
- * representing a PropertyInfo member.
- */
- public static final int Property = 0x10;
-
- /** Specifies that the member is a type,
- * representing a TypeInfo member. */
- public static final int TypeInfo = 0x20;
-
-
- /** Specifies that the member is a custom member type. */
- public static final int Custom = 0x40;
-
-
- /** Specifies that the member is a nested type,
- * extending MemberInfo. */
- public static final int NestedType = 0x80;
-
-
- /** Specifies all member types. */
- public static final int All =
- Constructor | Event | Field | Method | Property | TypeInfo | NestedType;
-
-
- public static String toString(int memberType) {
- if ((memberType & Constructor) != 0) return "Constructor";
- if ((memberType & Event) != 0) return "Event";
- if ((memberType & Field) != 0) return "Field";
- if ((memberType & Method) != 0) return "Method";
- if ((memberType & Property) != 0) return "Property";
- if ((memberType & TypeInfo) != 0) return "TypeInfo";
- if ((memberType & Custom) != 0) return "Custom";
- if ((memberType & NestedType) != 0) return "NestedType";
- return "Unknown MemberType: " + memberType;
- }
-
- //##########################################################################
-
- // makes the class uninstantiable
- private MemberTypes() {}
-
- //##########################################################################
-
-} // class MemberTypes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MethodAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/MethodAttributes.java
deleted file mode 100644
index a703c38fb8..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MethodAttributes.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/** Specifies flags for method attributes.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class MethodAttributes {
-
- //##########################################################################
- // Method access attributes
-
- /** Bitmask used to retrieve accessibility information. */
- public static final short MemberAccessMask = 0x0007;
-
- ///** Member not referenceable*/
- //public static final short CompilerConstrolled = 0x0000;
-
- /** Indicates that the member cannot be referenced. */
- public static final short PrivateScope = 0x0000;
-
- /** Method is accessible only by the current class. */
- public static final short Private = 0x0001;
-
- /** Method is accessible to members of this type
- * and its derived types that are in this assembly only. */
- public static final short FamANDAssem = 0x0002;
-
- /** Method is accessible to any class of this assembly. */
- public static final short Assembly = 0x0003;
-
- /** Method is accessible only to members of this class
- * and its derived classes. */
- public static final short Family = 0x0004;
-
- /** Method is accessible to derived classes anywhere,
- * as well as to any class in the assembly. */
- public static final short FamORAssem = 0x0005;
-
- /** Method is accessible to any object for which this object is in scope. */
- public static final short Public = 0x0006;
-
-
- //##########################################################################
- // Flags
-
- /** Method is defined on the type; otherwise, it is defined per instance. */
- public static final short Static = 0x0010;
-
- /** Method cannot be overridden. */
- public static final short Final = 0x0020;
-
- /** Method is virtual. */
- public static final short Virtual = 0x0040;
-
- /** Method hides by name and signature; otherwise, by name only. */
- public static final short HideBySig = 0x0080;
-
-
- //##########################################################################
- // vtable attributes
-
- /** Bitmask used to retrieve vtable attributes. */
- public static final short VtableLayoutMask = 0x0100;
-
- /** Method reuses existing slot in the vtable. */
- public static final short ReuseSlot = 0x0000;
-
-
- /** Method always gets a new slot in the vtable. */
- public static final short NewSlot = 0x0100;
-
-
- //##########################################################################
- // Flags
-
- /** Method does not provide implementation. */
- public static final short Abstract = 0x0400;
-
- /** Method is special. */
- public static final short SpecialName = 0x0800;
-
-
- //##########################################################################
- // Interop attributes
-
- /** Method implementation is forwarded through PInvoke. */
- public static final short PInvokeImpl = 0x2000;
-
- /** Reserved: shall be zero for conforming implementations.
- * Managed method is exported by thunk to unmanaged code. */
- public static final short UnmanagedExport = 0x0008;
-
-
- //##########################################################################
- // Additional flags
-
- /** CLI provides special behavior, depending on the name of the method. */
- public static final short RTSpecialName = 0x1000;
-
- /** Method has security associated with it.
- * Reserved flag for runtime use only.
- */
- public static final short HasSecurity = 0x00000040;
-
- /**
- * Indicates that the method calls another method containing security code.
- * Reserved flag for runtime use only.
- */
- public static final short RequireSecObject = 0x00004000;
-
- /** Indicates a reserved flag for runtime use only. */
- public static final short ReservedMask = 0x0000;
-
-
- //##########################################################################
-
- public static String toString(short attrs) {
- StringBuffer str = new StringBuffer(accessFlagsToString(attrs));
- if ((attrs & Static) != 0) str.append(" static");
- if ((attrs & Final) != 0) str.append(" final");
- if ((attrs & Virtual) != 0) str.append(" virtual");
- if ((attrs & Abstract) != 0) str.append(" abstract");
- if ((attrs & HideBySig) != 0) str.append(" hidebysig");
- if ((attrs & NewSlot) != 0) str.append(" newslot");
- if ((attrs & SpecialName) != 0) str.append(" specialname");
- if ((attrs & PInvokeImpl) != 0) str.append(" pinvokeimpl(?!?)");
- if ((attrs & RTSpecialName) != 0) str.append(" rtspecialname");
- return str.toString();
-
- }
-
- public static String accessFlagsToString(short attrs) {
- switch (attrs & MemberAccessMask) {
- case PrivateScope: return "compilercontrolled";
- case Private: return "private";
- case FamANDAssem: return "famandassem";
- case Assembly: return "assembly";
- case Family: return "family";
- case FamORAssem: return "famorassem";
- case Public: return "public";
- default: return "xxx";
- }
- }
-
- //##########################################################################
-
- // makes the class uninstantiable
- private MethodAttributes() {}
-
- //##########################################################################
-
-} // class Method Attributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MethodBase.java b/src/msil/ch/epfl/lamp/compiler/msil/MethodBase.java
deleted file mode 100644
index fe6404346e..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MethodBase.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.Iterator;
-
-/**
- * The common superclass of MemberInfo and ConstructorInfo
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class MethodBase extends MemberInfo {
-
- //##########################################################################
- // public interface
-
- private java.util.List /* GenericParamAndConstraints */ mVars = new java.util.LinkedList();
- private GenericParamAndConstraints[] sortedMVars = null;
-
- public void addMVar(GenericParamAndConstraints tvarAndConstraints) {
- sortedMVars = null;
- mVars.add(tvarAndConstraints);
- }
-
- public GenericParamAndConstraints[] getSortedMVars() {
- if(sortedMVars == null) {
- sortedMVars = new GenericParamAndConstraints[mVars.size()];
- for (int i = 0; i < sortedMVars.length; i ++){
- Iterator iter = mVars.iterator();
- while(iter.hasNext()) {
- GenericParamAndConstraints tvC = (GenericParamAndConstraints)iter.next();
- if(tvC.Number == i) {
- sortedMVars[i] = tvC;
- }
- }
- }
- }
- return sortedMVars;
- }
-
- public final boolean IsGeneric() {
- return mVars.size() > 0;
- }
-
- /** The attributes associated with this method/constructor. */
- public final short Attributes;
-
- /***/
- public final short CallingConvention;
-
- public abstract boolean IsConstructor();
-
- public final boolean IsAbstract() {
- return (Attributes & MethodAttributes.Abstract) != 0;
- }
-
- public final boolean IsFinal() {
- return (Attributes& MethodAttributes.Final) != 0;
- }
-
- public final boolean IsVirtual() {
- return (Attributes& MethodAttributes.Virtual) != 0;
- }
-
- public final boolean IsInstance() {
- return !IsStatic() && !IsVirtual();
- }
-
- public final boolean IsStatic() {
- return (Attributes & MethodAttributes.Static) != 0;
- }
-
- public final boolean IsHideBySig() {
- return (Attributes & MethodAttributes.HideBySig) != 0;
- }
-
- public final boolean IsSpecialName() {
- return (Attributes & MethodAttributes.SpecialName) != 0;
- }
-
-
- public final boolean IsPublic() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.Public;
- }
-
- public final boolean IsPrivate() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.Private;
- }
-
- public final boolean IsFamily() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.Family;
- }
-
- public final boolean IsAssembly() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.Assembly;
- }
-
- public final boolean IsFamilyOrAssembly() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.FamORAssem;
- }
-
- public final boolean IsFamilyAndAssembly() {
- return (Attributes & MethodAttributes.MemberAccessMask)
- == MethodAttributes.FamANDAssem;
- }
-
- public boolean HasPtrParamOrRetType() {
- // the override in MethodInfo checks the return type
- ParameterInfo[] ps = GetParameters();
- for (int i = 0; i < ps.length; i++) {
- Type pT = ps[i].ParameterType;
- if(pT.IsPointer()) {
- // Type.mkPtr creates a msil.Type for a pointer type
- return true;
- }
- if(pT.IsByRef() && !pT.GetElementType().CanBeTakenAddressOf()) {
- /* TODO Cases where GenMSIL (so far) con't emit good bytecode:
- the type being taken address of IsArray(), IsGeneric(), or IsTMVarUsage.
- For example, System.Enum declares
- public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct, new();
- */
- return true;
- }
- }
- return false;
- }
-
- /** Returns the parameters of the method/constructor. */
- public ParameterInfo[] GetParameters() {
- return (ParameterInfo[]) params.clone();
- }
-
- public int GetMethodImplementationFlags() { return implAttributes; }
-
- //##########################################################################
-
- /** Method parameters. */
- protected ParameterInfo[] params;
-
- protected short implAttributes;
-
- protected MethodBase(String name, Type declType, int attrs, Type[] paramTypes)
- {
- this(name, declType, attrs);
- assert paramTypes != null;
- params = new ParameterInfo[paramTypes.length];
- for (int i = 0; i < params.length; i++)
- params[i] = new ParameterInfo(null, paramTypes[i], 0, i);
- }
-
- protected MethodBase(String name, Type declType, int attrs,
- ParameterInfo[] params)
- {
- this(name, declType, attrs);
- this.params = params;
- }
-
- /**
- */
- private MethodBase(String name, Type declType, int attrs) {
- super(name, declType);
-
- Attributes = (short) attrs;
-
- if (IsConstructor()) {
- attrs |= MethodAttributes.SpecialName;
- attrs |= MethodAttributes.RTSpecialName;
- }
-
- CallingConvention = (short) (CallingConventions.Standard
- | (IsStatic() ? (short)0 : CallingConventions.HasThis));
- }
-
- //##########################################################################
- // internal methods
-
- protected String params2String() {
- StringBuffer s = new StringBuffer("(");
- for (int i = 0; i < params.length; i++) {
- if (i > 0) s.append(", ");
- s.append(params[i].ParameterType);
- }
- s.append(")");
- return s.toString();
- }
-
- //##########################################################################
-
-} // class MethodBase
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MethodImplAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/MethodImplAttributes.java
deleted file mode 100644
index 8e8d879593..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MethodImplAttributes.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Method implementation attributes
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class MethodImplAttributes {
-
- //##########################################################################
-
- /**
- * Specifies flags about code type. 3
- */
- public static final short CodeTypeMask = (short) 0x0003;
-
- /**
- * Specifies that the method implementation is in MSIL. 0
- */
- public static final short IL = (short) 0x0000;
-
- /**
- * Specifies that the method implementation is native. 1
- */
- public static final short Native = (short) 0x0001;
-
- /**
- * This member supports the .NET Framework infrastructure and
- * is not intended to be used directly from your code. 2
- */
- public static final short OPTIL = (short) 0x0002;
-
- /**
- * Specifies that the method implementation is provided by the runtime. 3
- */
- public static final short Runtime = (short) 0x0003;
-
-
-
- /**
- * Specifies whether the code is managed or unmanaged. 4
- */
- public static final short ManagedMask = (short) 0x0004;
-
- /**
- * Specifies that the method implementation is managed, otherwise unmanaged.
- */
- public static final short Managed = (short) 0x0000;
-
- /**
- * Specifies that the method implementation is unmanaged, otherwise managed.
- */
- public static final short Unmanaged = (short) 0x0004;
-
-
-
- /**
- * Specifies that the method cannot be inlined. 8
- */
- public static final short NoInlining = (short) 0x0008;
-
- /**
- * Specifies that the method is not defined. 16
- */
- public static final short ForwardRef = (short) 0x0010;
-
- /**
- * Specifies that the method is single-threaded through the body.
- * You can also use the C# lock statement or the Visual Basic
- * Lock function for this purpose. 32
- */
- public static final short Synchronized = (short) 0x0020;
-
- /**
- * Specifies that the method signature is exported exactly as declared. 128
- */
- public static final short PreserveSig = (short) 0x0080;
-
- /**
- * Specifies an internal call. 4096
- */
- public static final short InternalCall = (short) 0x1000;
-
- /**
- * Specifies a range check value. 65535
- */
- public static final short MaxMethodImplVal = (short) 0xffff;
-
- //##########################################################################
-
- public static String toString(int implAttr) {
- StringBuffer s = new StringBuffer();
- switch (implAttr & CodeTypeMask) {
- case IL: s.append("cil"); break;
- case Native: s.append("native"); break;
- case Runtime: s.append("runtime"); break;
- }
- switch (implAttr & ManagedMask) {
- case Managed: s.append(" managed"); break;
- case Unmanaged: s.append(" unmanaged"); break;
- }
- if ((implAttr & NoInlining) != 0) s.append(" noinlining");
- if ((implAttr & ForwardRef) != 0) s.append(" forwardref");
- if ((implAttr & Synchronized) != 0) s.append(" synchronized");
- if ((implAttr & InternalCall) != 0) s.append(" internalcall");
- return s.toString();
- }
-
- //##########################################################################
-
-} // class MethodImplAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/MethodInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/MethodInfo.java
deleted file mode 100644
index a415e7551f..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/MethodInfo.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.Iterator;
-
-/**
- * Discovers the attributes of a method and provides access to method metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class MethodInfo extends MethodBase {
-
- public boolean HasPtrParamOrRetType() {
- if(ReturnType.IsByRef() && !(ReturnType.GetElementType().IsValueType())) {
- /* A method returning ByRef won't pass peverify, so I guess this is dead code. */
- return true;
- }
- if(ReturnType.IsPointer()) {
- return true;
- }
- return super.HasPtrParamOrRetType();
- }
-
- //##########################################################################
- // public members
-
- public final int MemberType() { return MemberTypes.Method; }
-
- public final boolean IsConstructor() { return false; }
-
- /** The return type of this method.
- */
- public final Type ReturnType;
-
- //##########################################################################
- // protected members
-
- protected static final MethodInfo[] EMPTY_ARRAY = new MethodInfo[0];
-
- /**
- * Constructor Initializes a new instance of the MethodInfo class.
- */
- protected MethodInfo(String name, Type declType,
- int attrs, Type returnType, Type[] paramTypes )
- {
- super(name, declType, attrs, paramTypes);
- ReturnType = returnType;
- }
-
- protected MethodInfo(String name, Type declType,
- int attrs, Type returnType, ParameterInfo[] params )
- {
- super(name, declType, attrs, params);
- ReturnType = returnType;
- }
-
- public String toString() {
- return MethodAttributes.toString(Attributes) + " " + ReturnType +
- " " + DeclaringType + "::" + Name + params2String();
- }
-
- //##########################################################################
-
-} // class MethodInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Module.java b/src/msil/ch/epfl/lamp/compiler/msil/Module.java
deleted file mode 100644
index 8dd5e7119f..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/Module.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Defines and represents a module. Get an instance of ModuleBuilder
- * by calling DefineDynamicModule
- * A module is a portable executable file of type .dll or .exe consisting
- * of one or more classes and interfaces. There may be multiple namespaces
- * contained in a single module, and a namespace may span multiple modules.
- * One or more modules deployed as a unit compose an assembly.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class Module extends CustomAttributeProvider {
-
- //##########################################################################
- // public fields
-
- /** String representing the name of the module with the path removed. */
- public final String Name;
-
- /** String representing the fully qualified name and path to this module. */
- public final String FullyQualifiedName;
-
- /** String representing the name of the module. */
- public String ScopeName;
-
- /** The Assembly the Module belongs to. */
- public final Assembly Assembly;
-
- //##########################################################################
- // constructor
-
- protected Module(String name, String filename,
- String scopeName, Assembly assembly)
- {
- this.Name = name;
- this.FullyQualifiedName = filename;
- this.ScopeName = scopeName;
- this.Assembly = assembly;
- }
-
- //##########################################################################
- // public methods
-
- /** Returns the specified class, performing a case-sensitive search. */
- public Type GetType(String name) {
- initTypes();
- return (Type) typesMap.get(name);
- }
-
- /**
- * @return all the classes defined within this module.
- */
- public Type[] GetTypes() {
- initTypes();
- return (Type[]) types.clone();
- }
-
- /**
- * @return the global field with the specified name.
- */
- public FieldInfo GetField(String name) {
- for (int i = 0; i < fields.length; i++)
- if (fields[i].Name.equals(name))
- return fields[i];
- return null;
- }
-
- /**
- * @return an array of the global fields of the module
- */
- public FieldInfo[] GetFields() {
- return (FieldInfo[]) fields.clone();
- }
-
- /**
- * @return - the global method with the specified name
- */
- public MethodInfo GetMethod(String name) {
- for (int i = 0; i < methods.length; i++)
- if (methods[i].Name.equals(name))
- return methods[i];
- return null;
- }
-
- /**
- * @return - an array of all the global methods defined in this modules.
- */
- public MethodInfo[] GetMethods() {
- return (MethodInfo[]) methods.clone();
- }
-
- /**
- */
- public String toString() { return Name; }
-
- //########################################################################
- // protected members
-
- // all the types defined in this module
- protected final Map typesMap = new HashMap();
-
- // all the types defined in this module
- protected Type[] types;
-
- // the global fields of the module
- protected FieldInfo[] fields = FieldInfo.EMPTY_ARRAY;
-
- // the global methods of the module
- protected MethodInfo[] methods = MethodInfo.EMPTY_ARRAY;
-
- protected Type addType(Type type) {
- addType(type.FullName, type);
- Assembly.addType(type);
- return type;
- }
-
- protected Type addType(String name, Type type) {
- assert type!= null;
- typesMap.put(name, type);
- return type;
- }
-
- private boolean initTypes = true;
- protected final void initTypes() {
- if (initTypes) {
- loadTypes();
- initTypes = false;
- }
- }
-
- protected void loadTypes() {}
-
- private boolean initGlobals = true;
- protected final void initGlobals() {
- if (initGlobals) {
- loadGlobals();
- initGlobals = false;
- }
- }
-
- protected void loadGlobals() {}
-
- //##########################################################################
-
-} // class Module
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PEAssembly.java b/src/msil/ch/epfl/lamp/compiler/msil/PEAssembly.java
deleted file mode 100644
index a31db16c92..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PEAssembly.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.Table;
-import ch.epfl.lamp.compiler.msil.util.Table.*;
-
-import java.io.File;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/** Represents an assembly that resides in a real .NET assembly
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-final class PEAssembly extends Assembly {
-
- private final PEFile pefile;
-
- private PEModule mainModule;
-
- public PEAssembly(PEFile pefile, AssemblyName an) {
- super(an, true);
- this.pefile = pefile;
- String name = pefile.ModuleDef(1).getName();
- mainModule = new PEModule(pefile, 1, name, this);
- addModule(name, mainModule);
- //initModules();
- }
-
- protected void loadModules() {
- File parentDir = pefile.getParentFile();
- FileDef fd = pefile.FileDef;
- for (int row = 1; row <= fd.rows; row++) {
- fd.readRow(row);
- String filename = fd.getName();
- File f = new File(parentDir, filename);
- PEFile pe = Assembly.getPEFile(f);
- if (pe == null) {
- f = new File(filename);
- pe = Assembly.getPEFile(f);
- if (pe == null)
- continue;
-// throw new RuntimeException("Cannot find file " + filename +
-// " referenced by assembly " + this);
- }
- String name = pe.ModuleDef(1).getName();
- PEModule module = new PEModule(pe, 1, name, this);
- addModule(name, module);
- }
- }
-
- public File getFile() {
- return pefile.getUnderlyingFile();
- }
-
- protected void loadCustomAttributes(Type attributeType) {
- initModules();
- mainModule.initAttributes(this, 1, Table.AssemblyDef.ID, attributeType);
- }
-
- //##########################################################################
-
-} // class PEAssembly
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java b/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java
deleted file mode 100644
index 3eb22b9985..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PEFile.java
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.*;
-import ch.epfl.lamp.compiler.msil.util.Table.*;
-
-import ch.epfl.lamp.compiler.msil.Type;
-import ch.epfl.lamp.compiler.msil.Module;
-
-import java.io.File;
-import java.io.RandomAccessFile;
-import java.io.PrintStream;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.MappedByteBuffer;
-
-import java.util.Date;
-
-/**
- * A class that represents a .NET PE/COFF image.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- * @see <a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm">Standard ECMA-335: Common Language Infrastructure (CLI), 4th edition (June 2006)</a>
- */
-public class PEFile {
-
- //##########################################################################
-
- public static final int INT_SIZE = 4;
-
- protected final int PE_SIGNATURE_OFFSET;
- protected final int COFF_HEADER_OFFSET;
- protected final int PE_HEADER_OFFSET;
-
- protected final int numOfSections;
- protected final int CLI_RVA;
- protected final int CLI_Length;
- public final int rvaMetadata;
- public final int posMetadata;
- protected final int numOfStreams;
- protected final int optHeaderSize;
-
- protected final File underlyingFile;
- protected final RandomAccessFile file;
- protected final MappedByteBuffer buf;
-
- protected final PESection [] sections;
-
- public PEStream Meta, Strings, US, Blob, GUID;
-
- private final Table [] tables = new Table[Table.MAX_NUMBER];
-
- public final boolean isDLL;
-
- protected final int heapSizes;
- public final boolean StringIsShort, BlobIsShort, GUIDIsShort;
-
- protected PEModule pemodule = null;
-
- //##########################################################################
- // PEFile constructor
-
- private static void fileFormatCheck(boolean cond, String s) {
- if (cond)
- throw new RuntimeException(s);
- }
-
- /**
- */
- public PEFile(String filename) throws FileNotFoundException {
- this.underlyingFile = new File(filename);
- this.file = new RandomAccessFile(underlyingFile, "r");
- FileChannel fc = file.getChannel();
- MappedByteBuffer bb = null;
- try {
- bb = fc.map(FileChannel.MapMode.READ_ONLY, 0L, fc.size());
- } catch (IOException e) { throw new RuntimeException(e); }
-
- /** Ecma 335, 25 File format extensions to PE:
- *
- * "Unless stated otherwise, all binary values are stored in little-endian format."
- */
-
- bb.order(java.nio.ByteOrder.LITTLE_ENDIAN);
- this.buf = bb;
-
- /** Ecma 335, 25.2.1 MS-DOS header:
- *
- * "The PE format starts with an MS-DOS stub of exactly the following 128 bytes to
- * be placed at the front of the module."
- *
- * We are only checking for MZ (Mark Zbikowski)
- */
-
- seek(0);
- fileFormatCheck(readByte() != 0x4d, "Invalid PE file format: " + filename); // 'M'
- fileFormatCheck(readByte() != 0x5a, "Invalid PE file format: " + filename); // 'Z'
-
- /** Ecma 335, 25.2.1 MS-DOS header:
- *
- * "At offset 0x3c in the DOS header is a 4-byte unsigned integer offset, lfanew,
- * to the PE signature (shall be "PE\0\0"), immediately followed by the PE file header."
- */
-
- seek(0x3c);
- PE_SIGNATURE_OFFSET = readInt();
- seek(PE_SIGNATURE_OFFSET);
- // start of PE signature (a signature that is just 4 bytes long)
- fileFormatCheck(readByte() != 0x50, "Invalid PE file format: " + filename); // 'P'
- fileFormatCheck(readByte() != 0x45, "Invalid PE file format: " + filename); // 'E'
- fileFormatCheck(readByte() != 0x00, "Invalid PE file format: " + filename); // 0
- fileFormatCheck(readByte() != 0x00, "Invalid PE file format: " + filename); // 0
-
- //trace("PE signature offset = 0x" + Table.int2hex(PE_SIGNATURE_OFFSET));
-
- COFF_HEADER_OFFSET = PE_SIGNATURE_OFFSET + 4;
- PE_HEADER_OFFSET = COFF_HEADER_OFFSET + 20;
-
- seek(COFF_HEADER_OFFSET);
-
- /* start of PE file header, Sec. 25.2.2 in Partition II */
- skip(2); // Machine (always 0x14c)
- numOfSections = readShort(); // Number of sections; indicates size of the Section Table
- Date timeStamp = new Date(readInt() * 1000L);
- skip(2 * INT_SIZE); // skip Pointer to Symbol Table (always 0) and Number of Symbols (always 0)
- optHeaderSize = readShort();
- int characteristics = readShort();
- isDLL = (characteristics & 0x2000) != 0;
-
- seek(PE_HEADER_OFFSET + 208); // p.157, Partition II
-
- CLI_RVA = readInt(); // called "Data Directory Table" in Ch. 4 of Expert IL book
- CLI_Length = readInt();
- //trace("CLI_RVA = 0x" + Table.int2hex(CLI_RVA));
- //trace("CLI_Length = 0x" + Table.int2hex(CLI_Length));
-
- sections = new PESection[numOfSections];
-
- seek(PE_HEADER_OFFSET + optHeaderSize); // go to the sections descriptors
-
- for (int i = 0; i < numOfSections; i++) {
- seek(PE_HEADER_OFFSET + optHeaderSize + i * 40);
- sections[i] = new PESection(this);
- //sections[i].dump(System.out);
- }
-
- seek(fromRVA(CLI_RVA));
- skip(8);
- rvaMetadata = readInt();
- posMetadata = fromRVA(rvaMetadata);
- //trace("rvaMetadata = 0x" + Table.int2hex(rvaMetadata));
- //trace("posMetadata = 0x" + Table.int2hex(posMetadata));
-
- seek(posMetadata);
- int magic = readInt();
- //trace("Magic metadata signature = 0x" + Table.int2hex(magic));
- fileFormatCheck(magic != 0x424a5342, "Invalid metadata signature!");
- skip(8);
-
- int strlength = readInt();
- //trace("version name string length = " + strlength);
- skip(strlength);
- align(INT_SIZE, posMetadata);
- //trace("position of flags = 0x" + Table.int2hex((int)pos()));
- skip(2); // ignore the flags
- numOfStreams = readShort();
- //trace("Number of metadata streams = " + numOfStreams);
-
- for (int i = 0; i < numOfStreams; i++) {
- PEStream strm = new PEStream(this);
- //strm.dump(System.out);
- if (strm.name.equals("#~")
- || strm.name.equals("#-")) Meta = strm;
- if (strm.name.equals("#Strings")) Strings = strm;
- if (strm.name.equals("#US")) US = strm;
- if (strm.name.equals("#Blob")) Blob = strm;
- if (strm.name.equals("#GUID")) GUID = strm;
- }
-
- seek(Meta.offset);
- skip(6);
- heapSizes = readByte();
- StringIsShort = (heapSizes & 0x01) == 0;
- GUIDIsShort = (heapSizes & 0x02) == 0;
- BlobIsShort = (heapSizes & 0x04) == 0;
-
- skip(1);
- long tablesMask = readLong();
- long nonStandardTables = tablesMask & ~Table.VALID_TABLES_MASK;
- skip(8); //go to the list of number of rows
- for (int i = 0; i < tables.length; i++) {
- tables[i] = Table.newTable
- (this, i, ((tablesMask >> i) & 0x01) != 0 ? readInt() : 0);
- }
-
- initIndexSize();
- initTableRefs();
- // populate the tables from the CLI image file
- long start = pos();
- for (int i = 0; i < tables.length; i++)
- start = tables[i].init(start);
-
- } // PEFile()
-
-
- public final int[] indexSize = new int[Table.TABLE_SET_LENGTH];
-
- private void initIndexSize() {
- for (int i = 0; i < Table.TABLE_SET_LENGTH; i++) {
- indexSize[i] = 2;
- int[] tableSet = Table.TableSet[i];
- int treshold = (65536 >> Table.NoBits[i]);
- for (int j = 0; j < tableSet.length; j++) {
- if (tableSet[j] >= 0) {
- Table t = tables[tableSet[j]];
- if (t.rows >= treshold) {
- indexSize[i] = 4;
- break;
- }
- }
- }
- }
- }
-
- protected void initModule(PEModule module) {
- if (pemodule != null)
- throw new RuntimeException("File " + this
- + " has already been assigned module "
- + pemodule + "; new module is " + module);
- this.pemodule = module;
- }
-
- //##########################################################################
-
- public ModuleDef ModuleDef;
- public ModuleDef ModuleDef(int i) {
- ModuleDef.readRow(i);
- return ModuleDef;
- }
-
- public TypeRef TypeRef;
-
- public TypeDef TypeDef;
- public TypeDef TypeDef(int i) {
- TypeDef.readRow(i);
- return TypeDef;
- }
-
- public FieldTrans FieldTrans;
- public FieldTrans FieldTrans(int i) {
- FieldTrans.readRow(i);
- return FieldTrans;
- }
-
- public FieldDef FieldDef;
- public FieldDef FieldDef(int i) {
- FieldDef.readRow(i);
- return FieldDef;
- }
-
- public MethodTrans MethodTrans;
- public MethodTrans MethodTrans(int i) {
- MethodTrans.readRow(i);
- return MethodTrans;
- }
-
- public MethodDef MethodDef;
- public MethodDef MethodDef(int i) { MethodDef.readRow(i); return MethodDef; }
-
-
- public ParamDef ParamDef;
- public ParamDef ParamDef(int i) { ParamDef.readRow(i); return ParamDef; }
-
- public GenericParam GenericParam;
-
- public GenericParam GenericParam(int i) {
- GenericParam.readRow(i);
- return GenericParam;
- }
-
- public MethodSpec MethodSpec;
-
- public MethodSpec MethodSpec(int i) {
- MethodSpec.readRow(i);
- return MethodSpec;
- }
-
- public GenericParamConstraint GenericParamConstraint;
-
- public GenericParamConstraint GenericParamConstraint(int i) {
- GenericParamConstraint.readRow(i);
- return GenericParamConstraint;
- }
-
- public InterfaceImpl InterfaceImpl;
- public MemberRef MemberRef;
- public Constant Constant;
- public CustomAttribute CustomAttribute;
- public FieldMarshal FieldMarshal;
- public DeclSecurity DeclSecurity;
- public ClassLayout ClassLayout;
- public FieldLayout FieldLayout;
- public StandAloneSig StandAloneSig;
- public EventMap EventMap;
- public EventDef EventDef;
- public PropertyMap PropertyMap;
- public PropertyDef PropertyDef;
- public MethodSemantics MethodSemantics;
- public MethodImpl MethodImpl;
- public ModuleRef ModuleRef;
- public TypeSpec TypeSpec;
- public ImplMap ImplMap;
- public FieldRVA FieldRVA;
- public AssemblyDef AssemblyDef;
- public AssemblyRef AssemblyRef;
- public FileDef FileDef;
- public ExportedType ExportedType;
- public ManifestResource ManifestResource;
- public NestedClass NestedClass;
-
-
- private void initTableRefs() {
- ModuleDef = (ModuleDef) getTable(Table.ModuleDef.ID);
- TypeRef = (TypeRef) getTable(Table.TypeRef.ID);
- TypeDef = (TypeDef) getTable(Table.TypeDef.ID);
- FieldTrans = (FieldTrans) getTable(Table.FieldTrans.ID);
- FieldDef = (FieldDef) getTable(Table.FieldDef.ID);
- MethodTrans = (MethodTrans) getTable(Table.MethodTrans.ID);
- MethodDef = (MethodDef) getTable(Table.MethodDef.ID);
- ParamDef = (ParamDef) getTable(Table.ParamDef.ID);
- InterfaceImpl = (InterfaceImpl) getTable(Table.InterfaceImpl.ID);
- MemberRef = (MemberRef) getTable(Table.MemberRef.ID);
- Constant = (Constant) getTable(Table.Constant.ID);
- CustomAttribute = (CustomAttribute) getTable(Table.CustomAttribute.ID);
- FieldMarshal = (FieldMarshal) getTable(Table.FieldMarshal.ID);
- DeclSecurity = (DeclSecurity) getTable(Table.DeclSecurity.ID);
- ClassLayout = (ClassLayout) getTable(Table.ClassLayout.ID);
- FieldLayout = (FieldLayout) getTable(Table.FieldLayout.ID);
- StandAloneSig = (StandAloneSig) getTable(Table.StandAloneSig.ID);
- EventMap = (EventMap) getTable(Table.EventMap.ID);
- EventDef = (EventDef) getTable(Table.EventDef.ID);
- PropertyMap = (PropertyMap) getTable(Table.PropertyMap.ID);
- PropertyDef = (PropertyDef) getTable(Table.PropertyDef.ID);
- MethodSemantics = (MethodSemantics) getTable(Table.MethodSemantics.ID);
- MethodImpl = (MethodImpl) getTable(Table.MethodImpl.ID);
- ModuleRef = (ModuleRef) getTable(Table.ModuleRef.ID);
- TypeSpec = (TypeSpec) getTable(Table.TypeSpec.ID);
- ImplMap = (ImplMap) getTable(Table.ImplMap.ID);
- FieldRVA = (FieldRVA) getTable(Table.FieldRVA.ID);
- AssemblyDef = (AssemblyDef) getTable(Table.AssemblyDef.ID);
- AssemblyRef = (AssemblyRef) getTable(Table.AssemblyRef.ID);
- FileDef = (FileDef) getTable(Table.FileDef.ID);
- ExportedType = (ExportedType) getTable(Table.ExportedType.ID);
- NestedClass = (NestedClass) getTable(Table.NestedClass.ID);
- ManifestResource =
- (ManifestResource) getTable(Table.ManifestResource.ID);
- GenericParam = (GenericParam) getTable(Table.GenericParam.ID);
- MethodSpec = (MethodSpec) getTable(Table.MethodSpec.ID);
- GenericParamConstraint = (GenericParamConstraint) getTable(Table.GenericParamConstraint.ID);
- }
-
- public static String long2hex(long a) {
- StringBuffer str = new StringBuffer("0000000000000000");
- str.append(Long.toHexString(a));
- int l = str.length();
- return str.substring(l - 16, l);
- }
-
- public static String int2hex(int a) {
- StringBuffer str = new StringBuffer("00000000");
- str.append(Integer.toHexString(a));
- int l = str.length();
- return str.substring(l - 8, l);
- }
-
- public static String short2hex(int a) {
- StringBuffer str = new StringBuffer("0000");
- str.append(Integer.toHexString(a));
- int l = str.length();
- return str.substring(l - 4, l);
- }
-
- public static String byte2hex(int a) {
- StringBuffer str = new StringBuffer("00");
- str.append(Integer.toHexString(a));
- int l = str.length();
- return str.substring(l - 2, l);
- }
-
- public static String bytes2hex(byte[] buf) {
- StringBuffer str = new StringBuffer();
- for (int i = 0; i < buf.length; i++) {
- str.append(byte2hex(buf[i]));
- if (i < buf.length - 1)
- str.append(" ");
- }
- return str.toString();
- }
-
- //##########################################################################
- // filename
-
- public File getUnderlyingFile() {
- return underlyingFile;
- }
-
- /**
- * @return the absolute path of the file
- */
- public String getAbsolutePath() {
- return underlyingFile.getAbsolutePath();
- }
-
- /**
- * @return the name of this file
- */
- public String getName() {
- return underlyingFile.getName();
- }
-
- /**
- * @return
- */
- public String getParent() {
- return underlyingFile.getParent();
- }
-
- /**
- * @return the file representing the directory the file belongs to
- */
- public File getParentFile() {
- return underlyingFile.getParentFile();
- }
-
- public String toString() {
- return getAbsolutePath();
- }
-
- //##########################################################################
- // file pointer manipulation methods
-
- /** Returns the current position in the file. */
- public int pos() {
- return buf.position();
- }
-
- /** Go to the specified position in the file. */
- public void seek(int pos) {
- buf.position(pos);
- }
-
-
- /** Align the current position in the file. */
- public void align(int base) { align(base, 0); }
-
- /** Align the current position in a section starting at offset. */
- public void align(int base, int offset) {
- int p = pos() - offset;
- seek( offset + ((p % base) == 0 ? p : (p/base + 1) * base));
- }
-
- /** Computes the position in the file that corresponds to the given RVA. */
- public int fromRVA(int rva) {
- int i;
- for(i = 0; i < numOfSections; i++)
- if(sections[i].virtAddr <= rva &&
- rva <= (sections[i].virtAddr + sections[i].virtSize))
- return rva - sections[i].virtAddr + sections[i].realAddr;
- throw new RuntimeException("RVA 0x" + Integer.toHexString(rva) +
- " is not within this file's sections!");
- }
-
- /** Go to the specified RVA (Relative Virtual Address). */
- public void gotoRVA(int rva) {
- seek(fromRVA(rva));
- }
-
- /** Move the forward in the file by the specified number of bytes. */
- public void skip(int n) {
- buf.position(buf.position() + n);
- }
-
- /**
- * Returns a memory mapped little-endian buffer
- * for the specified region of the file.
- */
- public MappedByteBuffer mapBuffer(long offset, int size) {
- try {
- MappedByteBuffer b = file.getChannel()
- .map(FileChannel.MapMode.READ_ONLY, offset, size);
- b.order(java.nio.ByteOrder.LITTLE_ENDIAN);
- return b;
- } catch (IOException e) { throw new RuntimeException(e); }
- }
-
- /** Returns a buffer from the given offset to the end of the file. */
- public ByteBuffer getBuffer(long offset, int size) {
- buf.mark();
- buf.position((int)offset);
- ByteBuffer bb = buf.slice();
- buf.reset();
- bb.limit(size);
- bb.order(java.nio.ByteOrder.LITTLE_ENDIAN);
- return bb;
- }
-
- //##########################################################################
- // file read methods
-
- /**
- * Read bs.length number of bytes
- */
- public void read(byte[] bs) {
- buf.get(bs);
- }
-
- /**
- * Read 1-byte integer from the current position in the file.
- */
- public int readByte() {
- return buf.get();
- }
-
- /**
- * Read 2-byte integer from the current position in the file.
- */
- public int readShort() {
- return buf.getShort();
- }
-
- /**
- * Read 4-byte integer from the current position in the file.
- */
- public int readInt() {
- return buf.getInt();
- }
-
- /**
- * Read 8-byte integer from the current position in the file.
- */
- public long readLong() {
- return buf.getLong();
- }
-
- /**
- * @return the size of string indeces for this file.
- */
- public int getStringIndexSize() {
- return StringIsShort ? 2 : 4;
- }
-
- /**
- * @return the size of GUID indeces for this file.
- */
- public int getGUIDIndexSize() {
- return GUIDIsShort ? 2 : 4;
- }
-
- /**
- * @return the size of Blob indeces for this file.
- */
- public int getBlobIndexSize() {
- return BlobIsShort ? 2 : 4;
- }
-
- /**
- * @return the size of the index to tableID for this file;
- * @param tableID the ID of the table
- */
- public int getTableIndexSize(int tableID) {
- return tables[tableID].isShort ? 2 : 4;
- }
-
- /**
- * @return the size of the index to a set of tables with the given @param TableSetID
- * @param tableSetID the ID of the table set
- */
- public int getTableSetIndexSize(int tableSetID) {
- return indexSize[tableSetID];
- }
-
- /**
- * Read a String index from the current position in the file.
- * @return an index into the String stream
- */
- public int readStringIndex() {
- return StringIsShort ? readShort() : readInt();
- }
-
- /**
- * Read a GUID index from the current position in the file.
- * @return an index in to the GUID stream
- */
- public int readGUIDIndex() {
- return GUIDIsShort ? readShort() : readInt();
- }
-
- /**
- * Read a Blob index from the current position in the file.
- * @return an index into the Blob stream
- */
- public int readBlobIndex() {
- return BlobIsShort ? readShort() : readInt();
- }
-
- /** Read an entry interpreted as index into table @param tableID. */
- public int readTableIndex(int tableId) {
- return tables[tableId].isShort ? readShort() : readInt();
- }
-
- /***/
- public int readTableSetIndex(int tableSetId) {
- return indexSize[tableSetId] == 2 ? readShort() : readInt();
- }
-
- /**
- * Read a string from the String stream
- * @return the string at the given position
- * @param pos the position of the string in the String stream
- */
- public String getString(int pos) {
- String s = Strings.getString(pos);
- return s;//.length() == 0 ? null : s;
- }
-
- /**
- * Read a string from the US (User Strings) stream
- * @return the string at the given position
- * @param pos the position of the string in the US stream
- */
- public String getUString(int pos) {
- return US.getString(pos);
- }
-
- /**
- * Read a blob from the Blob Stream
- * @return the blob at the given position
- * @param pos the position of the blob in the Blob stream
- */
- public byte[] getBlob(int pos) {
- return Blob.getBlob(pos);
- }
-
- /***/
- public Sig getSignature(int pos) {
- //return new Sig(getBlob(pos));
- return Blob.getSignature(pos);
- }
-
- /***/
- public byte[] getGUID(int pos) {
- return GUID.getGUID(pos);
- }
-
- /**
- * @return the table with the corresponding ID.
- */
- public final Table getTable(int tableID) {
- return tables[tableID];
- }
-
- //##########################################################################
-
- /***/
- void trace(String msg) {
- System.out.println("[trace] " + msg);
- }
-
- //##########################################################################
-
- public Sig newSignature(ByteBuffer buf) {
- return new Sig(buf);
- }
-
- /**
- */
- public class Sig implements Signature {
-
- //######################################################################
- // instance members
-
- protected final ByteBuffer buf;
- protected final int pos;
- protected final int length;
-
- public Sig(ByteBuffer buf) {
- this.buf = buf;
- //int tmpPos = buf.position();
- length = decodeInt();
- this.pos = buf.position();
- }
-
- public String toString() {
- StringBuffer b = new StringBuffer("(");
- int savedPos = buf.position();
- reset();
- for (int i = 0; i < length; i++) {
- b.append(byte2hex(readByte()));
- if (i < length - 1)
- b.append(" ");
- }
- buf.position(savedPos);
- return b.append(")").toString();
- }
-
- public Sig reset() { buf.position(pos); return this; }
-
- public int pos() { return buf.position() - pos; }
-
- /** @return the byte at the current position in the signature Blob.
- * Stay at the same position
- */
- public int getByte() {
- return (buf.get(buf.position()) + 0x100) & 0xff;
- }
-
- /** @return the byte at the current position in the signature Blob.
- * Move to the next byte.
- */
- public int readByte() { return (buf.get() + 0x100) & 0xff; }
-
- /** Skip the current byte if equal to the given value. */
- public void skipByte(int b) { if (b == getByte()) buf.get(); }
-
- /** Decodes an integer from the signature Blob.
- * @return the decoded integer
- */
- public int decodeInt() {
- int res = readByte();
- if ((res & 0x80) != 0) {
- res = ((res & 0x7f) << 8) | readByte();
- if ((res & 0x4000) != 0)
- res = ((res & 0x3fff)<<16) | (readByte()<<8) | readByte();
- }
- return res;
- }
-
- /** @return - the type encoded at the current position in the signature
- * according to 23.2.12
- */
- public Type decodeType() {
- try { return decodeType0(); }
- catch (RuntimeException e) {
- System.out.println("" + pos() + "@" + this);
- throw e;
- }
- }
-
- public Type decodeType0() {
- Type type = null;
- int desc = readByte();
- switch (desc) {
- case ELEMENT_TYPE_BOOLEAN:type = Type.GetType("System.Boolean"); break;
- case ELEMENT_TYPE_CHAR: type = Type.GetType("System.Char"); break;
- case ELEMENT_TYPE_I1: type = Type.GetType("System.SByte"); break;
- case ELEMENT_TYPE_U1: type = Type.GetType("System.Byte"); break;
- case ELEMENT_TYPE_I2: type = Type.GetType("System.Int16"); break;
- case ELEMENT_TYPE_U2: type = Type.GetType("System.UInt16"); break;
- case ELEMENT_TYPE_I4: type = Type.GetType("System.Int32"); break;
- case ELEMENT_TYPE_U4: type = Type.GetType("System.UInt32"); break;
- case ELEMENT_TYPE_I8: type = Type.GetType("System.Int64"); break;
- case ELEMENT_TYPE_U8: type = Type.GetType("System.UInt64"); break;
- case ELEMENT_TYPE_R4: type = Type.GetType("System.Single"); break;
- case ELEMENT_TYPE_R8: type = Type.GetType("System.Double"); break;
- case ELEMENT_TYPE_OBJECT: type = Type.GetType("System.Object"); break;
- case ELEMENT_TYPE_STRING: type = Type.GetType("System.String"); break;
- case ELEMENT_TYPE_I: type = Type.GetType("System.IntPtr"); break;
- case ELEMENT_TYPE_U: type = Type.GetType("System.UIntPtr"); break;
- case ELEMENT_TYPE_PTR: // Followed by <type> token.
- if (getByte() == ELEMENT_TYPE_VOID) {
- readByte();
- type = Type.mkPtr(Type.GetType("System.Void"));
- } else type = Type.mkPtr(decodeType());
- break;
- case ELEMENT_TYPE_BYREF: /* although BYREF is not listed in 23.2.12. as possible alternative, this method is also called when parsing the signatures of a method param and a method return, which do allow for BYREF */
- type = Type.mkByRef(decodeType());
- break;
- case ELEMENT_TYPE_VALUETYPE: // Followed by TypeDefOrRefEncoded
- assert true;
- case ELEMENT_TYPE_CLASS:
- // Followed by <type> token
- type = pemodule.getTypeDefOrRef(decodeInt());
- if (type == null) throw new RuntimeException();
- break;
-
- case ELEMENT_TYPE_SZARRAY: // Single-dim array with 0 lower bound.
- skipCustomMods();
- type = Type.mkArray(decodeType(), 1);
- break;
- case ELEMENT_TYPE_ARRAY:
- // <type> <rank> <boundsCount> <bound1> ... <loCount> <lo1> ...
- // ArrayShape defined in 23.2.13 ArrayShape
- Type elem = decodeType();
- int rank = decodeInt();
- int numSizes = decodeInt();
- for (int i = 0; i < numSizes; i++)
- decodeInt(); // TODO don't ignore
- int numLoBounds = decodeInt();
- for (int i = 0; i < numLoBounds; i++)
- decodeInt(); // TODO don't ignore
- type = Type.mkArray(elem, rank);
- break;
-
- // a grammar production from 23.2.12 Type
- // GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount Type*
- case ELEMENT_TYPE_GENERICINST:
- int b = readByte();
- /*- TODO don't ignore b as done above. Should .NET valuetypes be represented as Scala case classes? */
- Type instantiatedType = pemodule.getTypeDefOrRef(decodeInt());
- int numberOfTypeArgs = decodeInt();
- Type[] typeArgs = new Type[numberOfTypeArgs];
- for (int iarg = 0; iarg < numberOfTypeArgs; iarg++) {
- typeArgs[iarg] = decodeType();
- }
- type = new ConstructedType(instantiatedType, typeArgs);
- break;
-
- // another grammar production from 23.2.12 Type
- // ELEMENT_TYPE_VAR number The number non-terminal following MVAR
- // or VAR is an unsigned integer value (compressed).
- /* See also duplicate code in PEModule.java */
- case ELEMENT_TYPE_VAR:
- int typeArgAsZeroBased = decodeInt();
- type = new Type.TMVarUsage(typeArgAsZeroBased, true);
- break;
-
- // another grammar production from 23.2.12 Type
- // ELEMENT_TYPE_MVAR number The number non-terminal following MVAR
- // or VAR is an unsigned integer value (compressed).
- /* See also duplicate code in PEModule.java */
- case ELEMENT_TYPE_MVAR:
- typeArgAsZeroBased = decodeInt();
- type = new Type.TMVarUsage(typeArgAsZeroBased, false);
- break;
-
- case ELEMENT_TYPE_FNPTR:
- // Followed MethodDefSig or by MethodRefSig.
- case ELEMENT_TYPE_END:
- // Marks end of a list
- case ELEMENT_TYPE_CMOD_REQD:
- // Required modifier : followed by a TypeDef or TypeRef token.
- case ELEMENT_TYPE_CMOD_OPT:
- // Optional modifier : followed by a TypeDef or TypeRef token.
- case ELEMENT_TYPE_INTERNAL:
- // Implemented within the CLI.
- case ELEMENT_TYPE_MODIFIER:
- // Or'd with following element types.
- case ELEMENT_TYPE_SENTINEL:
- // Sentinel for varargs method signature.
- case ELEMENT_TYPE_PINNED:
- // Denotes a local variable that points at a pinned object.
- default:
- throw new RuntimeException(byte2hex(desc) +
- "@" + pos() + " in " + this);
-
- }
- if (type == null) throw new RuntimeException();
- return type;
- } // decodeType0()
-
- public PECustomMod decodeFieldType() {
- skipByte(FIELD); // 0x06
- CustomModifier[] cmods = getCustomMods();
- Type fieldType = decodeType();
- return new PECustomMod(fieldType, cmods);
- }
-
- /** decodes the return type of a method signature (22.2.11). */
- public Type decodeRetType() {
- skipCustomMods();
- switch (getByte()) {
- case ELEMENT_TYPE_VOID:
- readByte();
- return Type.GetType("System.Void");
- case ELEMENT_TYPE_TYPEDBYREF:
- return Type.GetType("System.TypedReference");
- case ELEMENT_TYPE_BYREF:
- return decodeType();
- default:
- return decodeType();
- }
- }
-
- public Type decodeParamType() {
- skipCustomMods();
- switch (getByte()) {
- case ELEMENT_TYPE_BYREF:
- return decodeType();
- case ELEMENT_TYPE_TYPEDBYREF:
- return Type.GetType("System.TypedReference");
- default:
- return decodeType();
- }
- }
-
- public void skipCustomMods() {
- while (getByte() == ELEMENT_TYPE_CMOD_OPT /* 0x20 */
- || getByte() == ELEMENT_TYPE_CMOD_REQD /* 0x1f */ )
- {
- boolean isREQD = (getByte() == ELEMENT_TYPE_CMOD_REQD); // 0x1f
- // skip the tag 23.2.7
- readByte();
- // skip the TypeDefOrRefEncoded (23.2.8)
- Type ignored = pemodule.getTypeDefOrRef(decodeInt());
- if(isREQD) {
- // System.err.println("ELEMENT_TYPE_CMOD_REQD: " + ignored);
- // throw new RuntimeException("Reqired CMOD: " + ignored);
- }
- }
- }
-
- /**
- * @see CustomModifier
- */
- public CustomModifier[] getCustomMods() {
- java.util.List/*<CustomModifier>*/ cmods = new java.util.LinkedList();
- while (getByte() == ELEMENT_TYPE_CMOD_OPT || getByte() == ELEMENT_TYPE_CMOD_REQD) {
- boolean isReqd = (getByte() == ELEMENT_TYPE_CMOD_REQD);
- readByte(); // tag 23.2.7
- Type t = pemodule.getTypeDefOrRef(decodeInt()); // TypeDefOrRefEncoded (23.2.8)
- cmods.add(new CustomModifier(isReqd, t));
- }
- CustomModifier[] res = (CustomModifier[])cmods.toArray(new CustomModifier[0]);
- return res;
- }
-
- //######################################################################
-
- } // class Sig
-
- //##########################################################################
-
-} // class PEFile
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PEModule.java b/src/msil/ch/epfl/lamp/compiler/msil/PEModule.java
deleted file mode 100644
index cb8cd8f098..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PEModule.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.PEFile;
-import ch.epfl.lamp.compiler.msil.PEFile.Sig;
-import ch.epfl.lamp.compiler.msil.util.Signature;
-import ch.epfl.lamp.compiler.msil.util.Table;
-import ch.epfl.lamp.compiler.msil.util.Table.*;
-
-import java.nio.ByteBuffer;
-
-/** Represents a module corresponding to a PE/COFF file
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-final class PEModule extends Module {
-
- //##########################################################################
-
- protected final PEFile pefile;
-
- private final int definingRow;
-
- private Type[] typeRefs = null;
-
- protected PEModule(PEFile pefile, int definingRow, String scopeName,
- Assembly assem)
- {
- super(pefile.getName(), pefile.getAbsolutePath(), scopeName, assem);
- this.pefile = pefile;
- this.definingRow = definingRow;
- pefile.initModule(this);
- pefile.TypeDef.load(); // load into memory
- //loadTypes();
- //pefile.FieldDef.load();
- //pefile.MethodDef.load();
- loadGlobals();
- }
-
- //##########################################################################
-
- public Type GetType(String typeName) {
- initTypes();
- Object o = typesMap.get(typeName);
- if (o == null) {
- //System.out.println("PEModule.GetType(): Unable to find type "
- // + typeName + " int module " + this);
- return null;
- }
- return o instanceof Type ? (Type)o
- : getTypeDef(((Integer)o).intValue());
- }
-
-
- /** Load information about the types defined in this module.
- */
- protected void loadTypes() {
- typeRefs = new Type[pefile.TypeRef.rows];
- final int nbTypes = pefile.TypeDef.rows;
- for (int row = 2; row <= nbTypes; row++) {
- String name = pefile.TypeDef(row).getFullName();
- typesMap.put(name, new Integer(row));
- }
- this.types = new Type[nbTypes - 1];
- for (int row = 2; row <= nbTypes; row++) {
- getTypeDef(row);
- }
- }
-
- /** Return the type defined at the given row in the TypeDef table.
- */
- Type getTypeDef(int row) {
- if (this.types[row - 2] != null)
- return this.types[row - 2];
-
- TypeDef type = pefile.TypeDef(row);
- int attrs = type.Flags;
- String name = type.getFullName();
-
- Type declType = null;
- if (TypeAttributes.isNested(attrs)) {
- for (int i = 1; i <= pefile.NestedClass.rows; i++) {
- pefile.NestedClass.readRow(i);
- if (pefile.NestedClass.NestedClass == row)
- declType = getTypeDef
- (pefile.NestedClass.EnclosingClass);
- }
- }
- Type t = new PEType
- (this, attrs, name, declType, Type.AuxAttr.None, pefile, row);
- types[row - 2] = t;
- addType(t);
- int[] tvarIdxes = pefile.GenericParam.getTVarIdxes(row);
- // if(tvarIdxes.length > 0) { System.out.println("Type: " + t); }
- for(int i = 0; i < tvarIdxes.length; i++) {
- GenericParamAndConstraints tvarAndConstraints = getTypeConstraints(tvarIdxes[i]);
- // add tvarAndConstraints as i-th TVar in t
- t.addTVar(tvarAndConstraints);
- }
- return t;
- }
-
- public GenericParamAndConstraints getTypeConstraints(int genParamIdx) {
- int tvarNumber = pefile.GenericParam(genParamIdx).Number;
- // tvarName can be null
- String tvarName = pefile.GenericParam.getName();
- boolean isInvariant = pefile.GenericParam.isInvariant();
- boolean isCovariant = pefile.GenericParam.isCovariant();
- boolean isContravariant = pefile.GenericParam.isContravariant();
- boolean isReferenceType = pefile.GenericParam.isReferenceType();
- boolean isValueType = pefile.GenericParam.isValueType();
- boolean hasDefaultConstructor = pefile.GenericParam.hasDefaultConstructor();
- // grab constraints
- int[] TypeDefOrRefIdxes = pefile.GenericParamConstraint.getTypeDefOrRefIdxes(genParamIdx);
- Type[] tCtrs = new Type[TypeDefOrRefIdxes.length];
- for(int i = 0; i < TypeDefOrRefIdxes.length; i++) {
- Type tConstraint = getTypeDefOrRef(TypeDefOrRefIdxes[i]);
- tCtrs[i] = tConstraint;
- // System.out.println("\t\tConstraint: " + tConstraint);
- }
- GenericParamAndConstraints res = new GenericParamAndConstraints(tvarNumber, tvarName, tCtrs,
- isInvariant, isCovariant, isContravariant,
- isReferenceType, isValueType, hasDefaultConstructor);
- return res;
- }
-
- /**
- * Load the desription of the module-global fields and methods
- */
- protected void loadGlobals() {
- //TODO:
- }
-
- protected void loadCustomAttributes(Type attributeType) {
- initAttributes(this, 1, Table.ModuleDef.ID, attributeType);
- }
-
- /** Return the type referenced by the given row in the TypeRef table.
- */
- Type getTypeRef(int row) {
- return getTypeRef(row, null);
- }
-
- /** Return the type referenced by the given row in the TypeRef table
- * only if it resides in the given assembly.
- * <i>Used by initCustomAttributes to avoid unnecessary loading
- * of referenced assemblies.</i>
- */
- Type getTypeRef(int row, Assembly inAssembly) {
- Type type = typeRefs[row - 1];
- if (type != null)
- return type;
-
- Table.TypeRef tr = pefile.TypeRef;
- tr.readRow(row);
- int tableId = Table.getTableId(Table._ResolutionScope,
- tr.ResolutionScope);
- int refRow = tr.ResolutionScope >> Table.NoBits[Table._ResolutionScope];
- final String typeName = tr.getFullName();
- pefile.getTable(tableId).readRow(refRow);
- switch (tableId) {
- case AssemblyRef.ID:
- String name = pefile.AssemblyRef.getName();
- if (inAssembly != null && !inAssembly.GetName().Name.equals(name))
- return null;
- Assembly assem = getAssembly(name);
- type = assem.GetType(typeName);
- if (type == null) {
- // HACK: the IKVM.OpenJDK.Core assembly is compiled against mscorlib.dll v2.0
- // The MSIL library cannot parse the v2.0 mscorlib because of generics, so we
- // use the v1.0
- // However, the java.io.FileDescriptor.FlushFileBuffers method uses a type
- // Microsoft.Win32.SafeHandles.SafeFileHandle, which only exists in mscorlib
- // v2.0
- // For now, jsut return Object (fine as long as we don't use that method).
- Assembly asmb = getAssembly("mscorlib");
- type = asmb.GetType("System.Object");
- //throw new RuntimeException("Failed to locate type " +
- //typeName + " in assembly " + assem);
- }
- break;
- case ModuleDef.ID:
- assert refRow == 1;
- type = this.GetType(typeName);
- //assert type != null;
- break;
- case TypeRef.ID:
- Type nestingType = getTypeRef(refRow);
- String nestedName = typeName;
- type = nestingType.GetNestedType(nestedName);
- break;
- case ModuleRef.ID:
- type = getAssembly(pefile.ModuleRef.getName()).GetType(typeName);
- default:
- throw new RuntimeException(refRow + "@" + pefile.getTable(tableId).getTableName()/* PEFile.byte2hex(tableId)*/);
- }
- if (typeRefs[row - 1] != null)
- System.out.println("TypeRef[" + PEFile.short2hex(row) + "] " +
- "changing type " + typeRefs[row - 1] +
- " for type " + type);
- typeRefs[row - 1] = type;
- assert type != null : "Couldn't find type " + typeName;
- return type;
- }
-
- private Assembly getAssembly(String name) {
- Assembly assem = Assembly.getAssembly(name);
- if (assem != null)
- return assem;
- java.io.File dir = pefile.getParentFile();
- assem = Assembly.LoadFrom(dir, name);
- if (assem != null)
- return assem;
- try {
- dir = pefile.getUnderlyingFile().getCanonicalFile().getParentFile();
- } catch (java.io.IOException e) {
- throw new RuntimeException(e);
- }
- assem = Assembly.LoadFrom(dir, name);
- if (assem != null)
- return assem;
- throw new RuntimeException("Cannot find assembly: " + name);
-
- }
-
- /** Return the type corresponding to TypeDefOrRef coded index.
- * @param index - TypeDefOrRef coded index according to 23.2.6.
- */
- public Type getTypeDefOrRef(int index) {
- int tableId = Table.getTableId(Table._TypeDefOrRef, index);
- int row = index >> Table.NoBits[Table._TypeDefOrRef];
- Type type = null;
- switch (tableId) {
- case Table.TypeDef.ID:
- type = getTypeDef(row);
- break;
- case Table.TypeRef.ID:
- return getTypeRef(row);
- case Table.TypeSpec.ID:
- Table.TypeSpec ts = pefile.TypeSpec;
- ts.readRow(row);
- int posInBlobStream = ts.Signature;
- byte[] blobArrWithLengthStripped = pefile.Blob.getBlob(posInBlobStream);
- byte[] compressedUInt = compressUInt(blobArrWithLengthStripped.length);
- byte[] byteArr = new byte[blobArrWithLengthStripped.length + compressedUInt.length];
- System.arraycopy(compressedUInt, 0, byteArr, 0, compressedUInt.length);
- System.arraycopy(blobArrWithLengthStripped, 0, byteArr, compressedUInt.length, blobArrWithLengthStripped.length);
- ByteBuffer buf = ByteBuffer.wrap(byteArr);
- Sig sig = pefile.new Sig(buf);
- int desc = sig.readByte();
-
- switch (desc) {
-
- // GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncodred GenArgCount Type*
- case Signature.ELEMENT_TYPE_GENERICINST: // i.e. 0x15
- int b = sig.readByte(); // i.e. (0x12 | 0x11)
- /* TODO don't ignore b as done above */
- Type instantiatedType = getTypeDefOrRef(sig.decodeInt()); // TypeDefOrRefEncoded
- int numberOfTypeArgs = sig.decodeInt(); // GenArgCount
- Type[] typeArgs = new Type[numberOfTypeArgs];
- for (int iarg = 0; iarg < numberOfTypeArgs; iarg++) {
- typeArgs[iarg] = sig.decodeType(); // Type*
- }
- type = new ConstructedType(instantiatedType, typeArgs);
- break;
-
- /* Miguel says: Actually the following grammar rule production is not among those for a TypeSpecBlob
- but I've found it in assemblies compiled from C# 3.0.
- See also duplicate code in PEFile.java */
- case Signature.ELEMENT_TYPE_VAR:
- int typeArgAsZeroBased = sig.decodeInt();
- type = new Type.TMVarUsage(typeArgAsZeroBased, true);
- break;
-
- /* Miguel says: Actually the following grammar rule production is not among those for a TypeSpecBlob
- but I've found it in assemblies compiled from C# 3.0.
- See also duplicate code in PEFile.java */
- case Signature.ELEMENT_TYPE_MVAR:
- typeArgAsZeroBased = sig.decodeInt();
- type = new Type.TMVarUsage(typeArgAsZeroBased, false);
- break;
-
- case Signature.ELEMENT_TYPE_SZARRAY: // Single-dim array with 0 lower bound.
- sig.skipCustomMods();
- type = Type.mkArray(sig.decodeType(), 1);
- break;
-
- case Signature.ELEMENT_TYPE_ARRAY:
- // <type> <rank> <boundsCount> <bound1> ... <loCount> <lo1> ...
- // ArrayShape defined in 23.2.13 ArrayShape
- Type elem = sig.decodeType();
- int rank = sig.decodeInt();
- int numSizes = sig.decodeInt();
- for (int i = 0; i < numSizes; i++)
- sig.decodeInt(); // TODO don't ignore
- int numLoBounds = sig.decodeInt();
- for (int i = 0; i < numLoBounds; i++)
- sig.decodeInt(); // TODO don't ignore
- type = Type.mkArray(elem, rank);
- break;
-
- default:
- // TODO remaining grammar productions in 23.2.14 are for PTR and FNPTR only
- throw new RuntimeException("PEModule.getTypeDefOrRef(): TypeSpec");
- }
- break;
- default:
- throw new RuntimeException("PEModule.getTypeDefOrRef(): oops!");
- }
- return type;
- }
-
- private byte[] compressUInt(int u) {
- // 23.2 in Partition II
- // TODO add tests based on the examples in 23.2 in Partition II
- // the CCI implementation is WriteCompressedUInt
-
- /* informal discussion at http://www.cnblogs.com/AndersLiu/archive/2010/02/09/en-compressed-integer-in-metadata.html */
- if (u <= 127 && 0 <= u) {
- return new byte[]{(byte) u};
- } else if (u > 127 && u <= (2 ^ 14 - 1)) {
- byte loByte = (byte)(u & 0xff);
- byte hiByte = (byte)((u >> 8) | 0x80);
- byte[] res = new byte[] { hiByte, loByte };
- return res;
- } else {
- byte b0 = (byte)(u & 0xff);
- byte b1 = (byte)((u & 0xff00)>>8);
- byte b2 = (byte)((u & 0xff0000)>>16);
- byte b3 = (byte)((u >> 24)|0xc0);
- byte[] res = new byte[] { b3, b2, b1, b0 };
- return res;
- }
- }
-
- /**
- * Returns the method defined at the given row of the MethodDef table
- * by looking up the type that defines the method.
- */
- MethodBase getMethod(int row) {
- for (int i = 0; i < types.length; i++) {
- PEType type = (PEType)types[i];
- if ((type.methodListBeg <= row) && (row < type.methodListEnd)) {
- type.initMethods();
- return type.methoddefs[row - type.methodListBeg];
- }
- }
- throw new RuntimeException("In module " + this
- + ": cannot find type defining method 0x"
- + PEFile.int2hex(row));
- }
-
- /** Returns the member referenced by the given row of the MemberRef table.
- */
- protected MemberInfo getMemberRef(int row) {
- return getMemberRef(row, null);
- }
-
- /** Returns the member referenced by the given row of the MemberRef table
- * if defined in the given assembly.
- * <i>Used by initCustomAttributes to avoid unnecessary loading of
- * referenced assemblies</i>
- */
- protected MemberInfo getMemberRef(int row, Assembly inAssembly) {
- MemberInfo member = null;
- MemberRef mref = pefile.MemberRef;
- mref.readRow(row);
- int mtbl = Table.getTableId(Table._MemberRefParent, mref.Class);
- int mind = Table.getTableIndex(Table._MemberRefParent, mref.Class);
- switch (mtbl) {
- case TypeRef.ID:
- Type type = getTypeRef(mind, inAssembly);
- if (type == null)
- return null;
- Sig sig = mref.getSignature();
- int callconv = sig.readByte(); // should be 0x20
- int paramCount = sig.decodeInt();
- //sig.skipByte(Signature.ELEMENT_TYPE_BYREF); //from MethodDef
- Type retType = sig.decodeRetType();
- Type[] paramType = new Type[paramCount];
- for (int i = 0; i < paramCount; i++)
- paramType[i] = sig.decodeParamType();
-
- String memberName = mref.getName();
- if (memberName.equals(ConstructorInfo.CTOR) ||
- memberName.equals(ConstructorInfo.CCTOR))
- {
- member = type.GetConstructor(paramType);
- } else {
- member = type.GetMethod(memberName, paramType);
- }
- assert member != null : type + "::" + memberName;
- break;
- case ModuleRef.ID:
- case MethodDef.ID:
- case TypeSpec.ID:
- throw new RuntimeException("initCustomAttributes: "
- + pefile.getTable(mtbl).getTableName());
- }
- return member;
- }
-
- protected void initCustomAttributes(Type attributeType) {
- initAttributes(this, definingRow, Table.ModuleDef.ID, attributeType);
- }
-
- // explicitly only package-visible
- void initAttributes(CustomAttributeProvider cap, int definingRow,
- int sourceTableId, Type attributeType)
- {
- int parentIndex = Table.encodeIndex(definingRow,
- Table._HasCustomAttribute,
- sourceTableId);
- Table.CustomAttribute attrs = pefile.CustomAttribute;
- for (int row = 1; row <= attrs.rows; row++) {
- ConstructorInfo attrConstr = null;
- attrs.readRow(row);
- if (attrs.Parent == parentIndex) {
- int tableId = Table.getTableId(Table._CustomAttributeType,
- attrs.Type);
- int ind = Table.getTableIndex(Table._CustomAttributeType,
- attrs.Type);
- switch (tableId) {
- case MethodDef.ID:
- attrConstr = (ConstructorInfo)this.getMethod(ind);
- break;
- case MemberRef.ID:
- //System.out.println(PEFile.short2hex(ind) + "@MemberRef");
- Assembly attrAssem =
- attributeType == null ? null : attributeType.Assembly();
- MemberInfo mi = this.getMemberRef(ind, attrAssem);
- if (mi != null) {
- assert mi instanceof ConstructorInfo
- : "Expected ConstructorInfo; found " + mi;
- attrConstr = (ConstructorInfo)mi;
- }
- break;
- default:
- throw new RuntimeException();
- }
- if (attrConstr != null
- && (attrConstr.DeclaringType == attributeType
- || attributeType == null))
- cap.addCustomAttribute(attrConstr, attrs.getValue());
- }
- }
- }
-
- //##########################################################################
-
-} // class PEModule
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PEType.java b/src/msil/ch/epfl/lamp/compiler/msil/PEType.java
deleted file mode 100644
index 418c6603b3..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PEType.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.PEFile.Sig;
-
-import ch.epfl.lamp.compiler.msil.util.Table;
-import ch.epfl.lamp.compiler.msil.util.Table.*;
-import ch.epfl.lamp.compiler.msil.util.Signature;
-import ch.epfl.lamp.compiler.msil.util.PECustomMod;
-
-import java.util.ArrayList;
-
-/**
- * Represents a type from a .NET assembly
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-final class PEType extends Type implements Signature {
-
- //##########################################################################
-
- /** The PEFile that holds the description of the type. */
- final PEFile file;
-
- /** The number of the row in the TypeDef table defining the type. */
- final int definingRow;
-
- /** The row of the first method in the MethodDef table. */
- final int methodListBeg;
-
- /** The row of the last method in the MethodDef table + 1. */
- final int methodListEnd;
-
- /** @param definingRow - the index in the TypeDef table where
- * the type description is.
- */
- PEType(PEModule module,
- int attributes,
- String fullName,
- Type declType,
- int auxAttr,
- PEFile file,
- int definingRow)
- {
- super(module, attributes, fullName, null, null, declType, auxAttr);
- this.file = file;
- this.definingRow = definingRow;
- methodListBeg = file.TypeDef(definingRow).MethodList;
- methodListEnd = definingRow < file.TypeDef.rows
- ? file.TypeDef(definingRow + 1).MethodList
- : file.MethodDef.rows + 1;
- }
-
- //##########################################################################
- // lazy type construction methods
-
- protected void loadBaseType() {
- TypeDef type = file.TypeDef(definingRow);
- baseType = type.Extends == 0 ? null
- : ((PEModule)Module).getTypeDefOrRef(type.Extends);
- }
-
- protected void loadFields() {
- // the list of the declared fields starts from the
- // FieldList index in the TypeDef table up to the smaller of the:
- // - the last row of the FieldDef table
- // - the start of the next list of fields determined by the
- // FieldList index of the next row in the TypeDef table
- final ArrayList fields = new ArrayList();
- int fieldListBeg = file.TypeDef(definingRow).FieldList;
- int fieldListEnd = file.FieldDef.rows + 1;
- if (definingRow < file.TypeDef.rows)
- fieldListEnd = file.TypeDef(definingRow + 1).FieldList;
-
- for (int row = fieldListBeg; row < fieldListEnd; row++) {
- int frow = file.FieldTrans.rows == 0
- ? row : file.FieldTrans(row).Field;
- int attrs = file.FieldDef(frow).Flags;
- String name = file.FieldDef.getName();
- //System.out.println("\t-->Loading field: " + name);
- Sig sig = file.FieldDef.getSignature();
- PECustomMod pecmod = sig.decodeFieldType();
- Object val = null;
- Table.Constant consts = file.Constant;
- for (int i = 1; i <= consts.rows; i++) {
- consts.readRow(i);
- int tableId = Table.getTableId(Table._HasConstant,consts.Parent);
- int refRow = consts.Parent >> Table.NoBits[Table._HasConstant];
- if (tableId == Table.FieldDef.ID && refRow == frow)
- val = consts.getValue();
- }
- FieldInfo field = new PEFieldInfo(row, name, attrs, pecmod, val);
- if (field.Name.equals("value__") && field.IsSpecialName()) {
- assert underlyingType == null : underlyingType.toString();
- underlyingType = field.FieldType;
- }
- fields.add(field);
- }
- this.fields = (FieldInfo[])
- fields.toArray(FieldInfo.EMPTY_ARRAY);
- fields.clear();
- }
-
- protected MethodBase[] methoddefs;
-
- protected MethodInfo getMethod(int n) {
- return (MethodInfo)methoddefs[n - methodListBeg];
- }
-
- protected void loadMethods() {
- methoddefs = new MethodBase[methodListEnd - methodListBeg];
-
- final ArrayList methods = new ArrayList();
- final ArrayList constrs = new ArrayList();
- PEModule pemodule = (PEModule) Module;
- for (int row = methodListBeg; row < methodListEnd; row++) {
- int mrow = file.MethodTrans.rows == 0
- ? row : file.MethodTrans(row).Method;
- int attrs = file.MethodDef(mrow).Flags;
- String name = file.MethodDef.getName();
- Sig sig = file.MethodDef.getSignature();
- /* we're about to parse a MethodDefSig, defined in Sec. 23.2.1 of Partition II () */
-
- int callConv = sig.readByte();
- // TODO decode HASTHIS from high byte of calling convention
- // TODO decode EXPLICITTHIS from high byte of calling convention
- // TODO handle VARARG calling convention (not CLS but may show up )
- if((callConv & 0x1F) == Signature.GENERIC) {
- int genParamCount = sig.decodeInt();
- /* genParamCount is ignored because the method's type params will be obtained below
- (see: file.GenericParam.getMVarIdxes(row) ) */
- }
- int paramCount = sig.decodeInt();
- Type retType = sig.decodeRetType();
- Type[] paramType = new Type[paramCount];
- for (int i = 0; i < paramCount; i++)
- paramType[i] = sig.decodeParamType();
-
- ParameterInfo[] params = new ParameterInfo[paramCount];
- int paramListBeg = file.MethodDef.ParamList;
- int paramListEnd = paramListBeg + paramCount;
- if (paramListEnd > file.ParamDef.rows) {
- /* don't try to read param names past ParamDef's row count
- Some assembly-writers don't bother to give names for all params. */
- paramListEnd = file.ParamDef.rows + 1;
- }
- for (int i = paramListBeg; i < paramListEnd; i++) {
- int pattr = file.ParamDef(i).Flags;
- String paramName = file.ParamDef.getName();
- int seq = file.ParamDef.Sequence;
- if (seq == 0) {
- //System.out.println("Retval attributes 0x" +
- // PEFile.short2hex(pattr));
- } else {
- params[seq - 1] = new ParameterInfo(paramName, paramType[seq - 1], pattr, seq - 1);
- }
- }
- for (int i = 0; i < params.length; i++) {
- if (params[i] == null)
- params[i] = new ParameterInfo(null, paramType[i], 0, 0);
- }
- MethodBase method = null;
- if ((attrs & MethodAttributes.SpecialName) != 0
- && (attrs & MethodAttributes.RTSpecialName) != 0
- && (name.equals(ConstructorInfo.CTOR)
- || name.equals(ConstructorInfo.CCTOR)))
- {
- method = new PEConstructorInfo(row, attrs, params);
- }
- else {
- method = new PEMethodInfo(row, name, attrs, retType, params);
- int[] mvarIdxes = file.GenericParam.getMVarIdxes(row);
- // if(mvarIdxes.length > 0) { System.out.println("Method: " + method); }
- for(int i = 0; i < mvarIdxes.length; i++) {
- GenericParamAndConstraints mvarAndConstraints = pemodule.getTypeConstraints(mvarIdxes[i]);
- // add mvarAndConstraints as i-th MVar in method
- ((PEMethodInfo)method).addMVar(mvarAndConstraints);
- }
- }
- (method.IsConstructor() ? constrs : methods).add(method);
- methoddefs[row - methodListBeg] = method;
- }
-
- this.constructors = (ConstructorInfo[])
- constrs.toArray(ConstructorInfo.EMPTY_ARRAY);
- this.methods = (MethodInfo[])
- methods.toArray(MethodInfo.EMPTY_ARRAY);
- constrs.clear(); methods.clear();
- }
-
- protected void loadProperties() {
- final PropertyMap pmap = file.PropertyMap;
- if (pmap == null) {
- properties = PropertyInfo.EMPTY_ARRAY;
- return;
- }
-
- final PropertyDef pdef = file.PropertyDef;
- int propListBeg = -1;
- int propListEnd = pdef.rows + 1;
- for (int i = 1; i <= pmap.rows; i++) {
- pmap.readRow(i);
- if (pmap.Parent == this.definingRow) {
- propListBeg = pmap.PropertyList;
- if (i < pmap.rows) {
- pmap.readRow(i + 1);
- propListEnd = pmap.PropertyList;
- }
- break;
- }
- }
- if (propListBeg < 0) {
- properties = PropertyInfo.EMPTY_ARRAY;
- return;
- }
-
- final ArrayList properties = new ArrayList();
- for (int i = propListBeg; i < propListEnd; i++) {
- pdef.readRow(i);
- Sig sig = pdef.getSignature();
- int b = sig.readByte();
- b &= ~HASTHIS;
- int paramCount = sig.readByte();
- assert b == PROPERTY;
- Type propType = sig.decodeType();
- int index = Table.encodeIndex(i, Table._HasSemantics,
- Table.PropertyDef.ID);
- MethodSemantics msem = file.MethodSemantics;
- MethodInfo getter = null, setter = null;
- for (int j = 1; j <= msem.rows; j++) {
- msem.readRow(j);
- if (msem.Association != index)
- continue;
- if (msem.isGetter())
- getter = getMethod(msem.Method);
- else if (msem.isSetter())
- setter = getMethod(msem.Method);
- else
- System.err.println("PEType.loadProperties(): !?!");
- }
- properties.add
- (new PEPropertyInfo(i, pdef.getName(), (short)pdef.Flags,
- propType, getter, setter));
- }
- this.properties = (PropertyInfo[]) properties
- .toArray(PropertyInfo.EMPTY_ARRAY);
- }
-
- protected void loadEvents() {
- EventMap emap = file.EventMap;
- if (emap == null) {
- this.events = EventInfo.EMPTY_ARRAY;
- return;
- }
-
- final EventDef edef = file.EventDef;
- int eventListBeg = -1;
- int eventListEnd = edef.rows + 1;
- for (int i = 1; i <= emap.rows; i++) {
- emap.readRow(i);
- if (emap.Parent == this.definingRow) {
- eventListBeg = emap.EventList;
- if (i < emap.rows) {
- emap.readRow(i + 1);
- eventListEnd = emap.EventList;
- }
- break;
- }
- }
- if (eventListBeg < 0) {
- this.events = EventInfo.EMPTY_ARRAY;
- return;
- }
-
- final ArrayList events = new ArrayList();
- final MethodSemantics msem = file.MethodSemantics;
- for (int i = eventListBeg; i < eventListEnd; i++) {
- edef.readRow(i);
- final Type handler =
- ((PEModule)Module).getTypeDefOrRef(edef.EventType);
- int index =
- Table.encodeIndex(i, Table._HasSemantics, Table.EventDef.ID);
- MethodInfo add = null, remove = null;
- for (int j = 1; j <= msem.rows; j++) {
- msem.readRow(j);
- if (msem.Association != index)
- continue;
- if (msem.isAddOn())
- add = getMethod(msem.Method);
- else if (msem.isRemoveOn())
- remove = getMethod(msem.Method);
- else {
- }
- }
- events.add(new PEEventInfo(i, edef.getName(),
- (short)edef.EventFlags,
- handler, add, remove));
- }
- this.events = (EventInfo[]) events
- .toArray(EventInfo.EMPTY_ARRAY);
- }
-
- protected void loadNestedTypes() {
- final ArrayList nested = new ArrayList();
- for (int i = 1; i <= file.NestedClass.rows; i++) {
- file.NestedClass.readRow(i);
- if (file.NestedClass.EnclosingClass == this.definingRow)
- nested.add(((PEModule)Module)
- .getTypeDef(file.NestedClass.NestedClass));
- }
- this.nestedTypes = (Type[]) nested.toArray(Type.EmptyTypes);
- }
-
- protected void loadInterfaces() {
- // get the interfaces implemented by this class
- interfaces = Type.EmptyTypes;
- int index = file.InterfaceImpl.findType(definingRow);
- if (index > 0) {
- ArrayList ifaces = new ArrayList();
- for (int i = index; i <= file.InterfaceImpl.rows; i++) {
- file.InterfaceImpl.readRow(i);
- if (file.InterfaceImpl.Class != definingRow)
- break;
- ifaces.add(((PEModule)Module)
- .getTypeDefOrRef(file.InterfaceImpl.Interface));
- }
- interfaces = (Type[]) ifaces.toArray(new Type[ifaces.size()]);
- }
- }
-
- protected void loadCustomAttributes(Type attributeType) {
- initAttributes(this, definingRow, Table.TypeDef.ID, attributeType);
- }
-
- private void initAttributes(CustomAttributeProvider cap, int definingRow,
- int sourceTableId, Type attributeType)
- {
- ((PEModule)this.Module).initAttributes
- (cap, definingRow, sourceTableId, attributeType);
- }
-
- //##########################################################################
-
- private class PEFieldInfo extends FieldInfo {
- private final int definingRow;
- public PEFieldInfo(int definingRow, String name,
- int attrs, PECustomMod pecmod, Object value)
- {
- super(name, PEType.this, attrs, pecmod, value);
- this.definingRow = definingRow;
- }
- protected void loadCustomAttributes(Type attributeType) {
- PEType.this.initAttributes
- (this, definingRow, Table.FieldDef.ID, attributeType);
- }
- }
-
- private class PEMethodInfo extends MethodInfo {
- private final int definingRow;
- public PEMethodInfo(int row, String name,
- int attrs, Type retType, ParameterInfo[] params)
- {
- super(name, PEType.this, attrs, retType, params);
- this.definingRow = row;
- }
- protected void loadCustomAttributes(Type attributeType) {
- PEType.this.initAttributes
- (this, definingRow, Table.MethodDef.ID, attributeType);
- }
- }
-
- private class PEConstructorInfo extends ConstructorInfo {
- private final int definingRow;
- public PEConstructorInfo(int row, int attrs, ParameterInfo[] params) {
- super(PEType.this, attrs, params);
- this.definingRow = row;
- }
- protected void loadCustomAttributes(Type attributeType) {
- PEType.this.initAttributes
- (this, definingRow, Table.MethodDef.ID, attributeType);
- }
- }
-
- private class PEPropertyInfo extends PropertyInfo {
- private final int definingRow;
- public PEPropertyInfo(int row, String name, short attrs, Type propType,
- MethodInfo getter, MethodInfo setter)
- {
- super(name, PEType.this, attrs, propType, getter, setter);
- this.definingRow = row;
- }
- protected void loadCustomAttributes(Type attributeType) {
- PEType.this.initAttributes
- (this, definingRow, Table.PropertyDef.ID, attributeType);
- }
- }
-
- private class PEEventInfo extends EventInfo {
- private final int definingRow;
- public PEEventInfo(int row, String name, short attrs, Type handler,
- MethodInfo add, MethodInfo remove)
- {
- super(name, PEType.this, attrs, handler, add, remove);
- this.definingRow = row;
- }
- protected void loadCustomAttributes(Type attributeType) {
- PEType.this.initAttributes
- (this, definingRow, Table.EventDef.ID, attributeType);
- }
- }
-
- //##########################################################################
-
-} // class PEType
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/ParameterAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/ParameterAttributes.java
deleted file mode 100644
index d4360363fc..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/ParameterAttributes.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Defines the attributes that may be associated with a parameter.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class ParameterAttributes {
-
- // just to make the class uninstantiable
- private ParameterAttributes() {}
-
- //##########################################################################
-
- /** Specifies that there is no parameter attribute. */
- public static final short None = 0x0000;
-
- /** Specifies that the parameter is an input parameter. */
- public static final short In = 0x0001;
-
- /** Specifies that the parameter is an output parameter. */
- public static final short Out = 0x0002;
-
- /** Specifies that the parameter is a locale identifier. */
- public static final short Lcid = 0x0004;
-
- /** Specifies that the parameter is a return value. */
- public static final short Retval = 0x0008;
-
- /** Specifies that the parameter is optional.
- * Attention: In the specification the value is 0x0004 but
- * in mscorlib.dll that it Lcid and Optional is 0x0010
- */
- public static final short Optional = 0x0010;
-
- /** Specifies that the parameter has a default value. */
- public static final short HasDefault = 0x1000;
-
- /** Specifies that the parameter has field marshaling information. */
- public static final short HasFieldMarshal = 0x2000;
-
- /** Reserved. */
- public static final short Reserved3 = 0x4000;
-
- /** Reserved. */
- public static final short Reserved4 = (short)0x8000;
-
- /** Specifies that the parameter is reserved. */
- public static final short ReservedMask = (short)0xf000;
-
- /** Reserved: shall be zero in all conforming implementations. */
- public static final short Unused = (short) 0xcfe0;
-
- public static final String toString(int attrs) {
- StringBuffer s = new StringBuffer();
- if ((attrs & In) != 0) s.append("in ");
- if ((attrs & Out) != 0) s.append("out ");
- if ((attrs & Optional) != 0) s.append("opt ");
- if ((attrs & HasDefault) != 0) s.append("default(???) ");
- if ((attrs & HasFieldMarshal) != 0) s.append("marshal(???) ");
- return s.toString();
- }
-
- //##########################################################################
-
-} // class ParameterAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/ParameterInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/ParameterInfo.java
deleted file mode 100644
index 877d7aa8a5..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/ParameterInfo.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Discovers the attributes of a parameter and provides access to
- * parameter metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class ParameterInfo extends CustomAttributeProvider {
-
- //##########################################################################
-
- /** Attributes of the parameter. */
- public final short Attributes;
-
- /** Name of the parameter. */
- public final String Name;
-
- /** Type of the parameter. */
- public final Type ParameterType;
-
- /** Position of the parameter in the parameter list. */
- public final int Position;
-
- //##########################################################################
-
- /** Is this an input parameter? */
- public final boolean IsIn() {
- return (Attributes & ParameterAttributes.In) != 0;
- }
-
- /** Is this an output parameter? */
- public final boolean IsOut() {
- return (Attributes & ParameterAttributes.Out) != 0;
- }
-
- /** Is this an Lcid? */
- public final boolean IsLcid() {
- return (Attributes & ParameterAttributes.Lcid) != 0;
- }
-
- /** Is this a return value? */
- public final boolean IsRetval() {
- return (Attributes & ParameterAttributes.Retval) != 0;
- }
-
- /** Is this an optional parameter? */
- public final boolean IsOptional() {
- return (Attributes & ParameterAttributes.Optional) != 0;
- }
-
- //##########################################################################
- // members not part of the public Reflection.ParameterInfo interface
-
- /** Initializes a new instance of the ParameterInfo class. */
- protected ParameterInfo(String name, Type type, int attr, int pos) {
- Name = name;
- ParameterType = type;
- Attributes = (short)attr;
- Position = pos;
- }
-
- public String toString() {
- return ParameterAttributes.toString(Attributes) + ParameterType + " "
- + Name;
- }
-
- //##########################################################################
-
-} // class ParameterInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PrimitiveType.java b/src/msil/ch/epfl/lamp/compiler/msil/PrimitiveType.java
deleted file mode 100644
index b19fe29869..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PrimitiveType.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package ch.epfl.lamp.compiler.msil;
-
-import ch.epfl.lamp.compiler.msil.util.PECustomMod;
-
-public final class PrimitiveType extends Type {
- public PrimitiveType(Module module,
- int attributes,
- String fullName,
- Type baseType,
- Type[] interfaces,
- Type declType,
- int auxAttr,
- Type elemType) {
- super(module, attributes, fullName,
- baseType, interfaces, declType, auxAttr, elemType);
- clearMembers();
- }
-
- public void clearMembers() {
- fields = FieldInfo.EMPTY_ARRAY;
- methods = MethodInfo.EMPTY_ARRAY;
- constructors = ConstructorInfo.EMPTY_ARRAY;
- events = EventInfo.EMPTY_ARRAY;
-
- initBaseType();
- initInterfaces();
-
- initFields();
- initMethods();
- initEvents();
- initProperties();
- initNestedTypes();
- }
-
- public FieldInfo addField(String name, int attrs, Type fieldType) {
- PECustomMod fieldTypeWithMods = new PECustomMod(fieldType, null);
- FieldInfo res = new FieldInfo(name, this, attrs, fieldTypeWithMods, null);
- FieldInfo[] ms = new FieldInfo[fields.length + 1];
- System.arraycopy(fields, 0, ms, 0, fields.length);
- ms[ms.length - 1] = res;
- fields = ms;
- return res;
- }
-
- public MethodInfo addMethod(String name, int attrs, Type returnType, Type[] paramTypes) {
- MethodInfo res = new MethodInfo(name, this, attrs, returnType, paramTypes);
- MethodInfo[] ms = new MethodInfo[methods.length + 1];
- System.arraycopy(methods, 0, ms, 0, methods.length);
- ms[ms.length - 1] = res;
- return res;
- }
-
- public ConstructorInfo addConstructor(int attrs, Type[] paramTypes) {
- ConstructorInfo res = new ConstructorInfo(this, attrs, paramTypes);
- ConstructorInfo[] ms = new ConstructorInfo[constructors.length + 1];
- System.arraycopy(constructors, 0, ms, 0, constructors.length);
- ms[ms.length - 1] = res;
- return res;
- }
-
-}
-
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PropertyAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/PropertyAttributes.java
deleted file mode 100644
index b1bec64aff..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PropertyAttributes.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Attributes applcicable to properties
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class PropertyAttributes {
-
- // makes the class uninstantiable
- private PropertyAttributes() {}
-
- //##########################################################################
-
- /** Specifies that the property is special, with the name describing
- * how the property is special.
- */
- public static final short SpecialName = 0x0200;
-
- /** Specifies that the metadata internal APIs check the name encoding.
- */
- public static final short RTSpecialName = 0x0400;
-
- /** Specifies that the property has a default value.
- */
- public static final short HasDefault = 0x1000;
-
- //##########################################################################
-
- public static String toString(short attrs) {
- StringBuffer str = new StringBuffer();
- if ((attrs & SpecialName) != 0) str.append("specialname ");
- if ((attrs & RTSpecialName) != 0) str.append("rtspecialname ");
- return str.toString();
- }
-
- //##########################################################################
-
-} // class PropertyAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/PropertyInfo.java b/src/msil/ch/epfl/lamp/compiler/msil/PropertyInfo.java
deleted file mode 100644
index 4b7cef8bc1..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/PropertyInfo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Discovers the attributes of a property
- * and provides access to property metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public class PropertyInfo extends MemberInfo {
-
- //##########################################################################
-
- public final int MemberType() { return MemberTypes.Property; }
-
- public final short Attributes;
-
- public final boolean CanRead;
-
- public final boolean CanWrite;
-
- public final Type PropertyType;
-
- /** Returns an array of the public get and set accessors for this property.
- */
- public MethodInfo[] GetAccessors() {
- return GetAccessors(false);
- }
-
- /** Returns an array of the public or non-public <b>get</b>
- * and <b>set</b> accessors for this property.
- */
- public MethodInfo[] GetAccessors(boolean nonPublic) {
- MethodInfo getter = GetGetMethod(nonPublic);
- MethodInfo setter = GetSetMethod(nonPublic);
- if (getter == null)
- if (setter == null) return MethodInfo.EMPTY_ARRAY;
- else return new MethodInfo[]{setter};
- else if (setter == null) return new MethodInfo[] {getter};
- else return new MethodInfo[] {getter, setter};
- }
-
- /** Returns the public <b>get</b> accessor for this property.
- */
- public MethodInfo GetGetMethod() {
- return GetGetMethod(false);
- }
-
- /** Returns the public or non-public <b>get</b> accessor for this property.
- */
- public MethodInfo GetGetMethod(boolean nonPublic) {
- return nonPublic ? getter
- : getter == null || getter.IsPublic() ? getter : null;
- }
-
- /** Returns the public <b>set</b> accessor for this property.
- */
- public MethodInfo GetSetMethod() {
- return GetSetMethod(false);
- }
-
- /** Returns the public or non-public <b>set</b> accessor for this property.
- */
- public MethodInfo GetSetMethod(boolean nonPublic) {
- return nonPublic ? setter
- : setter == null || setter.IsPublic() ? setter : null;
- }
-
- public String toString() {
- MethodInfo m = getter != null ? getter : setter;
- return MethodAttributes.accessFlagsToString
- ((getter != null ? getter : setter).Attributes)
- + " " + PropertyAttributes.toString(Attributes)
- + DeclaringType + "::" + Name;
- }
-
- //##########################################################################
- // protected members
-
- protected static final PropertyInfo[] EMPTY_ARRAY = new PropertyInfo[0];
-
- protected MethodInfo getter;
- protected MethodInfo setter;
-
- protected PropertyInfo(String name, Type declType, short attr,
- Type propType, MethodInfo getter, MethodInfo setter)
- {
- super(name, declType);
- Attributes = attr;
- PropertyType = propType;
- this.getter = getter;
- this.setter = setter;
- CanRead = getter != null;
- CanWrite = setter != null;
- }
-
- //##########################################################################
-
-} // class PropertyInfo
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Type.java b/src/msil/ch/epfl/lamp/compiler/msil/Type.java
deleted file mode 100644
index 830632ce45..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/Type.java
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Arrays;
-
-/**
- * Represents type declarations: class types, interface types, array types,
- * value types, and enumeration types.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class Type extends MemberInfo {
-
- private java.util.List /* GenericParamAndConstraints */ tVars = new java.util.LinkedList();
- private GenericParamAndConstraints[] sortedTVars = null;
-
- public void addTVar(GenericParamAndConstraints tvarAndConstraints) {
- sortedTVars = null;
- tVars.add(tvarAndConstraints);
- }
-
- public GenericParamAndConstraints[] getSortedTVars() {
- if(sortedTVars == null) {
- sortedTVars = new GenericParamAndConstraints[tVars.size()];
- for (int i = 0; i < sortedTVars.length; i ++){
- Iterator iter = tVars.iterator();
- while(iter.hasNext()) {
- GenericParamAndConstraints tvC = (GenericParamAndConstraints)iter.next();
- if(tvC.Number == i) {
- sortedTVars[i] = tvC;
- }
- }
- }
- }
- return sortedTVars;
- }
-
-
- //##########################################################################
- // public static members
-
- /** Empty array of type Type. */
- public static final Type[] EmptyTypes = new Type[0];
-
- /** Separates names in the namespace of the Type. */
- public static final char Delimiter = '.';
-
- //##########################################################################
- // public properties
-
- /** The fully qualified name of the Type. */
- public final String FullName;
-
- /** The namespace of the Type. */
- public final String Namespace;
-
- /** The type from which the current Type directly inherits. */
- public final Type BaseType() {
- initBaseType();
- return baseType;
- }
- protected Type baseType;
-
- /** The attributes associated with the Type. */
- public final int Attributes;
-
- /** The sssembly that the type is declared in. */
- public final Assembly Assembly() { return Module.Assembly; }
-
- /** The module (the EXE/DLL) in which the current Type is defined. */
- public final Module Module;
-
- public final int MemberType() {
- return DeclaringType == null
- ? MemberTypes.TypeInfo : MemberTypes.NestedType;
- }
-
- //##########################################################################
- // internal members
-
- // Fields declared by this class
- protected FieldInfo[] fields;
-
- // Methods declared by this class
- protected MethodInfo[] methods;
-
- // Constructors of this class
- protected ConstructorInfo[] constructors;
-
- // Properties of the class
- protected PropertyInfo[] properties;
-
- // Events of the class
- protected EventInfo[] events;
-
- // Interfaces implemented by this class
- protected Type[] interfaces;
-
- // Nested types declared by this class
- protected Type[] nestedTypes;
-
- // holds the element type of array, pointer and byref types
- private final Type elemType;
-
- // the underlying type of an enumeration. null if the type is not enum.
- protected Type underlyingType;
-
- protected int auxAttr;
-
- //##########################################################################
- // Map with all the types known so far and operations on it
-
- private static final Map types = new HashMap();
-
- protected static Type getType(String name) {
- return (Type) types.get(name);
- }
-
- protected static Type addType(Type t) {
- assert(!(t instanceof TMVarUsage));
- assert(!(t instanceof ConstructedType));
- Type oldType = (Type) types.put(t.FullName, t);
-// if (oldType != null)
-// throw new RuntimeException("The type: [" + t.Assembly + "]" + t
-// + " replaces the type: [" +
-// oldType.Assembly + "]" + oldType);
- return t;
- }
-
- //##########################################################################
-
- /** The main constructor. */
- protected Type(Module module,
- int attr,
- String fullName,
- Type baseType,
- Type[] interfaces,
- Type declType,
- int auxAttr,
- Type elemType)
- {
- super(fullName.lastIndexOf(Delimiter) < 0 ? fullName :
- fullName.substring(fullName.lastIndexOf(Delimiter) + 1,
- fullName.length()),
- declType);
-
- Module = module; // null only for TMVarUsage and for PrimitiveType
- Attributes = attr;
- this.baseType = baseType;
- if (DeclaringType == null) {
- FullName = fullName;
- int i = FullName.lastIndexOf(Delimiter);
- Namespace = (i < 0) ? "" : FullName.substring(0,i);
- } else {
- FullName = declType.FullName + "+" + fullName;
- Namespace = DeclaringType.Namespace;
- }
-
- this.interfaces = interfaces;
- this.elemType = elemType;
- this.auxAttr = auxAttr;
- }
-
- public final boolean IsAbstract() {
- return (Attributes & TypeAttributes.Abstract) != 0;
-
- }
- public final boolean IsPublic() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.Public;
- }
-
- public final boolean IsNotPublic() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NotPublic;
- }
-
- public final boolean IsNestedPublic() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedPublic;
- }
-
- public final boolean IsNestedPrivate() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedPrivate;
- }
-
- public final boolean IsNestedFamily() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedFamily;
- }
-
- public final boolean IsNestedAssembly() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedAssembly;
- }
-
- public final boolean IsNestedFamORAssem() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedFamORAssem;
- }
-
- public final boolean IsNestedFamANDAssem() {
- return (Attributes & TypeAttributes.VisibilityMask)
- == TypeAttributes.NestedFamANDAssem;
- }
-
- public final boolean IsSealed() {
- return (Attributes & TypeAttributes.Sealed) != 0;
- }
-
- public final boolean IsSpecialName() {
- return (Attributes & TypeAttributes.SpecialName) != 0;
- }
-
- public final boolean IsClass() {
- return (Attributes & TypeAttributes.ClassSemanticsMask)
- == TypeAttributes.Class;
- }
-
- public final boolean IsInterface(){
- return (Attributes & TypeAttributes.ClassSemanticsMask)
- == TypeAttributes.Interface;
- }
-
- public final boolean IsAutoLayout() {
- return (Attributes & TypeAttributes.LayoutMask)
- == TypeAttributes.AutoLayout;
- }
- public final boolean IsExplictitLayout() {
- return (Attributes & TypeAttributes.LayoutMask)
- == TypeAttributes.ExplicitLayout;
- }
- public final boolean IsLayoutSequential() {
- return (Attributes & TypeAttributes.LayoutMask)
- == TypeAttributes.SequentialLayout;
- }
-
- public final boolean IsImport() {
- return (Attributes & TypeAttributes.Import) != 0;
- }
- public final boolean IsSerializable() {
- return (Attributes & TypeAttributes.Serializable) != 0;
- }
-
- public final boolean IsAnsiClass() {
- return (Attributes & TypeAttributes.StringFormatMask)
- == TypeAttributes.AnsiClass;
- }
-
- public final boolean IsUnicodeClass() {
- return (Attributes & TypeAttributes.StringFormatMask)
- == TypeAttributes.UnicodeClass;
- }
- public final boolean IsAutoClass() {
- return (Attributes & TypeAttributes.StringFormatMask)
- == TypeAttributes.AutoClass;
- }
-
- public final boolean IsArray() {
- return (auxAttr & AuxAttr.Array) != 0;
- }
- public final boolean IsByRef() {
- return (auxAttr & AuxAttr.ByRef) != 0;
- }
- public final boolean IsPointer() {
- return (auxAttr & AuxAttr.Pointer) != 0;
- }
- public final boolean IsPrimitive() {
- return (auxAttr & AuxAttr.Primitive) != 0;
- }
- public final boolean IsValueType() {
- return BaseType() == VALUE_TYPE() || IsEnum();
- }
- public final boolean IsEnum() {
- return BaseType() == ENUM();
- }
- public boolean CanBeTakenAddressOf() {
- /* TODO should be overridden in TMVarUsage,
- but there's currently no way to bind a TMVarUsage to its GenericParamAndConstraints definition. Why?
- Because of the way the msil library is organized (e.g., mkArray() returns the same !0[] representation
- for all !0[] usages, irrespective of the scope of the !0 type-param)
- This in turn is so because without generics there's no harm in using a type-def instance
- where a type-ref should go (e.g., the ParameterType of a ParameterInfo nowadays may point to a PEType).
- The net effect is that this method (CanBeTakenAddressOf) is conservative, it will answer "no"
- for example for !0 where !0 refers to a type-param with the isValuetype constraint set.
- The whole thing is ok at this point in time, where generics are not supported at the backend. */
- return IsValueType() && (this != ENUM());
- /* ENUM() is a singleton, i.e. System.Enum is not generic */
- }
-
- /** IsGeneric, true for a PEType or TypeBuilder (i.e., a type definition)
- * containing one or more type params. Not to be called on a reference
- * to a constructed type. */
- public final boolean IsGeneric() {
- return tVars.size() > 0;
- }
-
- public final boolean HasElementType() {
- return IsArray() || IsPointer() || IsByRef();
- }
-
- public boolean IsTMVarUsage() {
- // overridden in TMVarUsage
- return false;
- }
-
- public boolean IsNestedType() {
- return DeclaringType != null;
- }
-
- public boolean IsDefinitelyInternal() {
- if(IsNestedType()) {
- return IsNestedPrivate();
- } else {
- return IsNotPublic();
- }
- }
-
- //public final boolean IsCOMObject;
- //public final boolean IsContextful;
- //public final boolean IsMarshalByRef;
-
- protected Type(Module module,
- int attr,
- String fullName,
- Type baseType,
- Type[] interfaces,
- Type declType,
- int auxAttr)
- {
- this(module, attr, fullName, baseType, interfaces,
- declType, auxAttr, null);
- }
-
- //##########################################################################
-
- public static final class TMVarUsage extends Type {
-
- public final int Number;
- public final boolean isTVar;
-
- /** Non-defining reference to either a TVar or an MVar.
- * An instance of GenericParamAndConstraints represents a TVar or an MVar definition. */
- public TMVarUsage(int Number, boolean isTVar) {
- super(null, 0, ((isTVar ? "!" : "!!") + Number), null, null, null, AuxAttr.None, null);
- this.Number = Number;
- this.isTVar = isTVar;
- }
-
- public String toString() {
- return (isTVar ? "!" : "!!") + Number;
- }
-
- public final boolean IsTMVarUsage() {
- return true;
- }
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- TMVarUsage that = (TMVarUsage) o;
-
- if (Number != that.Number) return false;
- if (isTVar != that.isTVar) return false;
-
- return true;
- }
-
- public int hashCode() {
- int result = Number;
- result = 31 * result + (isTVar ? 1 : 0);
- return result;
- }
- }
-
- protected static final class AuxAttr {
- public static final int None = 0x0000;
- public static final int Array = 0x0001;
- public static final int ByRef = 0x0002;
- public static final int Pointer = 0x0008;
- public static final int Primitive = 0x0010;
- }
-
- /***/
- public static Type mkArray(Type elemType, int rank) {
- StringBuffer arrSig = new StringBuffer("[");
- for (int i = 0; i < rank; i++) {
- if (i > 0) arrSig.append(',');
- }
- arrSig.append(']');
- Type array = getType(elemType.FullName + arrSig);
- if (array != null)
- return array;
- array = new PrimitiveType(elemType.Module,
- elemType.Attributes
- | TypeAttributes.Sealed
- | TypeAttributes.Serializable,
- elemType.FullName + arrSig,
- ARRAY(), EmptyTypes, null,
- AuxAttr.Array, elemType);
- return addType(array);
- }
-
- /***/
- public static Type mkPtr(Type elemType) {
- String name = elemType.FullName + "*";
- Type type = getType(name);
- if (type != null) return type;
- type = new PrimitiveType(elemType.Module,
- elemType.Attributes,
- name, null, EmptyTypes, null,
- AuxAttr.Pointer, elemType);
- return addType(type);
- }
-
- /***/
- public static Type mkByRef(Type elemType) {
- String name = elemType.FullName + "&";
- Type type = getType(name);
- if (type != null) return type;
- type = new PrimitiveType(elemType.Module,
- elemType.Attributes,
- name, null, EmptyTypes, null,
- AuxAttr.ByRef, elemType);
- return addType(type);
- }
-
- //##########################################################################
- // public methods
-
- /**
- * Return the type with the specified signature parameters.
- * For example, the fully qualified name for a class might look like this:
- * TopNamespace.SubNameSpace.ContainingClass+NestedClass,MyAssembly
- */
- public static Type GetType(String fullName) {
- Type type = getType(fullName);
- if (type != null) return type;
-
- // check if it's an array type; TODO: make array type handling more robust
- int i = fullName.lastIndexOf('[');
- int j = fullName.lastIndexOf(']');
- if (i >= 0)
- if (j > i && j == (fullName.length() - 1)) {
- String elementTypeName = fullName.substring(0, i);
- Type elementType = GetType(elementTypeName);
- if (elementType == null)
- throw new RuntimeException
- ("Unknown element type '" + elementTypeName +
- "' for the array type: " + fullName);
- int rank = j - i;
- for (int k = i + 1; k < j; k++) {
- if (fullName.charAt(k) != ',')
- throw new RuntimeException
- ("Malformed type name: " + fullName);
- }
- return mkArray(elementType, rank);
- } else
- throw new RuntimeException("Malformed type name: " + fullName);
-
- // check if it's a pointer type
- if (fullName.charAt(fullName.length() - 1) == '*')
- return addType
- (mkPtr(GetType(fullName.substring(0, fullName.length()-1))));
-
- // check if it's a nested class
- i = fullName.lastIndexOf('+');
- if (i > 0) {
- if (i == 0 || i == (fullName.length() - 1))
- throw new RuntimeException("malformedTypeName");
- Type enclosing = GetType(fullName.substring(0, i));
- return enclosing == null ? null
- : enclosing.GetNestedType(fullName.substring(i + 1));
- }
-
- //System.out.println("Looking for type: " + fullName + " (" + fullName.length() + ")");
- // try in the assemblies
- Iterator assems = ch.epfl.lamp.compiler.msil.Assembly.
- assemblies.values().iterator();
- while (type == null && assems.hasNext()) {
- Assembly assem = ((Assembly) assems.next());
- type = assem.GetType(fullName);
- //System.out.println("\tin assemby " + assem + " -> " + type);
- }
-
- Type type2 = getType(fullName);
- if (type == type2) return type;
- return type == null ? null : addType(type);
- }
-
- /**
- * @return the type of the object encompassed or referenced to
- * by the current array, pointer or reference type.
- */
- public Type GetElementType() {
- return elemType;
- }
-
- /**
- * @return the type underlying an enumeration type.
- */
- public Type getUnderlyingType() {
- if (!IsEnum()) return null;
- // this would force the loading of the underlying type from the
- // the type of the value__ field of the enumeration
- initFields();
- return underlyingType;
- }
-
- //##########################################################################
- // GetField/s/
-
- /** Searches for the field with the specified name. */
- public FieldInfo GetField(String name) {
- initFields();
- for (int i = 0; i < fields.length; i++)
- if (fields[i].Name.equals(name) && !fields[i].IsPrivate())
- return fields[i];
- return null;
- }
-
- /**
- */
- public FieldInfo GetField(String name, int bindingFlags) {
- FieldInfo[] fields = this.GetFields(bindingFlags);
- for (int i = 0; i < fields.length; i++)
- if (name.equals(fields[i].Name))
- return fields[i];
- return null;
- }
-
- /** Gets the fields of the current Type. */
- public FieldInfo[] GetFields() {
- return GetFields(BindingFlags.Instance | BindingFlags.Public);
- }
-
- /**
- */
- public FieldInfo[] GetFields(int bindingFlags) {
- initFields();
- final FieldInfo[] fields =
- getAllFields((bindingFlags & BindingFlags.DeclaredOnly) != 0);
- final boolean getInstance = (bindingFlags & BindingFlags.Instance) != 0;
- final boolean getStatic = (bindingFlags & BindingFlags.Static) != 0;
- final boolean getPublic = (bindingFlags & BindingFlags.Public) != 0;
- final boolean getNonPublic =
- (bindingFlags & BindingFlags.NonPublic) != 0;
-
- int cnt = 0;
- for (int i = 0; i < fields.length; i++) {
- FieldInfo field = fields[i];
- boolean accessible = (getPublic && field.IsPublic())
- || (getNonPublic && !field.IsPublic());
- if (accessible
- // strip off the private fields up the hierarchy
- && ((field.DeclaringType == this)
- || ((field.DeclaringType != this) && !field.IsPrivate()))
- && ((getInstance && !field.IsStatic())
- || ((getStatic && field.IsStatic()) &&
- (field.DeclaringType == this
- || (bindingFlags & BindingFlags.FlattenHierarchy) != 0))
- )
- )
- fields[cnt++] = field;
- }
- FieldInfo [] resFields = new FieldInfo[cnt];
- System.arraycopy(fields, 0, resFields, 0, cnt);
- return resFields;
- }
-
- protected FieldInfo[] getAllFields(boolean declaredOnly) {
- initFields();
- FieldInfo [] inherited = BaseType() == null || declaredOnly
- ? FieldInfo.EMPTY_ARRAY
- : BaseType().getAllFields(declaredOnly);
- FieldInfo[] allFields =
- new FieldInfo[inherited.length + this.fields.length];
- System.arraycopy(inherited, 0, allFields, 0, inherited.length);
- System.arraycopy(this.fields, 0,
- allFields, inherited.length, this.fields.length);
- return allFields;
- }
-
- //##########################################################################
- // GetConstructor/s/
-
- /** Searches for a public instance constructor whose parameters
- * match the types in the specified array. */
- public ConstructorInfo GetConstructor(Type[] paramTypes) {
- initMethods();
- for (int i = 0; i < constructors.length; i++) {
- if (equalParameters(constructors[i].GetParameters(), paramTypes))
- return constructors[i];
- }
- return null;
- }
-
- /** Returns all public instance constructors defined for the current Type.*/
- public ConstructorInfo[] GetConstructors() {
- return GetConstructors(BindingFlags.Instance | BindingFlags.Public);
- }
-
- /***/
- public ConstructorInfo[] GetConstructors(int bindingFlags) {
- initMethods();
- final boolean getInstance = (bindingFlags & BindingFlags.Instance) != 0;
- final boolean getStatic = (bindingFlags & BindingFlags.Static) != 0;
- final boolean getPublic = (bindingFlags & BindingFlags.Public) != 0;
- final boolean getNonPublic =
- (bindingFlags & BindingFlags.NonPublic) != 0;
-
- ConstructorInfo[] constrs =
- new ConstructorInfo[this.constructors.length];
- int cnt = 0;
- for (int i = 0; i < this.constructors.length; i++) {
- ConstructorInfo constr = this.constructors[i];
- boolean accessible = (getPublic && constr.IsPublic())
- || (getNonPublic && !constr.IsPublic());
- if (accessible
- && ((getInstance && !constr.IsStatic())
- || (getStatic && constr.IsStatic())))
- constrs[cnt++] = constr;
- }
- ConstructorInfo [] resConstrs = new ConstructorInfo[cnt];
- System.arraycopy(constrs, 0, resConstrs, 0, cnt);
- return resConstrs;
- }
-
- //##########################################################################
- // GetMethod/s/
-
- /** Searches for the specified public method whose parameters
- * match the specified argument types. */
- public MethodInfo GetMethod(String name, Type[] paramTypes) {
- return GetMethod(name, paramTypes, null);
- }
-
- public MethodInfo GetMethod(String name, Type[] paramTypes, Type retType) {
- initMethods();
- MethodInfo method = findMethod(methods, name, paramTypes, retType);
- if (method != null)
- return method;
- if (BaseType() != null) {
- method = BaseType().GetMethod(name, paramTypes, retType);
- if (method != null)
- return method;
- }
-// StringBuffer str = new StringBuffer(name);
-// str.append('(');
-// for (int i = 0; i < paramTypes.length; i++) {
-// if (i > 0) str.append(", ");
-// str.append(paramTypes[i]);
-// }
-// str.append(')');
-// System.out.println("Cannot find method " + str + ":");
-// System.out.println("Methods of class " + this);
-// for (int i = 0; i < methods.length; i++)
-// System.out.println("\t" + methods[i]);
- return null;
- }
-
- /**
- */
- protected static MethodInfo findMethod(MethodInfo[] methods,
- String name,
- Type[] paramTypes,
- Type retType)
- {
- for (int i = 0; i < methods.length; i++)
- if (name.equals(methods[i].Name)
- && equalParameters(methods[i].GetParameters(), paramTypes)
- && (retType == null || methods[i].ReturnType == retType))
- return methods[i];
- return null;
- }
-
- /**
- */
- protected static boolean equalParameters(ParameterInfo[] params,
- Type[] paramTypes)
- {
- if (params.length != paramTypes.length)
- return false;
- for (int i = 0; i < params.length; i++) {
-// System.out.println(params[i].ParameterType + " == " + paramTypes[i]
-// + " = " + (params[i].ParameterType == paramTypes[i]));
- if (params[i].ParameterType != paramTypes[i])
- return false;
- }
- return true;
- }
-
- /**
- */
- public MethodInfo GetMethod(String name, Type[] paramTypes, int bindingFlags) {
- MethodInfo[] methods = GetMethods(bindingFlags);
- MethodInfo method = findMethod(methods, name, paramTypes, null);
- if (method == null) {
- StringBuffer str = new StringBuffer(name);
- str.append('(');
- for (int i = 0; i < paramTypes.length; i++) {
- if (i > 0) str.append(", ");
- str.append(paramTypes[i]);
- }
- str.append(')');
- System.out.println("Cannot find method " + str + ":");
- System.out.println("Methods of class " + this);
- for (int i = 0; i < methods.length; i++)
- System.out.println("\t" + methods[i]);
- }
- return method;
- }
-
- /** Returns all public methods of the current Type. */
- public MethodInfo[] GetMethods() {
- return GetMethods(BindingFlags.Instance | BindingFlags.Public);
- }
-
- /**
- */
- public MethodInfo[] GetMethods(int bindingFlags) {
- initMethods();
- final MethodInfo[] methods =
- getAllMethods((bindingFlags & BindingFlags.DeclaredOnly) != 0);
- //System.out.println("" + this + ".GetMethods(int) -> " + methods.length);
- final boolean getInstance = (bindingFlags & BindingFlags.Instance) != 0;
- final boolean getStatic = (bindingFlags & BindingFlags.Static) != 0;
- final boolean getPublic = (bindingFlags & BindingFlags.Public) != 0;
- final boolean getNonPublic =
- (bindingFlags & BindingFlags.NonPublic) != 0;
-
- int cnt = 0;
- for (int i = 0; i < methods.length; i++) {
- MethodInfo method = methods[i];
- boolean accessible = (getPublic && method.IsPublic())
- || (getNonPublic && !method.IsPublic());
- if (accessible
- // strip off the private methods up the hierarchy
- && ((method.DeclaringType == this)
- || ((method.DeclaringType != this) && !method.IsPrivate()))
- && ((getInstance && !method.IsStatic())
- || ((getStatic && method.IsStatic()) &&
- (method.DeclaringType == this
- || (bindingFlags & BindingFlags.FlattenHierarchy) != 0))
- )
- )
- methods[cnt++] = method;
- }
- MethodInfo [] resMethods = new MethodInfo[cnt];
- System.arraycopy(methods, 0, resMethods, 0, cnt);
- return resMethods;
- }
-
- protected MethodInfo[] getAllMethods(boolean declaredOnly) {
- initMethods();
- MethodInfo[] inherited = BaseType() == null || declaredOnly
- ? MethodInfo.EMPTY_ARRAY
- : BaseType().getAllMethods(declaredOnly);
- MethodInfo[] allMethods =
- new MethodInfo[inherited.length + this.methods.length];
- System.arraycopy(inherited, 0, allMethods, 0, inherited.length);
- System.arraycopy(this.methods, 0,
- allMethods, inherited.length, this.methods.length);
- return allMethods;
- }
-
- //##########################################################################
- // GetProperty/ies/
-
- /** Returns all public properties of the current Type.
- */
- public PropertyInfo[] GetProperties() {
- initProperties();
- return (PropertyInfo[]) properties.clone();
- }
-
- /** Returns the properties of the current class
- * that satisfy the binding constrints.
- */
- public PropertyInfo[] GetProperties(int bindingFlags) {
- initProperties();
- return (PropertyInfo[]) properties.clone();
- }
-
- /** Returns the public property with the given name.
- */
- public PropertyInfo GetProperty(String name) {
- initProperties();
- for (int i = 0; i < properties.length; i++)
- if (name.equals(properties[i].Name))
- return properties[i];
- return null;
- }
-
- /** Returns the property with the given name
- * that satisfies the binding constraints.
- */
- public PropertyInfo GetProperty(String name, int bindingFlags) {
- throw new RuntimeException("Method not implemented yet");
- }
-
- //##########################################################################
- // GetEvent(s)
-
- public EventInfo[] GetEvents() {
- initEvents();
- return (EventInfo[]) events.clone();
- }
-
- //##########################################################################
- // GetNestedType/s/
-
- /** Searches for nested type with the specified name. */
- public Type GetNestedType(String name) {
- initNestedTypes();
- for (int i = 0; i < nestedTypes.length; i++)
- if (nestedTypes[i].Name.equals(name))
- return nestedTypes[i];
- return null;
- }
-
- /** Returns all types nested within the current Type. */
- public Type[] GetNestedTypes() {
- initNestedTypes();
- return (Type[]) nestedTypes.clone();
- }
-
- //##########################################################################
- // GetInterface/s/
-
- /** Searches for an Interface with the given name implemented by this type
- */
- public Type GetInterface(String name) {
- return GetInterface(name, false);
- }
-
- /** Searches for the specified interface,
- * specifying whether to do a case-sensitive search.
- * @param name - the name of the interface to get
- * @param ignoreCase <b>true</b> to perform a case-insensitive search for name
- * <b>false</b> to perform a case-sensitive search for name
- * @return A Type object representing the interface with the specified name,
- * implemented or inherited by the current Type, if found;
- * otherwise, a null reference
- */
- public Type GetInterface(String name, boolean ignoreCase) {
- initInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- Type iface = interfaces[i];
- if (ignoreCase) {
- if (name.equalsIgnoreCase(iface.Name)) return iface;
- if (name.equalsIgnoreCase(iface.FullName)) return iface;
- } else {
- if (name.equals(iface.Name)) return iface;
- if (name.equals(iface.FullName)) return iface;
- }
- }
- return BaseType() == null ? null
- : BaseType().GetInterface(name, ignoreCase);
- }
-
- /** Returns the interfaces implemented or inherited by the current Type. */
- public Type[] GetInterfaces() {
- initInterfaces();
- if (BaseType() == null) return interfaces;
-
- Type[] ifaces = interfaces;
- int count = 0;
- for (int i = 0; i < interfaces.length; i++) {
- if (BaseType().GetInterface(interfaces[i].FullName) == null)
- ifaces[count++] = ifaces[i];
- }
- Type[] baseTypeIfaces = BaseType().GetInterfaces();
-
- Type[] res = new Type[baseTypeIfaces.length + count];
- System.arraycopy(baseTypeIfaces, 0, res, 0, baseTypeIfaces.length);
- System.arraycopy(ifaces, 0, res, baseTypeIfaces.length, count);
-
- return res;
- }
-
-
- public boolean isSubtypeOf(Type that) {
- if (this == that || BaseType() == that || that == OBJECT()) return true;
- initInterfaces();
- for (int i = 0; i < interfaces.length; i++)
- if (interfaces[i].isSubtypeOf(that))
- return true;
- boolean res = BaseType() == null ? false : BaseType().isSubtypeOf(that);
-// if (!res) {
-// System.out.println(dumpType(this) + " not a subtype of " +
-// dumpType(that));
-// }
- return res;
- }
-
- private static String formatType(Type t) {
- if (t == null) return "<null>";
- String cname = t.getClass().getName();
- int k = cname.lastIndexOf(".");
- if (k >= 0)
- cname = cname.substring(k + 1);
- return "[" + t.Assembly().GetName() + "]" + t +
- "(" + cname + "#" + Integer.toHexString(t.hashCode()) + ")";
- }
- private static String dumpType(Type t) {
- StringBuffer str = new StringBuffer();
- str.append(formatType(t) + " : ");
- str.append(formatType(t.BaseType()));
- Type[] ifaces = t.GetInterfaces();
- for (int i = 0; i < ifaces.length; i++)
- str.append(", " + formatType(ifaces[i]));
- return str.toString();
- }
-
- //##########################################################################
- // GetMember/s/
-
- protected MemberInfo[] members;
-
- public MemberInfo[] GetMember(String name) {
- aggregateMembers();
- List l = new ArrayList();
- for (int i = 0; i < members.length; i++) {
- if (name.equals(members[i].Name))
- l.add(members[i]);
- }
- return (MemberInfo[])l.toArray(MemberInfo.EMPTY_ARRAY);
- }
-
- protected void aggregateMembers() {
- if (members != null)
- return;
- initFields();
- initMethods();
- initProperties();
- initNestedTypes();
- // the List returned by Arrays.asList doesn't support the addAll method
- // so we have to wrap it in ArrayList
- List l = new ArrayList(Arrays.asList(fields));
- l.addAll(Arrays.asList(constructors));
- l.addAll(Arrays.asList(methods));
- l.addAll(Arrays.asList(properties));
- l.addAll(Arrays.asList(nestedTypes));
- members = (MemberInfo[]) l.toArray(MemberInfo.EMPTY_ARRAY);
- }
-
- //##########################################################################
- // non-standard methods that return only members declared in this type
-
- /**
- * Return only the fields declared in this type.
- */
- public FieldInfo[] getFields() {
- initFields();
- FieldInfo[] fields = new FieldInfo[this.fields.length];
- System.arraycopy(this.fields, 0, fields, 0, fields.length);
- return fields;
- }
-
- /**
- * Return only the conrtuctors declared in this type.
- */
- public ConstructorInfo[] getConstructors() {
- initMethods();
- ConstructorInfo[] ctors = new ConstructorInfo[constructors.length];
- System.arraycopy(constructors, 0, ctors, 0, ctors.length);
- return ctors;
- }
-
- /**
- * Return only the methods declared in this type.
- */
- public MethodInfo[] getMethods() {
- initMethods();
- MethodInfo[] methods = new MethodInfo[this.methods.length];
- System.arraycopy(this.methods, 0, methods, 0, methods.length);
- return methods;
- }
-
- /**
- * Return only the properties declared in this type.
- */
- public PropertyInfo[] getProperties() {
- initProperties();
- PropertyInfo[] props = new PropertyInfo[properties.length];
- System.arraycopy(properties, 0, props, 0, props.length);
- return props;
- }
-
- /**
- * Return only the interfaces directly implemented by this type.
- */
- public Type[] getInterfaces() {
- initInterfaces();
- Type[] ifaces = new Type[interfaces.length];
- System.arraycopy(interfaces, 0, ifaces, 0, ifaces.length);
- return ifaces;
- }
-
- /**
- * Return the types declared in this type.
- */
- public Type[] getNestedTypes() {
- initNestedTypes();
- Type[] nested = new Type[nestedTypes.length];
- System.arraycopy(nestedTypes, 0, nested, 0, nested.length);
- return nested;
- }
-
- //##########################################################################
-
- public String toString() {
- return FullName;
- }
-
- //##########################################################################
- // lazy type construction members
-
- private boolean initBaseType = true;
- protected final void initBaseType() {
- if (initBaseType) {
- loadBaseType();
- initBaseType = false;
- }
- }
- protected void loadBaseType() {}
-
- private boolean initInterfaces = true;
- protected void initInterfaces() {
- if (initInterfaces) {
- loadInterfaces();
- initInterfaces = false;
- }
- assert interfaces != null : "In type " + this;
- }
- protected void loadInterfaces() {}
-
- private boolean initNestedTypes = true;
- protected void initNestedTypes() {
- if (initNestedTypes) {
- loadNestedTypes();
- initNestedTypes = false;
- }
- assert nestedTypes != null : "In type " + this;
- }
- protected void loadNestedTypes() {}
-
- private boolean initFields = true;
- protected void initFields() {
- if (initFields) {
- loadFields();
- initFields = false;
- }
- assert fields != null : "In type " + this;
- }
- protected void loadFields() {}
-
- private boolean initMethods = true;
- protected void initMethods() {
- if (initMethods) {
- loadMethods();
- initMethods = false;
- }
- assert constructors != null : "In type " + this;
- assert methods != null : "In type " + this;
- }
- protected void loadMethods() {}
-
- private boolean initProperties = true;
- protected void initProperties() {
- if (initProperties) {
- initMethods();
- loadProperties();
- initProperties = false;
- }
- assert properties != null : "In type " + this;
- }
- protected void loadProperties() {}
-
- private boolean initEvents = true;
- protected void initEvents() {
- if (initEvents) {
- initMethods();
- loadEvents();
- initEvents = false;
- }
- assert events != null : "In type " + this;
- }
- protected void loadEvents() {}
-
- //##########################################################################
-
- //##########################################################################
- // static members
-
- private static Assembly MSCORLIB;
- private static Module MSCORLIB_DLL;
-
- public static Type OBJECT() { return __OBJECT; }
- public static Type STRING() { return __STRING; }
- public static Type ARRAY() { return __ARRAY; }
- public static Type VOID() { return __VOID; }
- public static Type ENUM() { return __ENUM; }
- public static Type VALUE_TYPE() { return __VALUE_TYPE; }
-
- private static Type __OBJECT;
- private static Type __STRING;
- private static Type __ARRAY;
- private static Type __VOID;
- private static Type __ENUM;
- private static Type __VALUE_TYPE;
-
- public static void initMSCORLIB(Assembly mscorlib) {
- if (MSCORLIB != null)
- throw new RuntimeException("mscorlib already initialized");
- MSCORLIB = mscorlib;
- MSCORLIB_DLL = MSCORLIB.GetModules()[0];
-
- __OBJECT = mscorlib.GetType("System.Object");
- __STRING = mscorlib.GetType("System.String");
- __ARRAY = mscorlib.GetType("System.Array");
- __VOID = mscorlib.GetType("System.Void");
- __ENUM = mscorlib.GetType("System.Enum");
- __VALUE_TYPE = mscorlib.GetType("System.ValueType");
- }
-
- //##########################################################################
-
-} // class Type
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/TypeAttributes.java b/src/msil/ch/epfl/lamp/compiler/msil/TypeAttributes.java
deleted file mode 100644
index 8f489fa46f..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/TypeAttributes.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-/**
- * Specifies type attributes.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class TypeAttributes {
-
- //##########################################################################
- // Visibilty attributes
-
- /** Bitmask used to retrieve visibility information. */
- public static final int VisibilityMask = 0x00000007;
-
- /** Class has no public scope. */
- public static final int NotPublic = 0x00000000;
-
- /** Class has public scope. */
- public static final int Public = 0x00000001;
-
- /** Class is nested with public visibility. */
- public static final int NestedPublic = 0x00000002;
-
- /** Class is nested with private visibility. */
- public static final int NestedPrivate = 0x00000003;
-
- /** Class is nested with family visibility, and is thus accessible
- * only by methods within its own type and any subtypes. */
- public static final int NestedFamily = 0x00000004;
-
- /** Class is nested with assembly visibility, and is thus accessible
- * only by methods within its assembly. */
- public static final int NestedAssembly = 0x00000005;
-
- /** Class is nested with assembly and family visibility, and is thus accessible
- * only by methods lying in the intersection of its family and assembly. */
- public static final int NestedFamANDAssem = 0x00000006;
-
- /** Class is nested with family or assembly visibility, and is thus accessible
- * only by methods lying in the union of its family and assembly. */
- public static final int NestedFamORAssem = 0x00000007;
-
- //##########################################################################
- // Class layout attributes
-
- /** Bitmask used to retrieve class layout information. */
- public static final int LayoutMask = 0x00000018;
-
- /** Class fields are automatically laid out by the CLR. */
- public static final int AutoLayout = 0x00000000;
-
- /** Class fields are laid out sequentially, in the order that the fields
- * were emitted to the metadata. */
- public static final int SequentialLayout = 0x00000008;
-
- /** Class fields are laid out at the specified offsets. */
- public static final int ExplicitLayout = 0x00000010;
-
- //##########################################################################
- // Class semantics attributes
-
- /** Bitmask used to retrieve class semantics information. */
- public static final int ClassSemanticsMask = 0x00000020;
-
- /** Type is a class. */
- public static final int Class = 0x00000000;
-
- /** Type is an interface. */
- public static final int Interface = 0x00000020;
-
- //##########################################################################
- // Special semantics in addition to class semantics
-
- /** Class is abstract. */
- public static final int Abstract = 0x00000080;
-
- /** Class is cannot be extended. */
- public static final int Sealed = 0x00000100;
-
- /** Class is special in a way denoted by the name. */
- public static final int SpecialName = 0x00000400;
-
- //##########################################################################
- // Implementation attributes
-
- /** Class/interface is imported from another module. */
- public static final int Import = 0x00001000;
-
- /** Class can be serialized. */
- public static final int Serializable = 0x00002000;
-
- //##########################################################################
- // String formatting attributes
-
- /** Bitmask used to retrieve string information for native interop. */
- public static final int StringFormatMask = 0x00030000;
-
- /** LPTSTR is interpreted as ANSI. */
- public static final int AnsiClass = 0x00000000;
-
- /** LPTSTR is interpreted as UNICODE. */
- public static final int UnicodeClass = 0x00010000;
-
- /** LPTSTR is interpreted automatically. */
- public static final int AutoClass = 0x00020000;
-
- //##########################################################################
- // Class initialization attributes
-
- /** Initialize the class before first static field access. */
- public static final int BeforeFieldInit = 0x00100000;
-
- //##########################################################################
- // Additional flags
-
- /** CLI provides 'special' behavior, depending upon the name of the type. */
- public static final int RTSpecialName = 0x00000800;
-
- /** Type has security associate with it. */
- public static final int HasSecurity = 0x00040000;
-
- //##########################################################################
-
- public static String accessModsToString(int attrs) {
- switch (attrs & VisibilityMask) {
- case NotPublic: return "private";
- case Public: return "public";
- case NestedPublic: return "nested public";
- case NestedPrivate: return "nested private";
- case NestedFamily: return "nested family";
- case NestedAssembly: return "nested assembly";
- case NestedFamANDAssem: return "nested famandassem";
- case NestedFamORAssem: return "nested famorassem";
- default:
- throw new RuntimeException();
- }
- }
-
- /** Returns a string representation of the given attributes. */
- public static String toString(int attrs) {
- StringBuffer str = new StringBuffer(accessModsToString(attrs));
- switch (attrs & LayoutMask) {
- case AutoLayout: str.append(" auto"); break;
- case SequentialLayout: str.append(" sequential"); break;
- case ExplicitLayout: str.append(" explicit"); break;
- }
- switch (attrs & StringFormatMask) {
- case AnsiClass: str.append(" ansi"); break;
- case UnicodeClass: str.append(" unicode"); break;
- case AutoClass: str.append(" autochar"); break;
- }
- if ((attrs & Interface) != 0) str.append(" interface");
- if ((attrs & Abstract) != 0) str.append(" abstract");
- if ((attrs & Sealed) != 0) str.append(" sealed");
- if ((attrs & BeforeFieldInit) != 0) str.append(" beforefieldinit");
- if ((attrs & Serializable) != 0) str.append(" serializable");
- if ((attrs & SpecialName) != 0) str.append(" specialname");
- if ((attrs & RTSpecialName) != 0) str.append(" rtspecialname");
- return str.toString();
- }
-
- /***/
- public static final boolean isNested(int attrs) {
- switch (attrs & VisibilityMask) {
- case NestedPublic:
- case NestedPrivate:
- case NestedFamily:
- case NestedAssembly:
- case NestedFamANDAssem:
- case NestedFamORAssem:
- return true;
- default: return false;
- }
- }
-
- //##########################################################################
-
- // makes the class uninstantiable
- private TypeAttributes() {}
-
- //##########################################################################
-
-} // class TypeAttributes
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Version.java b/src/msil/ch/epfl/lamp/compiler/msil/Version.java
deleted file mode 100644
index ad4b09b163..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/Version.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * System.Reflection-like API for access to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil;
-
-
-/**
- * Represents the version number for a common language runtime assembly
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class Version {
-
- //##########################################################################
- // public interface
-
- /**
- * Gets the value of the major component of the version
- * number for this instance.
- */
- public final int Major;
-
- /**
- * Gets the value of the minor component of the version
- * number for this instance.
- */
- public final int Minor;
-
- /**
- * Gets the value of the build component of the version
- * number for this instance.
- */
- public final int Build;
-
- /**
- * Gets the value of the revision component of the version
- * number for this instance.
- */
- public final int Revision;
-
- /**
- * Initializes a new instance of the Version class.
- */
- public Version() {
- this(0,0,0,0);
- }
-
- /**
- * Initializes a new instance of the Version class with
- * the specified major, minor, build, and revision numbers.
- */
- public Version(int major, int minor, int build, int revision) {
- this.Major = major;
- this.Minor = minor;
- this.Build = build;
- this.Revision = revision;
- }
-
- /**
- * Converts the value of this instance to its equivalent String representation
- */
- public String toString() {
- return "" + Major + "." + Minor + "." + Build + "." + Revision;
- }
-
- //##########################################################################
-
-} // class Version
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/AssemblyBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/AssemblyBuilder.scala
deleted file mode 100644
index 6bf4c7d1da..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/AssemblyBuilder.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil._
-import java.io.IOException
-
-/**
- * Defines and represents a dynamic assembly.
- * A dynamic assembly is an assembly that is created using the compiler.msil
- * emit APIs. The dynamic modules in the assembly are saved when the dynamic
- * assembly is saved using the Save method. To generate an executable, the
- * SetEntryPoint method must be called to identify the method that is the
- * entry point to the assembly. Assemblies are saved as DLL by default,
- * unless SetEntryPoint requests the generation of a console application
- * or a Windows-based application.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class AssemblyBuilder(name: AssemblyName)
- extends Assembly(name)
- with ICustomAttributeSetter
- with Visitable
-{
- //##########################################################################
- // public methods
-
- /**
- * Defines a dynamic module with the given name that will be saved
- * to the specified file. No symbol information is emitted.
- */
- def DefineDynamicModule(name: String, fileName: String): ModuleBuilder = {
- val module = new ModuleBuilder(name, fileName, "" + null, this)
- addModule(name, module)
- return module
- }
-
- /** Returns the dynamic module with the specified name. */
- def GetDynamicModule(name: String): ModuleBuilder = {
- return GetModule(name).asInstanceOf[ModuleBuilder]
- }
-
- /** Saves this dynamic assembly to disk. */
- @throws(classOf[IOException])
- def Save(fileName: String) {
- generatedFiles = scala.collection.mutable.ArrayBuffer.empty[String]
- ILPrinterVisitor.printAssembly(this, fileName)
- }
-
- @throws(classOf[IOException])
- def Save(destPath: String, sourceFilesPath: String) {
- generatedFiles = scala.collection.mutable.ArrayBuffer.empty[String]
- ILPrinterVisitor.printAssembly(this, destPath, sourceFilesPath)
- }
-
- /** Returns the list of generated files from calling Save(). */
- def GetGeneratedFiles(): Array[String] = {
- return generatedFiles.toArray // (new Array[String](generatedFiles.size())).asInstanceOf[Array[String]]
- }
-
- /** Sets the entry point for this dynamic assembly. */
- def SetEntryPoint(entryMethod: MethodInfo) {
- EntryPoint = entryMethod
- }
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
- // protected members
-
- // all extern assemblies used in this assembly builder
- protected var externAssemblies = scala.collection.mutable.Set.empty[Assembly]
-
- // register an extern assembly
- protected def registerExternAssembly(assembly: Assembly) {
- externAssemblies += assembly
- }
-
- // get all extern Assemblies used in this Assembly Builder
- def getExternAssemblies(): Array[Assembly] = {
- externAssemblies = scala.collection.mutable.Set[Assembly]()
- val iter = Assembly.assemblies.values().iterator
- while (iter.hasNext) {
- externAssemblies += iter.next.asInstanceOf[Assembly]
- }
- externAssemblies -= this
- return externAssemblies.toArray
- }
-
- def loadModules() {}
-
- // contains list of generated .msil files after calling Save()
- var generatedFiles = scala.collection.mutable.ArrayBuffer.empty[String]
-
- //##########################################################################
- //##########################################################################
-
- /** the apply method for a visitor */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseAssemblyBuilder(this)
- }
-
- //##########################################################################
-}
-
-object AssemblyBuilderFactory {
- /**
- * Defines a dynamic assembly with the specified name.
- */
- def DefineDynamicAssembly(name: AssemblyName): AssemblyBuilder = {
- //Assembly.reset()
- return new AssemblyBuilder(name)
- }
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ConstructorBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ConstructorBuilder.scala
deleted file mode 100644
index ddd4708ecd..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ConstructorBuilder.scala
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.ConstructorInfo
-import ch.epfl.lamp.compiler.msil.Type
-import java.io.IOException
-
-/**
- * Defines and represents a constructor of a dynamic class.
- * ConstructorBuilder is used to fully describe a constructor in
- * Microsoft intermediate language (MSIL), including the name, attributes,
- * signature, and constructor body. It is used in conjunction with the
- * TypeBuilder class to create classes at run time. Call DefineConstructor
- * to get an instance of ConstructorBuilder.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class ConstructorBuilder(declType: Type, attrs: Int, paramTypes: Array[Type])
- extends ConstructorInfo(declType, attrs, paramTypes)
- with ICustomAttributeSetter
- with Visitable
-{
-
- //##########################################################################
- // public interface
-
- /** Defines a parameter of this constructor. */
- def DefineParameter(pos: Int, attr: Int, name: String): ParameterBuilder = {
- val param = new ParameterBuilder(name, params(pos).ParameterType, attr, pos)
- params(pos) = param
- return param
- }
-
- /** Returns an ILGenerator for this constructor. */
- def GetILGenerator(): ILGenerator = {
- return ilGenerator
- }
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
-
- /** The apply method for a visitor. */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseConstructorBuilder(this)
- }
-
- //##########################################################################
-
- // the Intermediate Language Generator
- // it contains the method's body
- protected var ilGenerator: ILGenerator = new ILGenerator(this)
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/FieldBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/FieldBuilder.scala
deleted file mode 100644
index 7ef9dc7a5b..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/FieldBuilder.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.FieldInfo
-import ch.epfl.lamp.compiler.msil.Type
-import ch.epfl.lamp.compiler.msil.FieldAttributes
-import ch.epfl.lamp.compiler.msil.ConstructorInfo
-
-import ch.epfl.lamp.compiler.msil.util.PECustomMod
-
-import java.io.IOException
-
-/**
- * Discovers the attributes of a field and provides access to field metadata.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class FieldBuilder(name: String, declType: Type, attrs: Int, fieldTypeWithMods: PECustomMod)
- extends FieldInfo(name, declType, attrs, fieldTypeWithMods, null)
- with ICustomAttributeSetter
- with Visitable
-{
-
- //##########################################################################
- // public interface
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
-
- /** the apply method for a visitor */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseFieldBuilder(this)
- }
-
- //##########################################################################
-
- protected var defaultValue: Object = _
-
- /** Sets the default value of this field. */
- def SetConstant(defaultValue: Object) {
- this.defaultValue = defaultValue
- }
-
- /** Specifies the field layout. */
- def SetOffset(iOffset: Int) {
- //this.fieldOffset = FieldAttributes.Offset.Value(iOffset)
- }
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ICustomAttributeSetter.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ICustomAttributeSetter.scala
deleted file mode 100644
index 5d74d3aa95..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ICustomAttributeSetter.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.ConstructorInfo
-
-/**
- * Declares the possibility to set a custom attribute for a member
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-trait ICustomAttributeSetter {
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte])
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala
deleted file mode 100644
index 63ecbfd353..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILGenerator.scala
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil._
-import ch.epfl.lamp.compiler.msil.util.Table
-import java.util.Stack
-import java.io.IOException
-import ILGenerator._
-
-/**
- * Generates Microsoft intermediate language (MSIL) instructions.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
- final class ILGenerator(_owner: MethodBase) extends Visitable {
-
- //##########################################################################
- // public interface
-
- /**
- * Puts the specified instruction onto the stream of instructions.
- */
- def Emit(opcode: OpCode) {
- // switch opcode
- if (opcode == OpCode.Ret) {
- emit(opcode, null, 0)
- } else {
- emit(opcode, null)
- }
- }
-
- /**
- * Puts the specified instruction and character argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Char) {
- emit(opcode,new Character(arg))
- }
-
- /**
- * Puts the specified instruction and metadata token for the
- * specified constructor onto the Microsoft intermediate language
- * (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: ConstructorInfo) {
- assert(arg != null)
- // newobj
- // pop size is the number of parameters
- emit(opcode,arg, OpCode.PUSH_size(opcode.CEE_push) -
- arg.GetParameters().length)
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate language (MSIL)
- * stream followed by the index of the given local variable.
- */
- def Emit(opcode: OpCode, arg: LocalBuilder) {
- assert(arg != null)
- // ldarg | ldarg.s | ldarga
- // ldarga.s | ldloc | ldloc.s | ldloca
- // ldloca.s | starg | starg.s | stloc
- // stloc.s
-
- // <instr_var> <localname>
- emit(opcode, arg)
- }
-
-
- /**
- * Puts the specified instruction and numerical argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Double) {
- // ldc.r4 | ldc.r8
- emit(opcode, new java.lang.Double(arg))
- }
-
- /**
- * Puts the specified instruction and metadata token for the
- * specified field onto the Microsoft intermediate language (MSIL)
- * stream of instructions.
- */
- def Emit(opcode: OpCode,arg: FieldInfo) {
- assert(arg != null)
- // ldfld | ldflda | ldsfld | ldsflda | stfld | stsfld
- emit(opcode,arg)
- }
-
- /**
- * Puts the specified instruction and numerical argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Short ) {
- emit(opcode, new java.lang.Short(arg))
- }
-
- /**
- * Puts the specified instruction and numerical argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Int) {
- // ldc.i4 | ldc.i4.s | unaligned
- emit(opcode, new java.lang.Integer(arg))
- }
-
- /**
- * Puts the specified instruction and numerical argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Long) {
- // ldc.i8
- emit(opcode, new java.lang.Long(arg))
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate
- * language (MSIL) stream and leaves space to include a label when
- * fixes are done.
- */
- def Emit(opcode: OpCode,label: Label) {
- assert(label != null)
- // beq | beq.s | bge | bge.s |
- // bge.un | bge.un.s | bgt | bgt.s | bgt.un | bgt.un.s |
- // ble | ble.s | ble.un | ble.un.s | blt | blt.s |
- // blt.un | blt.un.s | bne.un | bne.un.s | br | br.s |
- // brfalse | brfalse.s | brtrue | brtrue.s | leave | leave.s
-
- emit(opcode, label)
- // is the label initialized ? if true backward jump else forward jump
- if (label.isInitialized()) {
-// if (arg.stacksize != lastLabel.stacksize) {
-// System.err.println("ILGenerator.Emit: Stack depth differs depending on path:");
-// System.err.println("\tmethod = " + owner);
-// System.err.println("\tPC = 0x" + Table.short2hex(lastLabel.address));
-// }
- //assert arg.stacksize == lastLabel.stacksize;
- }
- else {
- label.setStacksize(lastLabel.getStacksize())
- }
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate
- * language (MSIL) stream and leaves space to include a label when
- * fixes are done.
- */
- def Emit(opcode: OpCode, arg: Array[Label] ) {
- assert(arg != null)
- // switch
-
- // <instr> ::= <instr_switch> ( <labels> )
- // Examples:
- // switch (0x3, -14, Label1)
- // switch (5, Label2)
- emit(opcode, arg, arg.length)
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate
- * language (MSIL) stream followed by the metadata token for the
- * given method.
- */
- def Emit(opcode: OpCode,arg: MethodInfo) {
- assert(arg != null)
- // call | callvirt | jmp | ldftn | ldvirtftn
- // pop size is the number of parameters
- // pop 1 more if method is not static !
- // push size is either 0 (void Method) either 1
- assert(arg.ReturnType != null, "No ReturnType: " + arg.DeclaringType + "::" + arg.Name)
-
- val popush: Int = if (opcode == OpCode.Ldftn ||
- opcode == OpCode.Ldvirtftn ||
- opcode == OpCode.Jmp)
- {
- OpCode.PUSH_size(opcode.CEE_push) - OpCode.POP_size(opcode.CEE_pop)
- } else if (opcode == OpCode.Calli || opcode == OpCode.Callvirt) {
- (if(arg.ReturnType == VOID) 0 else 1) - arg.GetParameters().length - 1
- } else {
- (if(arg.ReturnType == VOID) 0 else 1) - arg.GetParameters().length
- }
- emit(opcode, arg, popush)
- }
-
- /**
- * Puts the specified instruction and numerical argument onto
- * the Microsoft intermediate language (MSIL) stream of instructions.
- */
- def Emit(opcode: OpCode, arg: Float ) {
- emit(opcode, new java.lang.Float(arg))
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate
- * language (MSIL) stream followed by the metadata token for the
- * given string.
- */
- def Emit(opcode: OpCode, arg: String ) {
- assert(arg != null)
- // ldstr
- emit(opcode, arg)
- }
-
- /**
- * Puts the specified instruction onto the Microsoft intermediate
- * language (MSIL) stream followed by the metadata token for the
- * given type.
- */
- def Emit(opcode: OpCode, arg: Type) {
- assert(arg != null)
- // box | castclass | cpobj | initobj | isinst |
- // ldelema | ldobj | mkrefany | newarr | refanyval |
- // sizeof | stobj | unbox
-
- emit(opcode, arg)
- }
-
- /**
- * Puts a call or callvirt instruction onto the Microsoft intermediate
- * language (MSIL) stream.
- */
- def EmitCall(opcode: OpCode, arg: MethodInfo,
- optionalParameterTypes: Array[Type]) {
- assert(arg != null)
- // pop size is the number of parameters
- // push size is either 0 (void Method) either 1
- //System.out.println(arg.ReturnType.Size + " " + arg.GetParameters().length);
- emit(opcode, arg, (if(arg.ReturnType == VOID) 0 else 1) -
- arg.GetParameters().length)
- }
-
- /**
- * Emits the Microsoft intermediate language (MSIL) necessary to
- * call WriteLine with the given field.
- */
- def EmitWriteLine(arg: FieldInfo) {
- // first load field info
- // if static use OpCode.Ldsfld
- if (arg.IsStatic())
- Emit(OpCodes.Ldsfld, arg)
- else
- Emit(OpCodes.Ldfld, arg)
- // then call System.Console.WriteLine(arg.Type)
- val t: Type = Type.GetType("System.Console")
- val argsType: Array[Type] = new Array[Type](1)
- argsType(0) = arg.FieldType
- val m: MethodInfo = t.GetMethod("WriteLine", argsType)
- EmitCall(OpCode.Call, m, null)
- }
-
- /**
- * Emits the Microsoft intermediate language (MSIL) necessary
- * to call WriteLine with the given local variable.
- */
- def EmitWriteLine(arg: LocalBuilder) {
- // first load local variable
- Emit(OpCodes.Ldloc, arg)
- // then call System.Console.WriteLine(arg.Type)
- val t: Type = Type.GetType("System.Console")
- val argsType: Array[Type] = new Array[Type](1)
- argsType(0) = arg.LocalType
- val m: MethodInfo = t.GetMethod("WriteLine", argsType)
- EmitCall(OpCode.Call, m, null)
- }
-
- /**
- * Emits the Microsoft intermediate language (MSIL) to call
- * WriteLine with a string.
- */
- def EmitWriteLine(arg: String) {
- // first load string
- Emit(OpCode.Ldstr, arg)
- // then call System.Console.WriteLine(string)
- val t: Type = Type.GetType("System.Console")
- val argsType: Array[Type] = new Array[Type](1)
- argsType(0) = Type.GetType("System.String")
- val m: MethodInfo = t.GetMethod("WriteLine", argsType)
- EmitCall(OpCode.Call, m, null)
- }
-
- /**
- * Declares a local variable.
- */
- def DeclareLocal(localType: Type): LocalBuilder = {
- val l: LocalBuilder = new LocalBuilder(locals, localType)
- locals = locals + 1
- localList += l
- return l
- }
-
- /**
- * Returns a new label that can be used as a token for branching.
- * In order to set the position of the label within the stream, you
- * must call MarkLabel. This is just a token and does not yet represent
- * any particular location within the stream.
- */
- def DefineLabel():Label = {
- new Label.NormalLabel()
- }
-
- /**
- * Marks the Microsoft intermediate language (MSIL) stream's
- * current position with the given label.
- */
- def MarkLabel(label: Label) {
- label.mergeWith(lastLabel)
- /*
- label.address = lastLabel.address;
- //label.stacksize = lastLabel.stacksize;
- if (label.stacksize >= 0)
- lastLabel.stacksize = label.stacksize;
- */
- }
-
- /** Begins a lexical scope. */
- def BeginScope() {
- emitSpecialLabel(Label.NewScope)
- }
-
- /** Ends a lexical scope. */
- def EndScope() {
- emitSpecialLabel(Label.EndScope)
- }
-
- /**
- * Begins an exception block for a non-filtered exception.
- * The label for the end of the block. This will leave you in the correct
- * place to execute finally blocks or to finish the try.
- */
- def BeginExceptionBlock() {
- emitSpecialLabel(Label.Try)
- val endExc: Label = new Label.NormalLabel() // new Label(lastLabel) ???
- excStack.push(Label.Try, endExc)
- }
-
- /** Begins a catch block. */
- def BeginCatchBlock(exceptionType: Type) {
- val kind = excStack.peekKind()
- if (kind == Label.Kind.Try ||
- kind == Label.Kind.Catch) {
- /* ok */
- } else {
- throw new RuntimeException("Catch should follow either a try or catch")
- }
- val endExc: Label = excStack.popLabel()
- Emit(OpCodes.Leave, endExc)
- // the CLI automatically provide the exception object on the evaluation stack
- // we adjust the stacksize
- lastLabel.incStacksize()
- excStack.push(Label.Catch, endExc)
- emitSpecialLabel(Label.Catch, exceptionType)
- }
-
- /** Ends an exception block. */
- def EndExceptionBlock() {
- val kind = excStack.peekKind()
- if (kind == Label.Kind.Try) {
- throw new RuntimeException("Try block with neither catch nor finally")
- } else if (kind == Label.Kind.Catch) {
- Emit(OpCodes.Leave, excStack.peekLabel())
- } else if (kind == Label.Kind.Finally) {
- Emit(OpCodes.Endfinally)
- }
- MarkLabel(excStack.popLabel())
- emitSpecialLabel(Label.EndTry)
- }
-
- /**
- * Begins a finally block in the Microsoft intermediate language
- * (MSIL) instruction stream.
- */
- def BeginFinallyBlock() {
- val endExc: Label = excStack.popLabel()
- Emit(OpCodes.Leave, endExc)
- excStack.push(Label.Finally, endExc)
- emitSpecialLabel(Label.Finally)
- }
-
- /**
- * Emits an instruction to throw an exception.
- */
- def ThrowException(exceptionType: Type) {
- assert(exceptionType != null)
- if (!exceptionType.isSubtypeOf(Type.GetType("System.Exception")))
- throw new RuntimeException
- (exceptionType + " doesn't extend System.Exception" )
- val ctor: ConstructorInfo = exceptionType.GetConstructor(Type.EmptyTypes)
- if (ctor == null)
- throw new RuntimeException("Type " + exceptionType
- + "doesn't have a default constructor")
- Emit(OpCodes.Newobj, ctor)
- Emit(OpCodes.Throw)
- }
-
- /**
- * sets the line of the source file corresponding to the next instruction
- */
- def setPosition(line: Int) {
- if (line != 0) lineNums.put(lastLabel, Integer.toString(line))
- }
-
- def setPosition(line: Int, filename: String) {
- if (line != 0) lineNums.put(lastLabel, line + " '" + filename + "'")
- }
-
- def setPosition(startLine: Int, endLine: Int, startCol: Int, endCol: Int, filename: String) {
- val lineRange = startLine + "," + endLine
- val colRange = startCol + "," + endCol
- lineNums.put(lastLabel, lineRange + ":" + colRange + " '" + filename + "'")
- }
-
- def getLocals(): Array[LocalBuilder] = localList.toArray
-
- def getLabelIterator() = labelList.iterator
-
- def getOpcodeIterator() = opcodeList.iterator
-
- def getArgumentIterator() = argumentList.iterator
-
- //##########################################################################
- // private implementation details
-
-
-
- // the local variable list
- private final val localList = scala.collection.mutable.ArrayBuffer.empty[LocalBuilder]
-
- // the label list, the opcode list and the opcode argument list
- // labelList is an array of Label
- // opcodeList is an array of OpCode
- // argumentList is an array of Object (null if no argument)
- private final val labelList = scala.collection.mutable.ArrayBuffer.empty[Label]
- private final val opcodeList = scala.collection.mutable.ArrayBuffer.empty[OpCode]
- private final val argumentList = scala.collection.mutable.ArrayBuffer.empty[Object]
-
- // the program counter (pc)
- // also called the stream's current position
- private var pc: Int = 0
-
- // last label
- private var lastLabel: Label = new Label.NormalLabel(pc,0)
-
- // the maximum size of stack
- private var maxstack: Int = 0
-
- // the number of the locals
- private var locals: Int = 0
-
- // stack of label for exception mechanism
- private val excStack: ExceptionStack = new ExceptionStack()
-
- // the method info owner of this ILGenerator
- var owner: MethodBase = _owner
-
- val lineNums = scala.collection.mutable.Map.empty[Label, String]
-
-
- def getMaxStacksize(): Int = { this.maxstack }
-
- // private emit with Object Argument
- private def emit(opcode: OpCode, arg: Object) {
- emit(opcode, arg, opcode.CEE_popush)
- }
-
- // private emit with Object Argument and override POPUSH
- private def emit(opcode: OpCode, arg: Object, overridePOPUSH: Int) {
- // add label, opcode and argument
- labelList += lastLabel
- opcodeList += opcode
- argumentList += arg
- // compute new lastLabel (next label)
- val stackSize: Int = lastLabel.getStacksize() + overridePOPUSH
- if (stackSize < 0) {
- val msg = "ILGenerator.emit(): Stack underflow in method: " + owner
- scala.Console.println(msg)
- // throw new RuntimeException(msg)
- }
- if (stackSize > maxstack)
- maxstack = stackSize
- var address: Int = lastLabel.getAddress() + opcode.CEE_length
- if (opcode.CEE_opcode == OpCode.CEE_SWITCH) {
- address = address + 4*arg.asInstanceOf[Array[Label]].length
- }
- lastLabel = new Label.NormalLabel(address, stackSize)
- pc = pc + 1
- }
-
- def Ldarg0WasJustEmitted() : Boolean = {
- if(opcodeList.isEmpty)
- return false
- val lastEmitted = opcodeList(opcodeList.size - 1)
- lastEmitted eq OpCode.Ldarg_0
- }
-
- private def emitSpecialLabel(l: Label) {
- emitSpecialLabel(l, null)
- }
- private def emitSpecialLabel(l: Label, catchType: Type) {
- labelList += l
- opcodeList += null
- argumentList += catchType
- }
-
- //##########################################################################
- //
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseILGenerator(this)
- }
-
- //##########################################################################
-} // class ILGenerator
-
-
-object ILGenerator {
-
- val VOID: Type = Type.GetType("System.Void")
- val NO_LABEL: String = ""
-
- private final class ExceptionStack {
- private val labels = new scala.collection.mutable.Stack[Label]()
- private val kinds = new scala.collection.mutable.Stack[Label]()
- def ExceptionStack() {}
- def pop() { labels.pop; kinds.pop }
- def push(kind: Label, label: Label) {
- kinds.push(kind); labels.push(label)
- }
- def peekKind(): Label.Kind = kinds.top.getKind
- def peekLabel(): Label = labels.top
- def popLabel(): Label = { kinds.pop(); labels.pop() }
- }
-
-}
-
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILPrinterVisitor.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ILPrinterVisitor.scala
deleted file mode 100644
index 413b08ddd8..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ILPrinterVisitor.scala
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies in MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import java.io.PrintWriter
-import java.io.IOException
-import java.util.Comparator
-
-import ch.epfl.lamp.compiler.msil._
-import ch.epfl.lamp.compiler.msil.util.Table
-
-/**
- * The MSIL printer Visitor. It prints a complete
- * assembly in a single or multiple files. Then this file can be compiled by ilasm.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-abstract class ILPrinterVisitor extends Visitor {
-
- import ILPrinterVisitor._
- import OpCode._
-
- //##########################################################################
-
- protected final val assemblyNameComparator =
- new scala.math.Ordering[Assembly]() {
- override def compare(o1: Assembly, o2: Assembly): Int = {
- val a1 = o1.asInstanceOf[Assembly]
- val a2 = o2.asInstanceOf[Assembly]
- return a1.GetName().Name.compareTo(a2.GetName().Name)
- }
- }
-
- // the output file writer
- protected var out: PrintWriter = null
-
- // the left margin
- private var lmargin = 0
-
- // indicate a newline
- private var newline = true
-
- // print types without or with members?
- protected var nomembers: Boolean = false
-
- // external assemblies
- protected var as: Array[Assembly] = null
-
- private def align() {
- if (newline)
- padding = lmargin
- printPadding()
- newline = false
- }
- private def indent() {
- lmargin += TAB
- }
- private def undent() {
- lmargin -= TAB
- assert(lmargin >= 0)
- }
-
- private var padding = 0
- private def pad(n: Int) {
- assert(n >= 0, "negative padding: " + n)
- padding += n
- }
- private def printPadding() {
- if (padding <= 0)
- return
- while (padding > SPACES_LEN) {
- out.print(SPACES)
- padding -= SPACES_LEN
- }
- out.print(SPACES.substring(0, padding))
- padding = 0
- }
-
- // methods to print code
- protected def print(s: String) { align(); out.print(s)}
- protected def print(o: Object) { align(); out.print(o) }
- protected def print(c: Char) { align(); out.print(c) }
- protected def print(`val`: Int) { align(); out.print(`val`)}
- protected def print(`val`: Long){ align(); out.print(`val`)}
- protected def println() { out.println(); newline = true; padding = 0 }
- protected def println(c: Char) { print(c); println() }
- protected def println(i: Int) { print(i); println() }
- protected def println(l: Long) { print(l); println() }
- protected def println(s: String){ print(s); println() }
- protected def println(o: Object){ print(o); println() }
- protected def printName(name: String) {
- val ch = name.charAt(0)
- //if (Character.isLetter(ch) && Character.isLowerCase(ch)) {
- if ((ch != '.') && (ch != '!')) {
- print('\''); print(name); print('\'')
- } else
- print(name)
- }
-
- protected def printAssemblyBoilerplate() {
- // print all the external assemblies
- for (j <- 0 until as.length) {
- printAssemblySignature(as(j), true)
- }
- // print assembly declaration
- printAssemblySignature(currAssembly, false)
- }
-
- // the entrypoint method
- protected var entryPoint: MethodInfo = null
-
- // current opcode argument
- protected var argument: Object = null
-
- /***/
- @throws(classOf[IOException])
- protected def print(vAble: Visitable) {
- if (vAble != null)
- vAble.apply(this)
- }
-
- /**
- * Visit an AssemblyBuilder
- */
- @throws(classOf[IOException])
- def caseAssemblyBuilder(assemblyBuilder: AssemblyBuilder)
-
- protected var currentModule: Module = null
- /**
- * Visit a ModuleBuilder
- */
- @throws(classOf[IOException])
- def caseModuleBuilder(module: ModuleBuilder)
-
- protected var currentType: Type = null
-
- def printTypeParams(sortedTVars : Array[GenericParamAndConstraints]) {
-
- def constraintFlags(tVar : GenericParamAndConstraints) = {
- val varianceDirective = (if (tVar.isCovariant) "+ " else (if (tVar.isContravariant) "- " else ""))
- val typeKindDirective = (if (tVar.isReferenceType) "class " else (if (tVar.isValueType) "valuetype " else ""))
- val dfltConstrDirective = (if (tVar.hasDefaultConstructor) ".ctor " else "")
- varianceDirective + typeKindDirective + dfltConstrDirective
- }
-
- def tparamName(tVar : GenericParamAndConstraints) = {
- /* TODO Type-params in referenced assemblies may lack a name (those in a TypeBuilder or MethodBuilder shouldn't).
- Given that we need not list (in ilasm syntax) the original type-params' names when
- providing type arguments to it, the only type-param-names we'll serialize into a .msil file
- are those for type-params in a TypeBuilder or MethodBuilder. Still, more details on this
- appear in Sec. 4.5 "Faulty metadata in XMLReaderFactory" of
- http://lamp.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/Libs4Lib.pdf
-
- To avoid name clashes when choosing a param name,
- first collect all existing tparam-names from a type (and its nested types).
- Not that those names are needed (ordinal positions can be used instead)
- but will look better when disassembling with ildasm. */
- assert(tVar.Name != null)
- tVar.Name
- }
-
- if(sortedTVars.length == 0) { return }
- print('<')
- val lastIdx = sortedTVars.length - 1
- for (it <- 0 until sortedTVars.length) {
- val tVar = sortedTVars(it)
- print(constraintFlags(tVar))
- if(tVar.Constraints.length > 0) {
- print('(')
- for (ic <- 0 until tVar.Constraints.length) {
- val cnstrt = tVar.Constraints(ic)
- printReference(cnstrt)
- if (ic < lastIdx) { print(", ") }
- }
- print(')')
- }
- print(" " + tparamName(tVar))
- if (it < lastIdx) { print(", ") }
- }
- print('>')
- }
-
- /**
- * Visit a TypeBuilder
- */
- @throws(classOf[IOException])
- def caseTypeBuilder(`type`: TypeBuilder) {
- currentType = `type`
- if (!`type`.Namespace.equals("") && `type`.DeclaringType == null) {
- print(".namespace \'" ); print(`type`.Namespace); println("\'")
- println("{"); indent()
- }
- print(".class ")
- // <classHead> ::=
- // <classAttr>* <id>
- // [extends <typeReference>]
- // [implements <typeReference> [, <typeReference>]*]
- print(TypeAttributes.toString(`type`.Attributes))
- print(" \'"); print(`type`.Name); print("\'")
- printTypeParams(`type`.getSortedTVars())
- if (`type`.BaseType() != null) {
- println()
- print(" extends ")
- printReference(`type`.BaseType())
- }
- val ifaces: Array[Type] = `type`.getInterfaces()
- if (ifaces.length > 0) {
- println()
- print(" implements ")
- for (i <- 0 until ifaces.length) {
- if (i > 0) {
- println(",")
- print(" ")
- }
- printReference(ifaces(i))
- }
- }
- println()
- println("{")
- indent()
- if (!nomembers && `type`.sourceFilename != null)
- println(".line " + `type`.sourceLine
- + " '" + `type`.sourceFilename + "'")
- if (!nomembers) {
- printAttributes(`type`)
- }
- // print nested classes
- val nested = `type`.nestedTypeBuilders.iterator
- while(nested.hasNext)
- print(nested.next().asInstanceOf[TypeBuilder])
-
- // print each field
- val fields = `type`.fieldBuilders.iterator
- while(fields.hasNext)
- print(fields.next().asInstanceOf[FieldBuilder])
-
- // print each constructor
- val constrs = `type`.constructorBuilders.iterator
- while (constrs.hasNext)
- print(constrs.next().asInstanceOf[ConstructorBuilder])
-
- // print each method
- val methods = `type`.methodBuilders.iterator
- while (methods.hasNext) {
- val method = methods.next().asInstanceOf[MethodBuilder]
- assert(method.DeclaringType == `type`)
- print(method)
- }
-
- undent(); println("}")
- if (!`type`.Namespace.equals("") && `type`.DeclaringType == null) {
- undent(); println("}")
- }
- currentType = null
- }
-
- /**
- * Visit a FieldBuilder
- */
- @throws(classOf[IOException])
- def caseFieldBuilder(field: FieldBuilder) {
- if (nomembers) return
- // [[int32]] <fieldAttr>* <type> <id> [= <fieldInit> | at <dataLabel>]
- print(".field ")
- print(FieldAttributes.toString(field.Attributes))
- print(" "); printSignature(field.FieldType, field.cmods)
- print(" \'"); print(field.Name); print("\'")
- if (field.IsLiteral()) {
- print(" = ")
- val value = field.getValue()
- if (value == null) {
- print("nullref")
- } else if (value.isInstanceOf[String]) {
- print(msilString(value.asInstanceOf[String]))
- } else if (value.isInstanceOf[Boolean]) {
- print("bool (")
- print(if((value.asInstanceOf[Boolean]).booleanValue()) { "true" } else { "false" })
- print(")")
- } else if (value.isInstanceOf[Byte]) {
- print("int8 (")
- print(value)
- print(")")
- } else if (value.isInstanceOf[java.lang.Short]) {
- print("int16 (")
- print(value)
- print(")")
- } else if (value.isInstanceOf[Character]) {
- print("char (")
- print((value.asInstanceOf[Character]).charValue())
- print(")")
- } else if (value.isInstanceOf[Integer]) {
- print("int32 (")
- print((value.asInstanceOf[Integer]).intValue())
- print(")")
- } else if (value.isInstanceOf[Long]) {
- print("int64 (")
- print((value.asInstanceOf[Long]).longValue())
- print(")")
- } else if (value.isInstanceOf[Float]) {
- print(msilSyntaxFloat(value.asInstanceOf[Float]))
- } else if (value.isInstanceOf[Double]) {
- print(msilSyntaxDouble(value.asInstanceOf[Double]))
- } else {
- throw new Error("ILPrinterVisitor: Illegal default value: "
- + value.getClass())
- }
- }
- println()
- printAttributes(field)
- }
-
- def msilSyntaxFloat(valFlo: java.lang.Float) : String = {
- // !!! check if encoding is correct
- val bits = java.lang.Float.floatToRawIntBits(valFlo.floatValue())
- /* see p. 170 in Lidin's book Expert .NET 2.0 IL Assembler */
- /* Note: no value is equal to Nan, including NaN. Thus, x == Float.NaN always evaluates to false. */
- val res = if (valFlo.isNaN) "0xFFC00000 /* NaN */ " /* TODO this is 'quiet NaN, http://www.savrola.com/resources/NaN.html , what's the difference with a 'signaling NaN'?? */
- else if (java.lang.Float.NEGATIVE_INFINITY == valFlo.floatValue) "0xFF800000 /* NEGATIVE_INFINITY */ "
- else if (java.lang.Float.POSITIVE_INFINITY == valFlo.floatValue) "0x7F800000 /* POSITIVE_INFINITY */ "
- else bits
- "float32 (" + res + ")"
- }
-
- def msilSyntaxDouble(valDou: java.lang.Double) : String = {
- // !!! check if encoding is correct
- val bits = java.lang.Double.doubleToRawLongBits(valDou.doubleValue())
- /* see p. 170 in Lidin's book Expert .NET 2.0 IL Assembler */
- /* Note: no value is equal to Nan, including NaN. Thus, x == Double.NaN always evaluates to false. */
- val res = if (valDou.isNaN) "0xffffffffffffffff /* NaN */ " /* TODO this is 'quiet NaN, http://www.savrola.com/resources/NaN.html , what's the difference with a 'signaling NaN'?? */
- else if (java.lang.Double.NEGATIVE_INFINITY == valDou.doubleValue) "0xfff0000000000000 /* NEGATIVE_INFINITY */ "
- else if (java.lang.Double.POSITIVE_INFINITY == valDou.doubleValue) "0x7ff0000000000000 /* POSITIVE_INFINITY */ "
- else bits
- // float64(float64(...)) != float64(...)
- "float64 (" + res + ")"
- }
-
- /**
- * Visit a ConstructorBuilder
- */
- @throws(classOf[IOException])
- def caseConstructorBuilder(constr: ConstructorBuilder) {
- if (nomembers) return
- print(".method "); printHeader(constr, VOID)
- println(); println("{"); indent()
- printAttributes(constr)
- try {
- print(constr.GetILGenerator())
- } catch {
- case e : RuntimeException => {
- System.err.println("In method " + constr)
- e.printStackTrace()
- }
- }
- undent(); println("}")
- }
-
- /**
- * Visit a MethodBuilder
- */
- @throws(classOf[IOException])
- def caseMethodBuilder(method: MethodBuilder) {
- if (nomembers) return
- print(".method "); printHeader(method, method.ReturnType)
- if (method.IsAbstract()
- || (method.DeclaringType != null
- && method.DeclaringType.IsInterface()
- && !method.IsStatic()))
- {
- println(" {"); indent()
- printAttributes(method)
- undent(); println("}")
- } else {
- println(); println("{"); indent()
- printAttributes(method)
- if (method == entryPoint)
- println(".entrypoint")
- try {
- print(method.GetILGenerator())
- } catch {
- case e: RuntimeException =>
- System.err.println("In method " + method)
- e.printStackTrace()
- }
- undent(); println("}")
- }
- }
-
- /**
- * Visit a ParameterBuilder
- */
- @throws(classOf[IOException])
- def caseParameterBuilder(param: ParameterBuilder) {
- print(ParameterAttributes.toString(param.Attributes))
- printSignature(param.ParameterType)
- //print(' ') print(marshal)
- print(' '); printName(param.Name)
- }
-
- var locals: Array[LocalBuilder] = null
- /**
- * Visit an ILGenerator
- */
- @throws(classOf[IOException])
- def caseILGenerator(code: ILGenerator) {
- // print maxstack
- println(".maxstack " + code.getMaxStacksize())
- // get the local variables
- locals = code.getLocals()
- if (locals.length > 0) {
- println(".locals init (")
- indent()
- for (i <- 0 until locals.length) {
- if (i > 0) println(",")
- print(locals(i))
- } // end while
- undent()
- println(")")
- }
- // get 3 iterators for the 3 lists
- val itL = code.getLabelIterator()
- val itO = code.getOpcodeIterator()
- val itA = code.getArgumentIterator()
- // iterate over each opcode
- while (itO.hasNext) {
- // first print label
- val label = itL.next
- val oOpt = code.lineNums.get(label)
- if (oOpt.isDefined) {
- println(".line " + oOpt.get)
- }
- argument = itA.next.asInstanceOf[Object]
- printLabel(label)
- val o2 = itO.next
- if (o2 != null) {
- print(" ")
- print(o2.asInstanceOf[OpCode])
- }
- println()
- } // end while
- }
-
- /**
- * visit an OpCode
- */
- @throws(classOf[IOException])
- def caseOpCode(opCode: OpCode) {
- val opString = opCode.toString()
- print(opString)
- pad(14 - opString.length())
-
- // switch opcode
- if (opCode == OpCode.Ldstr) {
- print(msilString(argument.toString()))
- } else if(opCode == OpCode.Switch) {
- // switch ( <labels> )
- print("(")
- val targets = argument.asInstanceOf[Array[Label]]
- val m = targets.length
- for (i <- 0 until m) {
- if (i != 0) print(", ")
- print(targets(i))
- } // end for
- print(")")
- } else if(opCode == OpCode.Call || opCode == OpCode.Callvirt || opCode == OpCode.Jmp || opCode == OpCode.Ldftn || opCode == OpCode.Ldvirtftn) {
- // call | callvirt | jmp | ldftn | ldvirtftn
- // <instr_method> <callConv> <type> [ <typeSpec> :: ] <methodName>
- printSignature(argument.asInstanceOf[MethodBase])
- } else if (opCode == OpCode.Newobj) {
- printSignature(argument.asInstanceOf[ConstructorInfo])
- // ldfld | ldflda | ldsfld | ldsflda | stfld | stsfld
- } else if (opCode == OpCode.Ldfld || opCode == OpCode.Ldflda || opCode == OpCode.Ldsfld || opCode == OpCode.Ldsflda || opCode == OpCode.Stfld || opCode == OpCode.Stsfld) {
- printSignature(argument.asInstanceOf[FieldInfo])
- } else if (opCode == OpCode.Castclass || opCode == OpCode.Isinst || opCode == OpCode.Ldobj || opCode == OpCode.Newarr) {
- printSignature(argument.asInstanceOf[Type])
- } else if (opCode == OpCode.Box || opCode == OpCode.Unbox || opCode == OpCode.Ldtoken || opCode == OpCode.Initobj) {
- printReference(argument.asInstanceOf[Type])
- } else if (opCode == OpCode.Ldloc || opCode == OpCode.Ldloc_S || opCode == OpCode.Ldloca || opCode == OpCode.Ldloca_S || opCode == OpCode.Stloc || opCode == OpCode.Stloc_S) {
- val loc = argument.asInstanceOf[LocalBuilder]
- print(loc.slot); print("\t// "); printSignature(loc.LocalType)
- print(" \'"); print(loc.name); print("\'")
- //print("'") print(((LocalBuilder)argument).name) print("'")
- } else if (opCode == OpCode.Ldloc_0 || opCode == OpCode.Ldloc_1 || opCode == OpCode.Ldloc_2 || opCode == OpCode.Ldloc_3 ) {
- val loc = locals(opCode.CEE_opcode - OpCode.CEE_LDLOC_0)
- print("\t// "); printSignature(loc.LocalType)
- print(" \'"); print(loc.name); print("\'")
- } else if (opCode == OpCode.Stloc_0 || opCode == OpCode.Stloc_1 || opCode == OpCode.Stloc_2 || opCode == OpCode.Stloc_3 ) {
- val loc = locals(opCode.CEE_opcode - OpCode.CEE_STLOC_0)
- print("\t// "); printSignature(loc.LocalType)
- print(" \'"); print(loc.name); print("\'")
- } else if (opCode == OpCode.Readonly) {
- // nothing to do
- } else if (opCode == OpCode.Constrained) {
- printReference(argument.asInstanceOf[Type])
- } else if (opCode == OpCode.Ldelema) {
- printReference(argument.asInstanceOf[Type])
- } else {
- // by default print toString argument if any
- if (argument != null) {
- val strArgument = java.lang.String.valueOf(argument)
- if ( argument.isInstanceOf[java.lang.Float]
- && ( strArgument.equals("NaN")
- || strArgument.equals("-Infinity")
- || strArgument.equals("Infinity")))
- print(msilSyntaxFloat(argument.asInstanceOf[java.lang.Float]))
- else if ( argument.isInstanceOf[java.lang.Double]
- && ( strArgument.equals("NaN")
- || strArgument.equals("-Infinity")
- || strArgument.equals("Infinity")))
- print(msilSyntaxDouble(argument.asInstanceOf[java.lang.Double]))
- else print(strArgument)
- }
-
- } // end switch
- }
-
- /**
- * Visit a Label
- */
- def printLabel(label: Label) {
- val kind = label.getKind()
- if (kind == Label.Kind.Normal) {
- print(label+ ": ")
- } else if (kind == Label.Kind.NewScope) {
- print("{"); indent()
- } else if (kind == Label.Kind.EndScope) {
- undent(); print("}")
- } else if (kind == Label.Kind.Try) {
- print(".try {"); indent()
- } else if (kind == Label.Kind.Catch) {
- undent()
- println("}")
- print("catch ")
- printReference(argument.asInstanceOf[Type])
- print(" {")
- indent()
- } else if (kind == Label.Kind.Filter) {
- undent()
- println("}")
- print("filter {")
- indent()
- } else if (kind == Label.Kind.EndFilter) {
- print("endfilter")
- undent()
- println("}")
- } else if (kind == Label.Kind.Finally) {
- undent()
- println("}")
- print("finally {")
- indent()
- } else if (kind == Label.Kind.EndTry) {
- undent()
- print("}")
- }
- }
-
- /**
- * Visit a LocalBuilder
- */
- @throws(classOf[IOException])
- def caseLocalBuilder(localBuilder: LocalBuilder) {
- // print type
- printSignature(localBuilder.LocalType)
- // space
- print(" \'")
- // print name
- print(localBuilder.name)
- print("\'")
- }
-
-
- //##########################################################################
-
- def printAssemblySignature(assem: Assembly, extern: Boolean) {
- print(".assembly ")
- if (extern)
- print("extern ")
- val an = assem.GetName()
- printName(an.Name); println()
- println("{")
- if (!extern)
- printAttributes(assem)
- val v = an.Version
- if (v != null) {
- print(" .ver "); print(v.Major); print(':'); print(v.Minor)
- print(':'); print(v.Build); print(':')
- print(v.Revision); println()
- }
- var key = an.GetPublicKeyToken()
- if (key != null) {
- print(" .publickeytoken = ("); print(PEFile.bytes2hex(key))
- println(")")
- } else {
- key = an.GetPublicKey()
- if (key != null) {
- print(" .publickey = ("); print(PEFile.bytes2hex(key))
- println(")")
- }
- }
- println("}")
- }
-
-
- def printSignature(field: FieldInfo) {
- printSignature(field.FieldType, field.cmods)
- //print(' ') print(owner)
- print(' ')
- //if (field.IsStatic && field.DeclaringType != currentType) {
- printReference(field.DeclaringType)
- print("::")
- //}
- printName(field.Name)
- }
-
- // print method head
- @throws(classOf[IOException])
- def printHeader(method: MethodBase, returnType: Type) {
- print(MethodAttributes.toString(method.Attributes))
- print(' '); print(CallingConventions.toString(method.CallingConvention))
- print(' '); printSignature(returnType)
- //print(' ') print(marshal)
- print(' '); printName(method.Name)
- if(method.isInstanceOf[MethodInfo]) {
- val mthdInfo = method.asInstanceOf[MethodInfo]
- printTypeParams(mthdInfo.getSortedMVars())
- }
- val params = method.GetParameters()
- print('(')
- for (i <- 0 until params.length) {
- if (i > 0) print(", ")
- print(params(i).asInstanceOf[ParameterBuilder])
- }
- print(") ")
-
- print(MethodImplAttributes
- .toString(method.GetMethodImplementationFlags()))
- }
-
-
- def printSignature(method: MethodBase) {
- var returnType: Type = null
- if (method.isInstanceOf[MethodInfo])
- returnType = (method.asInstanceOf[MethodInfo]).ReturnType
- else if (method.isInstanceOf[ConstructorInfo])
- returnType = VOID
- else
- throw new RuntimeException()
-
- val s = CallingConventions.toString(method.CallingConvention)
- print(s)
- if (s.length() > 0) print(' ')
- printSignature(returnType)
- //print(' ') print(owner)
- print(' '); printReference(method.DeclaringType)
- print("::"); printName(method.Name)
-
- val params = method.GetParameters()
- print("(")
- for (i <- 0 until params.length) {
- if (i > 0) print(", ")
- printSignature(params(i).ParameterType)
- }
- print(")")
- }
-
- def printSignature(marked: Type, cmods: Array[CustomModifier]) {
- printSignature(marked)
- if( (cmods != null) && !cmods.isEmpty ) {
- print(" ")
- for(cm <- cmods) {
- print(if (cm.isReqd) "modreq( " else "modopt( ")
- printReference(cm.marker)
- print(" ) ")
- }
- }
- }
-
- def printSignature(`type`: Type) {
- val sigOpt = primitive.get(`type`)
- if (sigOpt.isDefined) {
- print(sigOpt.get)
- return
- }
- if (`type`.HasElementType()) {
- printSignature(`type`.GetElementType())
- if (`type`.IsArray())
- print("[]")
- else if (`type`.IsPointer())
- print('*')
- else if (`type`.IsByRef())
- print('&')
- } else {
- val preref = if (`type`.isInstanceOf[Type.TMVarUsage]) ""
- else if(`type`.IsValueType()) "valuetype "
- else "class "
- print(preref)
- printReference(`type`)
- }
- }
-
- def printReference(`type`: Type) {
- if (`type`.Module != null) { // i.e. not PrimitiveType and not TMVarUsage
- if (`type`.Assembly() != currentModule.Assembly) {
- print('['); print(`type`.Assembly().GetName().Name); print("]")
- } else if (`type`.Module != currentModule) {
- print("[.module "); print(`type`.Module.Name); print("]")
- }
- }
- printTypeName(`type`)
- }
-
- def printTypeName(`type`: Type) {
- if (`type`.isInstanceOf[ConstructedType]) {
- val ct = `type`.asInstanceOf[ConstructedType]
- printTypeName(ct.instantiatedType)
- print("<")
- var i = 0
- while (i < ct.typeArgs.length) {
- val ta = ct.typeArgs(i)
- val sigOpt = primitive.get(ta)
- if (sigOpt.isDefined) print(sigOpt.get)
- else printTypeName(ta); /* should be printSignature, but don't want `class` or `valuetype`
- appearing before a type param usage. */
- i = i + 1;
- if (i < ct.typeArgs.length) {
- print(", ")
- }
- }
- print(">")
- } else if (`type`.DeclaringType != null) {
- printTypeName(`type`.DeclaringType)
- print('/')
- printName(`type`.Name)
- } else {
- printName(`type`.FullName)
- }
- }
-
- def printAttributes(icap: ICustomAttributeProvider) {
- val attrs = icap.GetCustomAttributes(false)
- for (i <- 0 until attrs.length) {
- print(".custom ")
- printSignature((attrs(i).asInstanceOf[Attribute]).getConstructor())
- print(" = (")
- print(PEFile.bytes2hex((attrs(i).asInstanceOf[Attribute]).getValue()))
- println(")")
- }
- }
-
- //##########################################################################
-
-} // class ILPrinterVisitor
-
-object ILPrinterVisitor {
- final val VOID: Type = Type.GetType("System.Void")
- protected final val TAB = 4
-
- protected final val SPACES = " "
- protected final val SPACES_LEN = SPACES.length()
-
- def hasControlChars(str: String): Boolean = {
- for(i <- 0 until str.length()) {
- val ch = str.charAt(i)
- ch match {
- case '\b' =>
- case '\t' =>
- case '\n' =>
- case '\f' =>
- case '\r' =>
- case _ => if(Character.isISOControl(ch)) return true
- }
- }
- return false
- }
-
- final val EMPTY: String = ""
- def msilString(s: String): String = {
- if (hasControlChars(s)) {
- try {
- return "bytearray (" + PEFile.bytes2hex(s.getBytes("UTF-16LE")) + ")"
- } catch {
- case e : java.io.UnsupportedEncodingException => throw new RuntimeException(e)
- }
- }
- val str = new StringBuffer(s)
- var ss = EMPTY
- var i = 0
- while(i < str.length()) {
- ss = EMPTY
- val c = str.charAt(i)
- c match {
- case '\b' => ss = "\\b"
- case '\t' => ss = "\\t"
- case '\n' => ss = "\\n"
- case '\f' => ss = "\\f"
- case '\r' => ss = "\\r"
- case '\"' => ss = "\\\""
- case '\'' => ss = "\\\'"
- case '\\' => ss = "\\\\"
- case _ => if (Character.isISOControl(c))
- ss = "\\u" + PEFile.int2hex(Character.getNumericValue(c))
- }
- if (ss != EMPTY) {
- str.replace(i, i + 1, ss)
- i = i + ss.length() - 1
- }
- i = i + 1
- }
- return "\"" + str.toString() + "\""
- }
-
- /**
- * the main printer method
- */
- @throws(classOf[IOException])
- def printAssembly(assemblyBuilder: AssemblyBuilder, fileName: String) {
- assemblyBuilder.apply(new SingleFileILPrinterVisitor(fileName))
- }
-
- @throws(classOf[IOException])
- def printAssembly(assemblyBuilder: AssemblyBuilder, destPath: String, sourceFilesPath: String) {
- assemblyBuilder.apply(new MultipleFilesILPrinterVisitor(destPath, sourceFilesPath))
- }
-
- /** The current assembly */
- var currAssembly: Assembly = _
-
- final var primitive = scala.collection.mutable.Map.empty[Type, String]
- def addPrimitive(name: String, sig: String) {
- val `type` =
- Type.GetType(name)
- assert(`type` != null, "Cannot lookup primitive type " + `type`)
- primitive.put(`type`, sig)
- }
-
- addPrimitive("System.Object", "object")
- addPrimitive("System.String", "string")
- addPrimitive("System.Void", "void")
- addPrimitive("System.Boolean", "bool")
- addPrimitive("System.Char", "char")
- addPrimitive("System.SByte", "int8")
- addPrimitive("System.Byte", "unsigned int8")
- addPrimitive("System.Int16", "int16")
- addPrimitive("System.UInt16", "unsigned int16")
- addPrimitive("System.Int32", "int32")
- addPrimitive("System.UInt32", "unsigned int32")
- addPrimitive("System.Int64", "int64")
- addPrimitive("System.UInt64", "unsigned int64")
- addPrimitive("System.IntPtr", "native int")
- addPrimitive("System.UIntPtr", "unsigned native int")
- addPrimitive("System.Single", "float32")
- addPrimitive("System.Double", "float64")
- addPrimitive("System.TypedReference", "typedref")
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/Label.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/Label.scala
deleted file mode 100644
index a80ea72323..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/Label.scala
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.Type
-
-/**
- * Represents a label in the instruction stream. Label is used in conjunction
- * with the ILGenerator class.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-abstract class Label protected {
- import Label._
- def isInitialized(): Boolean
- def getKind(): Kind
- def getAddress(): Int
- def getStacksize(): Int
- def setStacksize(stacksize: Int): Unit
- def incStacksize(): Unit
- def mergeWith(that: Label): Unit
-}
-
-object Label {
- final val DUMMY: Int = -((1<<31)-1)
-
- //##########################################################################
-
- final class NormalLabel(_address: Int, _stacksize: Int) extends Label {
-
- //##########################################################################
- // protected constructors
-
- //the position of the label
- private var address: Int = _address
-
- //the stacksize at the label
- private var stacksize: Int = _stacksize
-
- def this() {
- this(-1, DUMMY)
- }
-
- def this(that: NormalLabel) {
- this(that.getAddress(), that.getStacksize())
- }
-
- //##########################################################################
- // instrumental methods only used by ILGenerator
-
- def isInitialized() = (getAddress() != -1) || (stacksize != DUMMY)
-
- def getAddress() = address
-
- def getStacksize() = stacksize
-
- def setStacksize(stacksize: Int) {
- assert(stacksize >= 0)
- this.stacksize = stacksize
- }
-
- def incStacksize() {
- stacksize = stacksize + 1
- }
-
- def getKind(): Kind = Kind.Normal
-
- def mergeWith(that: Label) {
- //assert address < 0 : "this.address = " + address + " that.address = " + that.address
- address = that.getAddress()
-
- // assert stacksize == that.stacksize
- // : "this.stacksize = " + stacksize + " that.stacksize = "
- // + that.stacksize
- // stacksize = that.stacksize
- val ss: Int = math.max(stacksize, that.getStacksize())
- stacksize = ss
- that.setStacksize(ss)
- }
-
- //##########################################################################
- //
-
- /**
- * the toString Method return the label name
- * it's "IL" + address
- */
- override def toString(): String = {
- var pad: String = ""
- if (address < 16) pad = "000"
- else if (address < 256) pad = "00"
- else if (address < 4096) pad = "0"
- return "IL_" + pad + Integer.toHexString(address)
- }
-
- def getString(): String = {
- val name = super.toString()
- val i: Int = name.lastIndexOf('.')
- return name.substring(i+1, name.length())
- }
- }
-
- //########################################################################
- // Special Labels
-
- final class SpecialLabel(kind: Label.Kind) extends Label {
- def isInitialized() = true
- def getAddress(): Int = { throw new RuntimeException("" + kind) }
- def getStacksize(): Int = { throw new RuntimeException("" + kind) }
- def setStacksize(stacksize: Int) { throw new RuntimeException("" + kind) }
- def incStacksize() { throw new RuntimeException("" + kind) }
- def getKind(): Kind = kind
- def mergeWith(that: Label) { throw new RuntimeException("" + kind) }
- override def toString() = s"Label($kind)"
- }
-
- final val NewScope: Label = new SpecialLabel(Kind.NewScope)
- final val EndScope: Label = new SpecialLabel(Kind.EndScope)
- final val Try: Label = new SpecialLabel(Kind.Try)
- final val Catch: Label = new SpecialLabel(Kind.Catch)
- final val Filter: Label = new SpecialLabel(Kind.Filter)
- final val EndFilter: Label = new SpecialLabel(Kind.EndFilter)
- final val Finally: Label = new SpecialLabel(Kind.Finally)
- final val EndTry: Label = new SpecialLabel(Kind.EndTry)
-
- final class Kind() {}
-
- final object Kind {
- final val Normal: Kind = new Kind()
-
- final val NewScope: Kind = new Kind()
- final val EndScope: Kind = new Kind()
-
- final val Try: Kind = new Kind()
- final val Catch: Kind = new Kind()
- final val Filter: Kind = new Kind()
- final val EndFilter: Kind = new Kind()
- final val Finally: Kind = new Kind()
- final val EndTry: Kind = new Kind()
- }
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/LocalBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/LocalBuilder.scala
deleted file mode 100644
index 73bca4639f..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/LocalBuilder.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.Type
-
-/**
- * Represents a local variable within a method or constructor.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class LocalBuilder(_slot : Int, localType : Type) extends Visitable {
-
- /**
- * the type of the local variable.
- */
- var LocalType : Type = localType
-
- // the name of the local variable
- var name : String = "L_" + slot
-
- // the slot occupied by this local in the corresponding ILGenerator
- var slot : Int = _slot
-
- /**
- * Sets the name of this local variable.
- */
- def SetLocalSymInfo(name : String) {
- this.name = name
- }
-
- override def toString() : String = name
-
- /**
- * the apply method for a visitor
- */
- def apply(v : Visitor) {
- v.caseLocalBuilder(this)
- }
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/MethodBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/MethodBuilder.scala
deleted file mode 100644
index 237d8fd728..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/MethodBuilder.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.MethodInfo
-import ch.epfl.lamp.compiler.msil.ParameterInfo
-import ch.epfl.lamp.compiler.msil.Type
-import ch.epfl.lamp.compiler.msil.ConstructorInfo
-import java.io.IOException
-
-/**
- * Defines and represents a method of a dynamic class.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class MethodBuilder(name: String, declType: Type, attrs: Int, returnType: Type, paramTypes: Array[Type])
- extends MethodInfo(name, declType, attrs, returnType, paramTypes)
- with ICustomAttributeSetter
- with Visitable
-{
-
- //##########################################################################
- // public interface
-
- /** Defines a parameter of this method. TODO: Parameters are indexed staring
- * from number 1 for the first parameter
- */
- def DefineParameter(pos: Int, attr: Int, name: String): ParameterBuilder = {
- val param = new ParameterBuilder(name, params(pos).ParameterType, attr, pos)
- params(pos) = param
- return param
- }
-
- /** Returns an ILGenerator for this method. */
- def GetILGenerator(): ILGenerator = {
- if (ilGenerator == null)
- throw new RuntimeException
- ("No code generator available for this method: " + this)
- return ilGenerator
- }
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
-
- /** The apply method for a visitor. */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseMethodBuilder(this)
- }
-
- //##########################################################################
-
- // the Intermediate Language Generator
- // it contains the method's body
- protected final val ilGenerator : ILGenerator =
- if (DeclaringType == null // global method
- || !DeclaringType.IsInterface())
- new ILGenerator(this)
- else null
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ModuleBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ModuleBuilder.scala
deleted file mode 100644
index 2319d5ca27..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ModuleBuilder.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil._
-import java.io.IOException
-
-/**
- * Defines and represents a module. Get an instance of ModuleBuilder
- * by calling DefineDynamicModule
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class ModuleBuilder(name: String, fullname: String, scopeName: String, assembly: Assembly)
- extends Module(name, fullname, scopeName, assembly)
- with ICustomAttributeSetter
- with Visitable
-{
-
- //##########################################################################
- // public interface
-
- /**
- * Complete the global function definitions for this dynamic module.
- * This method should be called when the user is done with defining
- * all of the global functions within this dynamic module. After calling
- * this function, no more new global functions or new global data are
- * allowed.
- */
- def CreateGlobalFunctions() {
- if (globalsCreated)
- throw new RuntimeException("Global functions are already created")
- this.fields = fieldBuilders.toArray // (fields).asInstanceOf[Array[FieldInfo]]
- this.methods = methodBuilders.toArray // (methods).asInstanceOf[Array[MethodInfo]]
- globalsCreated = true
- }
-
- /**
- * Constructs a TypeBuilder for a type with the specified name
- */
- def DefineType(typeName: String): TypeBuilder = {
- return DefineType(typeName, 0, null, Type.EmptyTypes)
- }
-
- /**
- * Constructs a TypeBuilder for a type with the specified name
- * and specified attributes
- */
- def DefineType(typeName: String, attributes: Int): TypeBuilder = {
- return DefineType(typeName, attributes, null, Type.EmptyTypes)
- }
-
- /**
- * Constructs a TypeBuilder given type name, its attributes,
- * and the type that the defined type extends.
- */
- def DefineType(typeName: String, attributes: Int,
- baseType: Type): TypeBuilder = {
- return DefineType(typeName, attributes, baseType, Type.EmptyTypes)
- }
-
- /**
- * Constructs a TypeBuilder given the Full specification of a type,
- * Given the type name, attributes, the type that the defined type
- * extends, and the interfaces that the defined type implements.
- */
- def DefineType(typeName: String,
- attributes: Int,
- baseType: Type,
- interfaces: Array[Type]): TypeBuilder =
- {
- val t: Type = GetType(typeName) // Module.GetType(String)
- if (t != null)
- throw new RuntimeException
- ("Type [" + Assembly + "]" + typeName + "' already exists!")
- val `type` =
- new TypeBuilder(this, attributes, typeName, baseType, interfaces, null)
- addType(`type`)
- return `type`
- }
-
- /**
- * Defines a global method given its name, attributes, return type, and
- * parameter types.
- */
- def DefineGlobalMethod(name: String, attributes: Int,
- returnType: Type, paramTypes: Array[Type]): MethodBuilder =
- {
- val method =
- new MethodBuilder(name, null, attributes, returnType, paramTypes)
- methodBuilders += method
- return method
- }
-
-
- override def GetTypes(): Array[Type] = {
- val res = scala.collection.mutable.ArrayBuffer.empty[Type]
- val iter = typesMap.values().iterator
- while (iter.hasNext) {
- res += iter.next.asInstanceOf[Type]
- }
- return res.toArray
- }
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
- // internal members
-
- var globalsCreated = false
- protected var fieldBuilders = scala.collection.mutable.ArrayBuffer.empty[FieldInfo]
- protected var methodBuilders = scala.collection.mutable.ArrayBuffer.empty[MethodInfo]
-
- override def addType(t: Type): Type = {
- return super.addType(t)
- }
-
- //##########################################################################
-
- /**
- * the apply method for a visitor
- */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseModuleBuilder(this)
- }
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/MultipleFilesILPrinterVisitor.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/MultipleFilesILPrinterVisitor.scala
deleted file mode 100644
index bbbbf40508..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/MultipleFilesILPrinterVisitor.scala
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies in MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import java.io.PrintWriter
-import java.io.IOException
-import java.util.Iterator
-import java.util.Arrays
-
-import ch.epfl.lamp.compiler.msil._
-import ch.epfl.lamp.compiler.msil.emit
-import ch.epfl.lamp.compiler.msil.util.Table
-
-/**
- * The MSIL printer Visitor. It prints a complete
- * assembly into separate files. Then these files can be compiled by ilasm.
- *
- * @author Nikolay Mihaylov
- * @author Daniel Lorch
- * @version 1.0
- */
-final class MultipleFilesILPrinterVisitor(destPath: String, sourceFilesPath: String) extends ILPrinterVisitor {
- /**
- * Visit an AssemblyBuilder
- */
- @throws(classOf[IOException])
- def caseAssemblyBuilder(assemblyBuilder: AssemblyBuilder) {
- ILPrinterVisitor.currAssembly = assemblyBuilder
-
- // first get the entryPoint
- this.entryPoint = assemblyBuilder.EntryPoint
-
- // all external assemblies
- as = assemblyBuilder.getExternAssemblies()
- scala.util.Sorting.quickSort(as)(assemblyNameComparator) // Arrays.sort(as, assemblyNameComparator)
-
- // print each module
- val m: Array[Module] = assemblyBuilder.GetModules()
- nomembers = true
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[ModuleBuilder])
- }
-
- nomembers = false
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[ModuleBuilder])
- }
- ILPrinterVisitor.currAssembly = null
- }
-
- /**
- * Visit a ModuleBuilder
- */
- @throws(classOf[IOException])
- def caseModuleBuilder(module: ModuleBuilder) {
- val assemblyBuilder = ILPrinterVisitor.currAssembly.asInstanceOf[AssemblyBuilder]
-
- // print module declaration
- currentModule = module
-
- // global methods typically contain the main method
- if (!module.globalsCreated)
- module.CreateGlobalFunctions()
-
- val m: Array[MethodInfo] = module.GetMethods()
-
- // "Types" contain all the classes
- val t: Array[Type] = module.GetTypes()
- for(i <- 0 until t.length) {
- val tBuilder = t(i).asInstanceOf[TypeBuilder]
- val sourceFilename = tBuilder.sourceFilename
- val sourceFilepath = new File(tBuilder.sourceFilepath).getCanonicalPath
- val sourcePath = new File(sourceFilesPath).getCanonicalPath
- var append = false
-
- if(!sourceFilepath.startsWith(sourcePath)) {
- throw new IOException("Source file " + sourceFilename + " must lie inside sourcepath " + sourcePath)
- }
-
- assert(sourceFilepath.endsWith(".scala"), "Source file doesn't end with .scala")
- val relativeFilename = sourceFilepath.substring(sourcePath.length, sourceFilepath.length() - 6) + ".msil"
- val fileName = new File(destPath, relativeFilename)
- if(assemblyBuilder.generatedFiles.contains(fileName.getPath)) {
- append = true
- } else {
- fileName.getParentFile().mkdirs()
- assemblyBuilder.generatedFiles += (fileName.getPath)
- }
-
- out = new PrintWriter(new BufferedWriter(new FileWriter(fileName, append)))
- // only write assembly boilerplate and class prototypes
- if (!append && nomembers) {
- printAssemblyBoilerplate()
-
- print(".module \'"); print(module.Name); println("\'")
- printAttributes(module)
- }
-
- print(t(i).asInstanceOf[TypeBuilder])
- out.close()
- }
-
- // now write the global methods (typically contains the "main" method)
- if(!nomembers) {
- val globalMethods: File = new File(destPath, ILPrinterVisitor.currAssembly.GetName().Name + ".msil")
- val append = assemblyBuilder.generatedFiles.contains(globalMethods.getPath)
-
- out = new PrintWriter(new BufferedWriter(new FileWriter(globalMethods, append)))
-
- // make sure we're the first in the list (ilasm uses the first file name to guess the output file name)
- assemblyBuilder.generatedFiles.insert(0, globalMethods.getPath)
-
- // if this file hasn't been created by one of the classes, write boilerplate
- if(!append) {
- printAssemblyBoilerplate()
-
- print(".module \'"); print(module.Name); println("\'")
- printAttributes(module)
- }
-
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[MethodBuilder])
- }
-
- out.close()
- }
-
- currentModule = null
- }
-
-} // class MultipleFilesILPrinterVisitor
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCode.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCode.scala
deleted file mode 100644
index b0c26884af..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCode.scala
+++ /dev/null
@@ -1,1948 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.IOException
-
-/** Describes a Microsoft intermediate language (MSIL) instruction.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class OpCode extends Visitable {
- import OpCode._
-
- /** The Operation Code of Microsoft intermediate language (MSIL) instruction. */
- var CEE_opcode : Int = _
-
- /** The name of the Microsoft intermediate language (MSIL) instruction. */
- var CEE_string: String = _
-
- /** The type of Microsoft intermediate language (MSIL) instruction. */
- var CEE_code: Short = _
-
- /** How the Microsoft intermediate language (MSIL) instruction pops the stack. */
- var CEE_pop: Byte = _
-
- /** How the Microsoft intermediate language (MSIL) instruction pushes operand onto the stack. */
- var CEE_push: Byte = _
-
- /** Describes the type of flow control. */
- var CEE_flow: Byte = _
-
- /** ????? */
- var CEE_inline: Byte = _
-
- var CEE_length: Byte = _
-
- var CEE_popush: Byte = _
-
- /**
- * the apply method for a visitor
- */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseOpCode(this)
- }
-
- protected def length(): Byte = {
- val code = OpCode.length(CEE_code)
- val inline = OpCode.INLINE_length(CEE_inline)
- return if(inline < 0) { -1 } else { (code + inline).toByte }
- }
-
- protected def popush(): Byte = {
- val pop = OpCode.POP_size(CEE_pop)
- val push = OpCode.PUSH_size(CEE_push)
- return if(pop < 0 || push < 0) { OpCode.POPUSH_SPECIAL } else { (push - pop).toByte }
- }
-
- override def toString(): String = {
- return CEE_string
- }
-}
-
-object OpCode {
-
- //########################################################################
- // Common Execution Environment opcodes
-
- final val CEE_NOP : Int = 0x0000
- final val CEE_BREAK : Int = 0x0001
- final val CEE_LDARG_0 : Int = 0x0002
- final val CEE_LDARG_1 : Int = 0x0003
- final val CEE_LDARG_2 : Int = 0x0004
- final val CEE_LDARG_3 : Int = 0x0005
- final val CEE_LDLOC_0 : Int = 0x0006
- final val CEE_LDLOC_1 : Int = 0x0007
- final val CEE_LDLOC_2 : Int = 0x0008
- final val CEE_LDLOC_3 : Int = 0x0009
- final val CEE_STLOC_0 : Int = 0x000A
- final val CEE_STLOC_1 : Int = 0x000B
- final val CEE_STLOC_2 : Int = 0x000C
- final val CEE_STLOC_3 : Int = 0x000D
- final val CEE_LDARG_S : Int = 0x000E
- final val CEE_LDARGA_S : Int = 0x000F
- final val CEE_STARG_S : Int = 0x0010
- final val CEE_LDLOC_S : Int = 0x0011
- final val CEE_LDLOCA_S : Int = 0x0012
- final val CEE_STLOC_S : Int = 0x0013
- final val CEE_LDNULL : Int = 0x0014
- final val CEE_LDC_I4_M1 : Int = 0x0015
- final val CEE_LDC_I4_0 : Int = 0x0016
- final val CEE_LDC_I4_1 : Int = 0x0017
- final val CEE_LDC_I4_2 : Int = 0x0018
- final val CEE_LDC_I4_3 : Int = 0x0019
- final val CEE_LDC_I4_4 : Int = 0x001A
- final val CEE_LDC_I4_5 : Int = 0x001B
- final val CEE_LDC_I4_6 : Int = 0x001C
- final val CEE_LDC_I4_7 : Int = 0x001D
- final val CEE_LDC_I4_8 : Int = 0x001E
- final val CEE_LDC_I4_S : Int = 0x001F
- final val CEE_LDC_I4 : Int = 0x0020
- final val CEE_LDC_I8 : Int = 0x0021
- final val CEE_LDC_R4 : Int = 0x0022
- final val CEE_LDC_R8 : Int = 0x0023
- final val CEE_UNUSED49 : Int = 0x0024
- final val CEE_DUP : Int = 0x0025
- final val CEE_POP : Int = 0x0026
- final val CEE_JMP : Int = 0x0027
- final val CEE_CALL : Int = 0x0028
- final val CEE_CALLI : Int = 0x0029
- final val CEE_RET : Int = 0x002A
- final val CEE_BR_S : Int = 0x002B
- final val CEE_BRFALSE_S : Int = 0x002C
- final val CEE_BRTRUE_S : Int = 0x002D
- final val CEE_BEQ_S : Int = 0x002E
- final val CEE_BGE_S : Int = 0x002F
- final val CEE_BGT_S : Int = 0x0030
- final val CEE_BLE_S : Int = 0x0031
- final val CEE_BLT_S : Int = 0x0032
- final val CEE_BNE_UN_S : Int = 0x0033
- final val CEE_BGE_UN_S : Int = 0x0034
- final val CEE_BGT_UN_S : Int = 0x0035
- final val CEE_BLE_UN_S : Int = 0x0036
- final val CEE_BLT_UN_S : Int = 0x0037
- final val CEE_BR : Int = 0x0038
- final val CEE_BRFALSE : Int = 0x0039
- final val CEE_BRTRUE : Int = 0x003A
- final val CEE_BEQ : Int = 0x003B
- final val CEE_BGE : Int = 0x003C
- final val CEE_BGT : Int = 0x003D
- final val CEE_BLE : Int = 0x003E
- final val CEE_BLT : Int = 0x003F
- final val CEE_BNE_UN : Int = 0x0040
- final val CEE_BGE_UN : Int = 0x0041
- final val CEE_BGT_UN : Int = 0x0042
- final val CEE_BLE_UN : Int = 0x0043
- final val CEE_BLT_UN : Int = 0x0044
- final val CEE_SWITCH : Int = 0x0045
- final val CEE_LDIND_I1 : Int = 0x0046
- final val CEE_LDIND_U1 : Int = 0x0047
- final val CEE_LDIND_I2 : Int = 0x0048
- final val CEE_LDIND_U2 : Int = 0x0049
- final val CEE_LDIND_I4 : Int = 0x004A
- final val CEE_LDIND_U4 : Int = 0x004B
- final val CEE_LDIND_I8 : Int = 0x004C
- final val CEE_LDIND_I : Int = 0x004D
- final val CEE_LDIND_R4 : Int = 0x004E
- final val CEE_LDIND_R8 : Int = 0x004F
- final val CEE_LDIND_REF : Int = 0x0050
- final val CEE_STIND_REF : Int = 0x0051
- final val CEE_STIND_I1 : Int = 0x0052
- final val CEE_STIND_I2 : Int = 0x0053
- final val CEE_STIND_I4 : Int = 0x0054
- final val CEE_STIND_I8 : Int = 0x0055
- final val CEE_STIND_R4 : Int = 0x0056
- final val CEE_STIND_R8 : Int = 0x0057
- final val CEE_ADD : Int = 0x0058
- final val CEE_SUB : Int = 0x0059
- final val CEE_MUL : Int = 0x005A
- final val CEE_DIV : Int = 0x005B
- final val CEE_DIV_UN : Int = 0x005C
- final val CEE_REM : Int = 0x005D
- final val CEE_REM_UN : Int = 0x005E
- final val CEE_AND : Int = 0x005F
- final val CEE_OR : Int = 0x0060
- final val CEE_XOR : Int = 0x0061
- final val CEE_SHL : Int = 0x0062
- final val CEE_SHR : Int = 0x0063
- final val CEE_SHR_UN : Int = 0x0064
- final val CEE_NEG : Int = 0x0065
- final val CEE_NOT : Int = 0x0066
- final val CEE_CONV_I1 : Int = 0x0067
- final val CEE_CONV_I2 : Int = 0x0068
- final val CEE_CONV_I4 : Int = 0x0069
- final val CEE_CONV_I8 : Int = 0x006A
- final val CEE_CONV_R4 : Int = 0x006B
- final val CEE_CONV_R8 : Int = 0x006C
- final val CEE_CONV_U4 : Int = 0x006D
- final val CEE_CONV_U8 : Int = 0x006E
- final val CEE_CALLVIRT : Int = 0x006F
- final val CEE_CPOBJ : Int = 0x0070
- final val CEE_LDOBJ : Int = 0x0071
- final val CEE_LDSTR : Int = 0x0072
- final val CEE_NEWOBJ : Int = 0x0073
- final val CEE_CASTCLASS : Int = 0x0074
- final val CEE_ISINST : Int = 0x0075
- final val CEE_CONV_R_UN : Int = 0x0076
- final val CEE_UNUSED58 : Int = 0x0077
- final val CEE_UNUSED1 : Int = 0x0078
- final val CEE_UNBOX : Int = 0x0079
- final val CEE_THROW : Int = 0x007A
- final val CEE_LDFLD : Int = 0x007B
- final val CEE_LDFLDA : Int = 0x007C
- final val CEE_STFLD : Int = 0x007D
- final val CEE_LDSFLD : Int = 0x007E
- final val CEE_LDSFLDA : Int = 0x007F
- final val CEE_STSFLD : Int = 0x0080
- final val CEE_STOBJ : Int = 0x0081
- final val CEE_CONV_OVF_I1_UN : Int = 0x0082
- final val CEE_CONV_OVF_I2_UN : Int = 0x0083
- final val CEE_CONV_OVF_I4_UN : Int = 0x0084
- final val CEE_CONV_OVF_I8_UN : Int = 0x0085
- final val CEE_CONV_OVF_U1_UN : Int = 0x0086
- final val CEE_CONV_OVF_U2_UN : Int = 0x0087
- final val CEE_CONV_OVF_U4_UN : Int = 0x0088
- final val CEE_CONV_OVF_U8_UN : Int = 0x0089
- final val CEE_CONV_OVF_I_UN : Int = 0x008A
- final val CEE_CONV_OVF_U_UN : Int = 0x008B
- final val CEE_BOX : Int = 0x008C
- final val CEE_NEWARR : Int = 0x008D
- final val CEE_LDLEN : Int = 0x008E
- final val CEE_LDELEMA : Int = 0x008F
- final val CEE_LDELEM_I1 : Int = 0x0090
- final val CEE_LDELEM_U1 : Int = 0x0091
- final val CEE_LDELEM_I2 : Int = 0x0092
- final val CEE_LDELEM_U2 : Int = 0x0093
- final val CEE_LDELEM_I4 : Int = 0x0094
- final val CEE_LDELEM_U4 : Int = 0x0095
- final val CEE_LDELEM_I8 : Int = 0x0096
- final val CEE_LDELEM_I : Int = 0x0097
- final val CEE_LDELEM_R4 : Int = 0x0098
- final val CEE_LDELEM_R8 : Int = 0x0099
- final val CEE_LDELEM_REF : Int = 0x009A
- final val CEE_STELEM_I : Int = 0x009B
- final val CEE_STELEM_I1 : Int = 0x009C
- final val CEE_STELEM_I2 : Int = 0x009D
- final val CEE_STELEM_I4 : Int = 0x009E
- final val CEE_STELEM_I8 : Int = 0x009F
- final val CEE_STELEM_R4 : Int = 0x00A0
- final val CEE_STELEM_R8 : Int = 0x00A1
- final val CEE_STELEM_REF : Int = 0x00A2
- final val CEE_UNUSED2 : Int = 0x00A3
- final val CEE_UNUSED3 : Int = 0x00A4
- final val CEE_UNUSED4 : Int = 0x00A5
- final val CEE_UNUSED5 : Int = 0x00A6
- final val CEE_UNUSED6 : Int = 0x00A7
- final val CEE_UNUSED7 : Int = 0x00A8
- final val CEE_UNUSED8 : Int = 0x00A9
- final val CEE_UNUSED9 : Int = 0x00AA
- final val CEE_UNUSED10 : Int = 0x00AB
- final val CEE_UNUSED11 : Int = 0x00AC
- final val CEE_UNUSED12 : Int = 0x00AD
- final val CEE_UNUSED13 : Int = 0x00AE
- final val CEE_UNUSED14 : Int = 0x00AF
- final val CEE_UNUSED15 : Int = 0x00B0
- final val CEE_UNUSED16 : Int = 0x00B1
- final val CEE_UNUSED17 : Int = 0x00B2
- final val CEE_CONV_OVF_I1 : Int = 0x00B3
- final val CEE_CONV_OVF_U1 : Int = 0x00B4
- final val CEE_CONV_OVF_I2 : Int = 0x00B5
- final val CEE_CONV_OVF_U2 : Int = 0x00B6
- final val CEE_CONV_OVF_I4 : Int = 0x00B7
- final val CEE_CONV_OVF_U4 : Int = 0x00B8
- final val CEE_CONV_OVF_I8 : Int = 0x00B9
- final val CEE_CONV_OVF_U8 : Int = 0x00BA
- final val CEE_UNUSED50 : Int = 0x00BB
- final val CEE_UNUSED18 : Int = 0x00BC
- final val CEE_UNUSED19 : Int = 0x00BD
- final val CEE_UNUSED20 : Int = 0x00BE
- final val CEE_UNUSED21 : Int = 0x00BF
- final val CEE_UNUSED22 : Int = 0x00C0
- final val CEE_UNUSED23 : Int = 0x00C1
- final val CEE_REFANYVAL : Int = 0x00C2
- final val CEE_CKFINITE : Int = 0x00C3
- final val CEE_UNUSED24 : Int = 0x00C4
- final val CEE_UNUSED25 : Int = 0x00C5
- final val CEE_MKREFANY : Int = 0x00C6
- final val CEE_UNUSED59 : Int = 0x00C7
- final val CEE_UNUSED60 : Int = 0x00C8
- final val CEE_UNUSED61 : Int = 0x00C9
- final val CEE_UNUSED62 : Int = 0x00CA
- final val CEE_UNUSED63 : Int = 0x00CB
- final val CEE_UNUSED64 : Int = 0x00CC
- final val CEE_UNUSED65 : Int = 0x00CD
- final val CEE_UNUSED66 : Int = 0x00CE
- final val CEE_UNUSED67 : Int = 0x00CF
- final val CEE_LDTOKEN : Int = 0x00D0
- final val CEE_CONV_U2 : Int = 0x00D1
- final val CEE_CONV_U1 : Int = 0x00D2
- final val CEE_CONV_I : Int = 0x00D3
- final val CEE_CONV_OVF_I : Int = 0x00D4
- final val CEE_CONV_OVF_U : Int = 0x00D5
- final val CEE_ADD_OVF : Int = 0x00D6
- final val CEE_ADD_OVF_UN : Int = 0x00D7
- final val CEE_MUL_OVF : Int = 0x00D8
- final val CEE_MUL_OVF_UN : Int = 0x00D9
- final val CEE_SUB_OVF : Int = 0x00DA
- final val CEE_SUB_OVF_UN : Int = 0x00DB
- final val CEE_ENDFINALLY : Int = 0x00DC
- final val CEE_LEAVE : Int = 0x00DD
- final val CEE_LEAVE_S : Int = 0x00DE
- final val CEE_STIND_I : Int = 0x00DF
- final val CEE_CONV_U : Int = 0x00E0
- final val CEE_UNUSED26 : Int = 0x00E1
- final val CEE_UNUSED27 : Int = 0x00E2
- final val CEE_UNUSED28 : Int = 0x00E3
- final val CEE_UNUSED29 : Int = 0x00E4
- final val CEE_UNUSED30 : Int = 0x00E5
- final val CEE_UNUSED31 : Int = 0x00E6
- final val CEE_UNUSED32 : Int = 0x00E7
- final val CEE_UNUSED33 : Int = 0x00E8
- final val CEE_UNUSED34 : Int = 0x00E9
- final val CEE_UNUSED35 : Int = 0x00EA
- final val CEE_UNUSED36 : Int = 0x00EB
- final val CEE_UNUSED37 : Int = 0x00EC
- final val CEE_UNUSED38 : Int = 0x00ED
- final val CEE_UNUSED39 : Int = 0x00EE
- final val CEE_UNUSED40 : Int = 0x00EF
- final val CEE_UNUSED41 : Int = 0x00F0
- final val CEE_UNUSED42 : Int = 0x00F1
- final val CEE_UNUSED43 : Int = 0x00F2
- final val CEE_UNUSED44 : Int = 0x00F3
- final val CEE_UNUSED45 : Int = 0x00F4
- final val CEE_UNUSED46 : Int = 0x00F5
- final val CEE_UNUSED47 : Int = 0x00F6
- final val CEE_UNUSED48 : Int = 0x00F7
- final val CEE_PREFIX7 : Int = 0x00F8
- final val CEE_PREFIX6 : Int = 0x00F9
- final val CEE_PREFIX5 : Int = 0x00FA
- final val CEE_PREFIX4 : Int = 0x00FB
- final val CEE_PREFIX3 : Int = 0x00FC
- final val CEE_PREFIX2 : Int = 0x00FD
- final val CEE_PREFIX1 : Int = 0x00FE
- final val CEE_PREFIXREF : Int = 0x00FF
-
- final val CEE_ARGLIST : Int = 0x0100
- final val CEE_CEQ : Int = 0x0101
- final val CEE_CGT : Int = 0x0102
- final val CEE_CGT_UN : Int = 0x0103
- final val CEE_CLT : Int = 0x0104
- final val CEE_CLT_UN : Int = 0x0105
- final val CEE_LDFTN : Int = 0x0106
- final val CEE_LDVIRTFTN : Int = 0x0107
- final val CEE_UNUSED56 : Int = 0x0108
- final val CEE_LDARG : Int = 0x0109
- final val CEE_LDARGA : Int = 0x010A
- final val CEE_STARG : Int = 0x010B
- final val CEE_LDLOC : Int = 0x010C
- final val CEE_LDLOCA : Int = 0x010D
- final val CEE_STLOC : Int = 0x010E
- final val CEE_LOCALLOC : Int = 0x010F
- final val CEE_UNUSED57 : Int = 0x0110
- final val CEE_ENDFILTER : Int = 0x0111
- final val CEE_UNALIGNED : Int = 0x0112
- final val CEE_VOLATILE : Int = 0x0113
- final val CEE_TAILCALL : Int = 0x0114
- final val CEE_INITOBJ : Int = 0x0115
- final val CEE_CONSTRAINED : Int = 0xFE16
- final val CEE_READONLY : Int = 0xFE1E
- final val CEE_UNUSED68 : Int = 0x0116
- final val CEE_CPBLK : Int = 0x0117
- final val CEE_INITBLK : Int = 0x0118
- final val CEE_UNUSED69 : Int = 0x0119
- final val CEE_RETHROW : Int = 0x011A
- final val CEE_UNUSED51 : Int = 0x011B
- final val CEE_SIZEOF : Int = 0x011C
- final val CEE_REFANYTYPE : Int = 0x011D
- final val CEE_UNUSED52 : Int = 0x011E
- final val CEE_UNUSED53 : Int = 0x011F
- final val CEE_UNUSED54 : Int = 0x0120
- final val CEE_UNUSED55 : Int = 0x0121
- final val CEE_UNUSED70 : Int = 0x0122
-
- final val CEE_ILLEGAL : Int = 0x0140
- final val CEE_MACRO_END : Int = 0x0141
-
- final val CEE_BRNULL : Int = 0x0180 // CEE_BRFALSE
- final val CEE_BRNULL_S : Int = 0x0181 // CEE_BRFALSE_S
- final val CEE_BRZERO : Int = 0x0182 // CEE_BRFALSE
- final val CEE_BRZERO_S : Int = 0x0183 // CEE_BRFALSE_S
- final val CEE_BRINST : Int = 0x0184 // CEE_BRTRUE
- final val CEE_BRINST_S : Int = 0x0185 // CEE_BRTRUE_S
- final val CEE_LDIND_U8 : Int = 0x0186 // CEE_LDIND_I8
- final val CEE_LDELEM_U8 : Int = 0x0187 // CEE_LDELEM_I8
- final val CEE_LDC_I4_M1x : Int = 0x0188 // CEE_LDC_I4_M1
- final val CEE_ENDFAULT : Int = 0x0189 // CEE_ENDFINALLY
-
- final val CEE_BRNONZERO : Int = 0x01C0 // CEE_BRTRUE
- final val CEE_BRNONZERO_S : Int = 0x01C1 // CEE_BRTRUE_S
-
- final val CEE_BRNOT : Int = 0x01C2
- final val CEE_BRNOT_S : Int = 0x01C3
- final val CEE_NOCODE : Int = 0x01C4
-
- final val CEE_count : Int = 0x0200
-
-
- //########################################################################
- // Opcode's amount and type of poped data
-
- final val POP_NONE : Byte = 0x00
- final val POP_1 : Byte = 0x01
- final val POP_1_1 : Byte = 0x02
- final val POP_I : Byte = 0x03
- final val POP_I_1 : Byte = 0x04
- final val POP_I_I : Byte = 0x05
- final val POP_I_I8 : Byte = 0x06
- final val POP_I_R4 : Byte = 0x07
- final val POP_I_R8 : Byte = 0x08
- final val POP_I_I_I : Byte = 0x09
- final val POP_REF : Byte = 0x0A
- final val POP_REF_1 : Byte = 0x0B
- final val POP_REF_I : Byte = 0x0C
- final val POP_REF_I_I : Byte = 0x0D
- final val POP_REF_I_I8 : Byte = 0x0E
- final val POP_REF_I_R4 : Byte = 0x0F
- final val POP_REF_I_R8 : Byte = 0x10
- final val POP_REF_I_REF : Byte = 0x11
- final val POP_SPECIAL : Byte = 0x12
- final val POP_count : Int = 0x13
- final val POP_size : Array[Byte] = new Array[Byte](POP_count)
-
- POP_size(POP_NONE) = 0
- POP_size(POP_1) = 1
- POP_size(POP_1_1) = 2
- POP_size(POP_I) = 1
- POP_size(POP_I_1) = 2
- POP_size(POP_I_I) = 2
- POP_size(POP_I_I8) = 2
- POP_size(POP_I_R4) = 2
- POP_size(POP_I_R8) = 2
- POP_size(POP_I_I_I) = 3
- POP_size(POP_REF) = 1
- POP_size(POP_REF_1) = 2
- POP_size(POP_REF_I) = 2
- POP_size(POP_REF_I_I) = 3
- POP_size(POP_REF_I_I8) = 3
- POP_size(POP_REF_I_R4) = 3
- POP_size(POP_REF_I_R8) = 3
- POP_size(POP_REF_I_REF) = 3
- POP_size(POP_SPECIAL) = -1
-
- //########################################################################
- // Opcode's amount and type of pushed data
-
- final val PUSH_NONE : Byte = 0x00
- final val PUSH_1 : Byte = 0x01
- final val PUSH_1_1 : Byte = 0x02
- final val PUSH_I : Byte = 0x03
- final val PUSH_I8 : Byte = 0x04
- final val PUSH_R4 : Byte = 0x05
- final val PUSH_R8 : Byte = 0x06
- final val PUSH_REF : Byte = 0x07
- final val PUSH_SPECIAL : Byte = 0x08
- final val PUSH_count : Int = 0x09
- final val PUSH_size : Array[Byte] = new Array[Byte](PUSH_count)
-
- PUSH_size(PUSH_NONE) = 0
- PUSH_size(PUSH_1) = 1
- PUSH_size(PUSH_1_1) = 2
- PUSH_size(PUSH_I) = 1
- PUSH_size(PUSH_I8) = 1
- PUSH_size(PUSH_R4) = 1
- PUSH_size(PUSH_R8) = 1
- PUSH_size(PUSH_REF) = 1
- PUSH_size(PUSH_SPECIAL) = -1
-
- //########################################################################
- // Opcode's amount of moved data
-
- final val POPUSH_SPECIAL : Byte = -128
-
- //########################################################################
- // Opcode's inline argument types
-
- final val INLINE_NONE : Byte = 0x00
- final val INLINE_VARIABLE_S : Byte = 0x01
- final val INLINE_TARGET_S : Byte = 0x02
- final val INLINE_I_S : Byte = 0x03
- final val INLINE_VARIABLE : Byte = 0x04
- final val INLINE_TARGET : Byte = 0x05
- final val INLINE_I : Byte = 0x06
- final val INLINE_I8 : Byte = 0x07
- final val INLINE_R : Byte = 0x08
- final val INLINE_R8 : Byte = 0x09
- final val INLINE_STRING : Byte = 0x0A
- final val INLINE_TYPE : Byte = 0x0B
- final val INLINE_FIELD : Byte = 0x0C
- final val INLINE_METHOD : Byte = 0x0D
- final val INLINE_SIGNATURE : Byte = 0x0E
- final val INLINE_TOKEN : Byte = 0x0F
- final val INLINE_SWITCH : Byte = 0x10
- final val INLINE_count : Int = 0x11
- final val INLINE_length : Array[Byte] = new Array[Byte](INLINE_count)
-
- INLINE_length(INLINE_NONE) = 0
- INLINE_length(INLINE_VARIABLE_S) = 1
- INLINE_length(INLINE_TARGET_S) = 1
- INLINE_length(INLINE_I_S) = 1
- INLINE_length(INLINE_VARIABLE) = 2
- INLINE_length(INLINE_TARGET) = 4
- INLINE_length(INLINE_I) = 4
- INLINE_length(INLINE_I8) = 8
- INLINE_length(INLINE_R) = 4
- INLINE_length(INLINE_R8) = 8
- INLINE_length(INLINE_STRING) = 4
- INLINE_length(INLINE_TYPE) = 4
- INLINE_length(INLINE_FIELD) = 4
- INLINE_length(INLINE_METHOD) = 4
- INLINE_length(INLINE_SIGNATURE) = 4
- INLINE_length(INLINE_SWITCH) = 4
- INLINE_length(INLINE_TOKEN) = 4
-
- //########################################################################
- // Opcode's control flow implications
-
- final val FLOW_META : Byte = 0x00
- final val FLOW_NEXT : Byte = 0x01
- final val FLOW_BRANCH : Byte = 0x02
- final val FLOW_COND_BRANCH : Byte = 0x03
- final val FLOW_BREAK : Byte = 0x04
- final val FLOW_CALL : Byte = 0x05
- final val FLOW_RETURN : Byte = 0x06
- final val FLOW_THROW : Byte = 0x07
- final val FLOW_count : Int = 0x08
-
- //########################################################################
- // Init methods for Opcode
-
- def opcode(that: OpCode, opcode: Int, string: String, code: Int,
- pop: Byte, push: Byte, inline: Byte, flow: Byte) {
- that.CEE_opcode = opcode
- that.CEE_string = string
- that.CEE_code = code.toShort
- that.CEE_pop = pop
- that.CEE_push = push
- that.CEE_inline = inline
- that.CEE_flow = flow
- that.CEE_length = that.length()
- that.CEE_popush = that.popush()
- }
-
- def length(code: Int): Byte = {
- if ((code & 0xFFFFFF00) == 0xFFFFFF00) return 1
- if ((code & 0xFFFFFF00) == 0xFFFFFE00) return 2
- return 0
- }
-
- //########################################################################
- // case OpCode
-
- /**
- * Adds two values and pushes the result onto the evaluation stack.
- */
- final val Add = new OpCode()
- opcode(Add, CEE_ADD, "add", 0xFFFFFF58, POP_1_1, PUSH_1, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Fills space if bytecodes are patched. No meaningful operation is performed
- * although a processing cycle can be consumed.
- */
- final val Nop = new OpCode()
- opcode(Nop, CEE_NOP, "nop", 0xFFFFFF00, POP_NONE, PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Signals the Common Language Infrastructure (CLI) to inform the debugger that
- * a break point has been tripped.
- */
- final val Break = new OpCode()
- opcode(Break, CEE_BREAK, "break" , 0xFFFFFF01, POP_NONE, PUSH_NONE , INLINE_NONE , FLOW_BREAK)
-
- /**
- * Loads the argument at index 0 onto the evaluation stack.
- */
- final val Ldarg_0 = new OpCode()
- opcode(Ldarg_0, CEE_LDARG_0 , "ldarg.0" , 0xFFFFFF02, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the argument at index 1 onto the evaluation stack.
- */
- final val Ldarg_1 = new OpCode()
- opcode(Ldarg_1, CEE_LDARG_1 , "ldarg.1" , 0xFFFFFF03, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the argument at index 2 onto the evaluation stack.
- */
- final val Ldarg_2 = new OpCode()
- opcode(Ldarg_2, CEE_LDARG_2 , "ldarg.2" , 0xFFFFFF04, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the argument at index 3 onto the evaluation stack.
- */
- final val Ldarg_3 = new OpCode()
- opcode(Ldarg_3, CEE_LDARG_3 , "ldarg.3" , 0xFFFFFF05, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the local variable at index 0 onto the evaluation stack.
- */
- final val Ldloc_0 = new OpCode()
- opcode(Ldloc_0, CEE_LDLOC_0 , "ldloc.0" , 0xFFFFFF06, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the local variable at index 1 onto the evaluation stack.
- */
- final val Ldloc_1 = new OpCode()
- opcode(Ldloc_1, CEE_LDLOC_1 , "ldloc.1" , 0xFFFFFF07, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the local variable at index 2 onto the evaluation stack.
- */
- final val Ldloc_2 = new OpCode()
- opcode(Ldloc_2, CEE_LDLOC_2 , "ldloc.2" , 0xFFFFFF08, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the local variable at index 3 onto the evaluation stack.
- */
- final val Ldloc_3 = new OpCode()
- opcode(Ldloc_3, CEE_LDLOC_3 , "ldloc.3" , 0xFFFFFF09, POP_NONE, PUSH_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 0.
- */
- final val Stloc_0 = new OpCode()
- opcode(Stloc_0, CEE_STLOC_0 , "stloc.0" , 0xFFFFFF0A, POP_1 , PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 1.
- */
- final val Stloc_1 = new OpCode()
- opcode(Stloc_1, CEE_STLOC_1 , "stloc.1" , 0xFFFFFF0B, POP_1 , PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 2.
- */
- final val Stloc_2 = new OpCode()
- opcode(Stloc_2, CEE_STLOC_2 , "stloc.2" , 0xFFFFFF0C, POP_1 , PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 3.
- */
- final val Stloc_3 = new OpCode()
- opcode(Stloc_3, CEE_STLOC_3 , "stloc.3" , 0xFFFFFF0D, POP_1 , PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the argument (referenced by a specified short form index)
- * onto the evaluation stack.
- */
- final val Ldarg_S = new OpCode()
- opcode(Ldarg_S, CEE_LDARG_S , "ldarg.s" , 0xFFFFFF0E, POP_NONE, PUSH_1 , INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Load an argument address, in short form, onto the evaluation stack.
- */
- final val Ldarga_S = new OpCode()
- opcode(Ldarga_S, CEE_LDARGA_S , "ldarga.s" , 0xFFFFFF0F, POP_NONE, PUSH_I , INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Loads the local variable at a specific index onto the evaluation stack,
- * short form.
- */
- final val Ldloc_S = new OpCode()
- opcode(Ldloc_S, CEE_LDLOC_S , "ldloc.s" , 0xFFFFFF11, POP_NONE, PUSH_1 , INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Loads the address of the local variable at a specific index onto
- * the evaluation stack, short form.
- */
- final val Ldloca_S = new OpCode()
- opcode(Ldloca_S, CEE_LDLOCA_S , "ldloca.s" , 0xFFFFFF12, POP_NONE, PUSH_I , INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Stores the value on top of the evaluation stack in the argument slot
- * at a specified index, short form.
- */
- final val Starg_S = new OpCode()
- opcode(Starg_S, CEE_STARG_S , "starg.s" , 0xFFFFFF10, POP_1 , PUSH_NONE , INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and stores it
- * in a the local variable list at index (short form).
- */
- final val Stloc_S = new OpCode()
- opcode(Stloc_S, CEE_STLOC_S , "stloc.s" , 0xFFFFFF13, POP_1 , PUSH_NONE, INLINE_VARIABLE_S, FLOW_NEXT)
-
- /**
- * Pushes a null reference (type O) onto the evaluation stack.
- */
- final val Ldnull = new OpCode()
- opcode(Ldnull, CEE_LDNULL , "ldnull" , 0xFFFFFF14, POP_NONE, PUSH_REF , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of -1 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_M1 = new OpCode()
- opcode(Ldc_I4_M1, CEE_LDC_I4_M1, "ldc.i4.m1", 0xFFFFFF15, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 0 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_0 = new OpCode()
- opcode(Ldc_I4_0, CEE_LDC_I4_0 , "ldc.i4.0" , 0xFFFFFF16, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 1 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_1 = new OpCode()
- opcode(Ldc_I4_1, CEE_LDC_I4_1 , "ldc.i4.1" , 0xFFFFFF17, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 2 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_2 = new OpCode()
- opcode(Ldc_I4_2, CEE_LDC_I4_2 , "ldc.i4.2" , 0xFFFFFF18, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 3 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_3 = new OpCode()
- opcode(Ldc_I4_3, CEE_LDC_I4_3 , "ldc.i4.3" , 0xFFFFFF19, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 4 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_4 = new OpCode()
- opcode(Ldc_I4_4, CEE_LDC_I4_4 , "ldc.i4.4" , 0xFFFFFF1A, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 5 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_5 = new OpCode()
- opcode(Ldc_I4_5, CEE_LDC_I4_5 , "ldc.i4.5" , 0xFFFFFF1B, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 6 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_6 = new OpCode()
- opcode(Ldc_I4_6, CEE_LDC_I4_6 , "ldc.i4.6", 0xFFFFFF1C, POP_NONE, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 7 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_7 = new OpCode()
- opcode(Ldc_I4_7, CEE_LDC_I4_7 , "ldc.i4.7", 0xFFFFFF1D, POP_NONE , PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the integer value of 8 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_8 = new OpCode()
- opcode(Ldc_I4_8, CEE_LDC_I4_8 , "ldc.i4.8", 0xFFFFFF1E, POP_NONE , PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes the supplied int8 value onto the evaluation stack as an int32, short form.
- */
- final val Ldc_I4_S = new OpCode()
- opcode(Ldc_I4_S, CEE_LDC_I4_S , "ldc.i4.s", 0xFFFFFF1F, POP_NONE , PUSH_I, INLINE_I_S, FLOW_NEXT)
-
- /**
- * Pushes a supplied value of type int32 onto the evaluation stack as an int32.
- */
- final val Ldc_I4 = new OpCode()
- opcode(Ldc_I4, CEE_LDC_I4, "ldc.i4" , 0xFFFFFF20, POP_NONE , PUSH_I, INLINE_I , FLOW_NEXT)
-
- /**
- * Pushes a supplied value of type int64 onto the evaluation stack as an int64.
- */
- final val Ldc_I8 = new OpCode()
- opcode(Ldc_I8, CEE_LDC_I8, "ldc.i8" , 0xFFFFFF21, POP_NONE , PUSH_I8, INLINE_I8 , FLOW_NEXT)
-
- /**
- * Pushes a supplied value of type float32 onto the evaluation stack as type F (float).
- */
- final val Ldc_R4 = new OpCode()
- opcode(Ldc_R4, CEE_LDC_R4, "ldc.r4" , 0xFFFFFF22, POP_NONE , PUSH_R4, INLINE_R , FLOW_NEXT)
-
- /**
- * Pushes a supplied value of type float64 onto the evaluation stack as type F (float).
- */
- final val Ldc_R8 = new OpCode()
- opcode(Ldc_R8, CEE_LDC_R8, "ldc.r8" , 0xFFFFFF23, POP_NONE , PUSH_R8, INLINE_R8 , FLOW_NEXT)
-
- /**
- * Copies the current topmost value on the evaluation stack, and then pushes the copy
- * onto the evaluation stack.
- */
- final val Dup = new OpCode()
- opcode(Dup, CEE_DUP , "dup" , 0xFFFFFF25, POP_1 , PUSH_1_1 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Removes the value currently on top of the evaluation stack.
- */
- final val Pop = new OpCode()
- opcode(Pop, CEE_POP , "pop" , 0xFFFFFF26, POP_1 , PUSH_NONE , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Exits current method and jumps to specified method.
- */
- final val Jmp = new OpCode()
- opcode(Jmp, CEE_JMP , "jmp" , 0xFFFFFF27, POP_NONE , PUSH_NONE , INLINE_METHOD, FLOW_CALL)
-
- /**
- * Calls the method indicated by the passed method descriptor.
- */
- final val Call = new OpCode()
- opcode(Call, CEE_CALL , "call" , 0xFFFFFF28, POP_SPECIAL, PUSH_SPECIAL, INLINE_METHOD , FLOW_CALL)
-
- /**
- * constrained prefix
- */
- final val Constrained = new OpCode()
-opcode(Constrained, CEE_CONSTRAINED , "constrained." , 0xFFFFFE16, POP_NONE, PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * readonly prefix
- */
- final val Readonly = new OpCode()
-opcode(Readonly, CEE_READONLY , "readonly." , 0xFFFFFE1E, POP_NONE, PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Calls the method indicated on the evaluation stack (as a pointer to an entry point)
- * with arguments described by a calling convention.
- */
- final val Calli = new OpCode()
- opcode(Calli, CEE_CALLI, "calli" , 0xFFFFFF29, POP_SPECIAL, PUSH_SPECIAL, INLINE_SIGNATURE , FLOW_CALL)
-
- /**
- * Returns from the current method, pushing a return value (if present) from the caller's
- * evaluation stack onto the callee's evaluation stack.
- */
- final val Ret = new OpCode()
- opcode(Ret, CEE_RET , "ret" , 0xFFFFFF2A, POP_SPECIAL, PUSH_NONE, INLINE_NONE , FLOW_RETURN)
-
- /**
- * Unconditionally transfers control to a target instruction (short form).
- */
- final val Br_S = new OpCode()
- opcode(Br_S, CEE_BR_S , "br.s" , 0xFFFFFF2B, POP_NONE, PUSH_NONE, INLINE_TARGET_S , FLOW_BRANCH)
-
- /**
- * Transfers control to a target instruction if value is false, a null reference, or zero.
- */
- final val Brfalse_S = new OpCode()
- opcode(Brfalse_S, CEE_BRFALSE_S,"brfalse.s", 0xFFFFFF2C, POP_I, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if value is true, not null, or non-zero.
- */
- final val Brtrue_S = new OpCode()
- opcode(Brtrue_S, CEE_BRTRUE_S , "brtrue.s", 0xFFFFFF2D, POP_I, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if two values are equal.
- */
- final val Beq_S = new OpCode()
- opcode(Beq_S, CEE_BEQ_S, "beq.s", 0xFFFFFF2E, POP_1_1 , PUSH_NONE, INLINE_TARGET_S , FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * or equal to the second value.
- */
- final val Bge_S = new OpCode()
- opcode(Bge_S, CEE_BGE_S, "bge.s", 0xFFFFFF2F, POP_1_1 , PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * the second value.
- */
- final val Bgt_S = new OpCode()
- opcode(Bgt_S, CEE_BGT_S, "bgt.s" , 0xFFFFFF30, POP_1_1 , PUSH_NONE, INLINE_TARGET_S , FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * or equal to the second value.
- */
- final val Ble_S = new OpCode()
- opcode(Ble_S, CEE_BLE_S, "ble.s" , 0xFFFFFF31, POP_1_1 , PUSH_NONE, INLINE_TARGET_S , FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * the second value.
- */
- final val Blt_S = new OpCode()
- opcode(Blt_S, CEE_BLT_S, "blt.s", 0xFFFFFF32, POP_1_1, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) when two unsigned integer values
- * or unordered float values are not equal.
- */
- final val Bne_Un_S = new OpCode()
- opcode(Bne_Un_S, CEE_BNE_UN_S, "bne.un.s", 0xFFFFFF33, POP_1_1 , PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greather
- * than the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bge_Un_S = new OpCode()
- opcode(Bge_Un_S, CEE_BGE_UN_S, "bge.un.s", 0xFFFFFF34, POP_1_1, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bgt_Un_S = new OpCode()
- opcode(Bgt_Un_S, CEE_BGT_UN_S, "bgt.un.s", 0xFFFFFF35, POP_1_1, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * or equal to the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Ble_Un_S = new OpCode()
- opcode(Ble_Un_S, CEE_BLE_UN_S , "ble.un.s", 0xFFFFFF36, POP_1_1, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Blt_Un_S = new OpCode()
- opcode(Blt_Un_S, CEE_BLT_UN_S, "blt.un.s", 0xFFFFFF37, POP_1_1, PUSH_NONE, INLINE_TARGET_S, FLOW_COND_BRANCH)
-
- /**
- * Unconditionally transfers control to a target instruction.
- */
- final val Br = new OpCode()
- opcode(Br, CEE_BR , "br" , 0xFFFFFF38, POP_NONE, PUSH_NONE, INLINE_TARGET, FLOW_BRANCH)
-
- /**
- * Transfers control to a target instruction if value is false, a null reference
- * (Nothing in Visual Basic), or zero.
- */
- final val Brfalse = new OpCode()
- opcode(Brfalse, CEE_BRFALSE, "brfalse", 0xFFFFFF39, POP_I, PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if value is true, not null, or non-zero.
- */
- final val Brtrue = new OpCode()
- opcode(Brtrue, CEE_BRTRUE , "brtrue", 0xFFFFFF3A, POP_I , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if two values are equal.
- */
- final val Beq = new OpCode()
- opcode(Beq, CEE_BEQ, "beq", 0xFFFFFF3B, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is greater than or
- * equal to the second value.
- */
- final val Bge = new OpCode()
- opcode(Bge, CEE_BGE, "bge", 0xFFFFFF3C, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is greater than the second value.
- */
- final val Bgt = new OpCode()
- opcode(Bgt, CEE_BGT, "bgt", 0xFFFFFF3D, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is less than or equal
- * to the second value.
- */
- final val Ble = new OpCode()
- opcode(Ble, CEE_BLE, "ble", 0xFFFFFF3E, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is less than the second value.
- */
- final val Blt = new OpCode()
- opcode(Blt, CEE_BLT, "blt", 0xFFFFFF3F, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction when two unsigned integer values or
- * unordered float values are not equal.
- */
- final val Bne_Un = new OpCode()
- opcode(Bne_Un, CEE_BNE_UN , "bne.un", 0xFFFFFF40, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is greather than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bge_Un = new OpCode()
- opcode(Bge_Un, CEE_BGE_UN , "bge.un", 0xFFFFFF41, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is greater than the
- * second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bgt_Un = new OpCode()
- opcode(Bgt_Un, CEE_BGT_UN , "bgt.un", 0xFFFFFF42, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is less than or equal to
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Ble_Un = new OpCode()
- opcode(Ble_Un, CEE_BLE_UN , "ble.un" , 0xFFFFFF43, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Transfers control to a target instruction if the first value is less than the second value,
- * when comparing unsigned integer values or unordered float values.
- */
- final val Blt_Un = new OpCode()
- opcode(Blt_Un, CEE_BLT_UN , "blt.un", 0xFFFFFF44, POP_1_1 , PUSH_NONE, INLINE_TARGET, FLOW_COND_BRANCH)
-
- /**
- * Implements a jump table.
- */
- final val Switch = new OpCode()
- opcode(Switch, CEE_SWITCH , "switch", 0xFFFFFF45, POP_I , PUSH_NONE, INLINE_SWITCH, FLOW_COND_BRANCH)
-
- /**
- * Loads a value of type int8 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I1 = new OpCode()
- opcode(Ldind_I1, CEE_LDIND_I1 , "ldind.i1" , 0xFFFFFF46, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type int16 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I2 = new OpCode()
- opcode(Ldind_I2, CEE_LDIND_I2 , "ldind.i2" , 0xFFFFFF48, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type int32 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I4 = new OpCode()
- opcode(Ldind_I4, CEE_LDIND_I4 , "ldind.i4" , 0xFFFFFF4A, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type int64 as an int64 onto the evaluation stack indirectly.
- */
- final val Ldind_I8 = new OpCode()
- opcode(Ldind_I8, CEE_LDIND_I8 , "ldind.i8" , 0xFFFFFF4C, POP_I , PUSH_I8 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type natural int as a natural int onto the evaluation stack indirectly.
- */
- final val Ldind_I = new OpCode()
- opcode(Ldind_I, CEE_LDIND_I , "ldind.i" , 0xFFFFFF4D, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type float32 as a type F (float) onto the evaluation stack indirectly.
- */
- final val Ldind_R4 = new OpCode()
- opcode(Ldind_R4, CEE_LDIND_R4 , "ldind.r4" , 0xFFFFFF4E, POP_I , PUSH_R4 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type float64 as a type F (float) onto the evaluation stack indirectly.
- */
- final val Ldind_R8 = new OpCode()
- opcode(Ldind_R8, CEE_LDIND_R8 , "ldind.r8" , 0xFFFFFF4F, POP_I , PUSH_R8 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads an object reference as a type O (object reference) onto the evaluation stack indirectly.
- */
- final val Ldind_Ref = new OpCode()
- opcode(Ldind_Ref, CEE_LDIND_REF, "ldind.ref", 0xFFFFFF50, POP_I , PUSH_REF, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type unsigned int8 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U1 = new OpCode()
- opcode(Ldind_U1, CEE_LDIND_U1 , "ldind.u1" , 0xFFFFFF47, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type unsigned int16 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U2 = new OpCode()
- opcode(Ldind_U2, CEE_LDIND_U2 , "ldind.u2" , 0xFFFFFF49, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Loads a value of type unsigned int32 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U4 = new OpCode()
- opcode(Ldind_U4, CEE_LDIND_U4 , "ldind.u4" , 0xFFFFFF4B, POP_I , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a object reference value at a supplied address.
- */
- final val Stind_Ref = new OpCode()
- opcode(Stind_Ref, CEE_STIND_REF, "stind.ref", 0xFFFFFF51, POP_I_I , PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type int8 at a supplied address.
- */
- final val Stind_I1 = new OpCode()
- opcode(Stind_I1, CEE_STIND_I1 , "stind.i1", 0xFFFFFF52, POP_I_I , PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type int16 at a supplied address.
- */
- final val Stind_I2 = new OpCode()
- opcode(Stind_I2, CEE_STIND_I2 , "stind.i2", 0xFFFFFF53, POP_I_I , PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type int32 at a supplied address.
- */
- final val Stind_I4 = new OpCode()
- opcode(Stind_I4, CEE_STIND_I4 , "stind.i4", 0xFFFFFF54, POP_I_I , PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type int64 at a supplied address.
- */
- final val Stind_I8 = new OpCode()
- opcode(Stind_I8, CEE_STIND_I8 , "stind.i8", 0xFFFFFF55, POP_I_I8, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type float32 at a supplied address.
- */
- final val Stind_R4 = new OpCode()
- opcode(Stind_R4, CEE_STIND_R4 , "stind.r4", 0xFFFFFF56, POP_I_R4, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Stores a value of type float64 at a supplied address.
- */
- final val Stind_R8 = new OpCode()
- opcode(Stind_R8, CEE_STIND_R8 , "stind.r8", 0xFFFFFF57, POP_I_R8, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Subtracts one value from another and pushes the result onto the evaluation stack.
- */
- final val Sub = new OpCode()
- opcode(Sub, CEE_SUB, "sub" , 0xFFFFFF59, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Multiplies two values and pushes the result on the evaluation stack.
- */
- final val Mul = new OpCode()
- opcode(Mul, CEE_MUL, "mul" , 0xFFFFFF5A, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Divides two values and pushes the result as a floating-point (type F) or
- * quotient (type int32) onto the evaluation stack.
- */
- final val Div = new OpCode()
- opcode(Div, CEE_DIV, "div" , 0xFFFFFF5B, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Divides two unsigned integer values and pushes the result (int32) onto the evaluation stack.
- */
- final val Div_Un = new OpCode()
- opcode(Div_Un, CEE_DIV_UN, "div.un" , 0xFFFFFF5C, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Divides two values and pushes the remainder onto the evaluation stack.
- */
- final val Rem = new OpCode()
- opcode(Rem, CEE_REM , "rem" , 0xFFFFFF5D, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Divides two unsigned values and pushes the remainder onto the evaluation stack.
- */
- final val Rem_Un = new OpCode()
- opcode(Rem_Un, CEE_REM_UN, "rem.un" , 0xFFFFFF5E, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Computes the bitwise AND of two values and pushes the result onto the evaluation stack.
- */
- final val And = new OpCode()
- opcode(And, CEE_AND, "and" , 0xFFFFFF5F, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compute the bitwise complement of the two integer values on top of the stack and
- * pushes the result onto the evaluation stack.
- */
- final val Or = new OpCode()
- opcode(Or, CEE_OR , "or" , 0xFFFFFF60, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Computes the bitwise XOR of the top two values on the evaluation stack,
- * pushing the result onto the evaluation stack.
- */
- final val Xor = new OpCode()
- opcode(Xor, CEE_XOR, "xor" , 0xFFFFFF61, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Shifts an integer value to the left (in zeroes) by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shl = new OpCode()
- opcode(Shl, CEE_SHL, "shl" , 0xFFFFFF62, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Shifts an integer value (in sign) to the right by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shr = new OpCode()
- opcode(Shr, CEE_SHR, "shr" , 0xFFFFFF63, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Shifts an unsigned integer value (in zeroes) to the right by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shr_Un = new OpCode()
- opcode(Shr_Un, CEE_SHR_UN, "shr.un" , 0xFFFFFF64, POP_1_1, PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Negates a value and pushes the result onto the evaluation stack.
- */
- final val Neg = new OpCode()
- opcode(Neg, CEE_NEG , "neg" , 0xFFFFFF65, POP_1 , PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Computes the bitwise complement of the integer value on top of the stack and pushes
- * the result onto the evaluation stack as the same type.
- */
- final val Not = new OpCode()
- opcode(Not, CEE_NOT , "not" , 0xFFFFFF66, POP_1 , PUSH_1 , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to int8, then extends (pads) it to int32.
- */
- final val Conv_I1 = new OpCode()
- opcode(Conv_I1, CEE_CONV_I1, "conv.i1", 0xFFFFFF67, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to int16, then extends (pads) it to int32.
- */
- final val Conv_I2 = new OpCode()
- opcode(Conv_I2, CEE_CONV_I2, "conv.i2", 0xFFFFFF68, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to int32.
- */
- final val Conv_I4 = new OpCode()
- opcode(Conv_I4, CEE_CONV_I4, "conv.i4", 0xFFFFFF69, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to int64.
- */
- final val Conv_I8 = new OpCode()
- opcode(Conv_I8, CEE_CONV_I8, "conv.i8", 0xFFFFFF6A, POP_1 , PUSH_I8, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to float32.
- */
- final val Conv_R4 = new OpCode()
- opcode(Conv_R4, CEE_CONV_R4, "conv.r4", 0xFFFFFF6B, POP_1 , PUSH_R4, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to float64.
- */
- final val Conv_R8 = new OpCode()
- opcode(Conv_R8, CEE_CONV_R8, "conv.r8", 0xFFFFFF6C, POP_1 , PUSH_R8, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int32, and extends it to int32.
- */
- final val Conv_U4 = new OpCode()
- opcode(Conv_U4, CEE_CONV_U4, "conv.u4", 0xFFFFFF6D, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int64, and extends it to int64.
- */
- final val Conv_U8 = new OpCode()
- opcode(Conv_U8, CEE_CONV_U8, "conv.u8", 0xFFFFFF6E, POP_1 , PUSH_I8, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Calls a late-bound method on an object, pushing the return value onto the evaluation stack.
- */
- final val Callvirt = new OpCode()
- opcode(Callvirt, CEE_CALLVIRT, "callvirt", 0xFFFFFF6F,POP_SPECIAL,PUSH_SPECIAL,INLINE_METHOD,FLOW_CALL)
-
- /**
- * Copies the value type located at the address of an object (type &, * or natural int)
- * to the address of the destination object (type &, * or natural int).
- */
- final val Cpobj = new OpCode()
- opcode(Cpobj, CEE_CPOBJ , "cpobj" , 0xFFFFFF70, POP_I_I , PUSH_NONE, INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Copies the value type object pointed to by an address to the top of the evaluation stack.
- */
- final val Ldobj = new OpCode()
- opcode(Ldobj, CEE_LDOBJ , "ldobj" , 0xFFFFFF71, POP_I , PUSH_1 , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Pushes a new object reference to a string literal stored in the metadata.
- */
- final val Ldstr = new OpCode()
- opcode(Ldstr, CEE_LDSTR , "ldstr" , 0xFFFFFF72, POP_NONE , PUSH_REF , INLINE_STRING, FLOW_NEXT)
-
- /**
- * Creates a new object or a new instance of a value type, pushing an object reference
- * (type O) onto the evaluation stack.
- */
- final val Newobj = new OpCode()
- opcode(Newobj, CEE_NEWOBJ, "newobj", 0xFFFFFF73, POP_SPECIAL , PUSH_REF , INLINE_METHOD, FLOW_CALL)
-
- /**
- * Attempts to cast an object passed by reference to the specified class.
- */
- final val Castclass = new OpCode()
- opcode(Castclass, CEE_CASTCLASS, "castclass", 0xFFFFFF74, POP_REF , PUSH_REF , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Tests whether an object reference (type O) is an instance of a particular class.
- */
- final val Isinst = new OpCode()
- opcode(Isinst, CEE_ISINST , "isinst" , 0xFFFFFF75, POP_REF , PUSH_I , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Converts the unsigned integer value on top of the evaluation stack to float32.
- */
- final val Conv_R_Un = new OpCode()
- opcode(Conv_R_Un, CEE_CONV_R_UN, "conv.r.un", 0xFFFFFF76, POP_1 , PUSH_R8 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the boxed representation of a value type to its unboxed form.
- */
- final val Unbox = new OpCode()
- opcode(Unbox, CEE_UNBOX , "unbox" , 0xFFFFFF79, POP_REF , PUSH_I , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Throws the exception object currently on the evaluation stack.
- */
- final val Throw = new OpCode()
- opcode(Throw, CEE_THROW , "throw" , 0xFFFFFF7A, POP_REF , PUSH_NONE, INLINE_NONE , FLOW_THROW)
-
- /**
- * Finds the value of a field in the object whose reference is currently
- * on the evaluation stack.
- */
- final val Ldfld = new OpCode()
- opcode(Ldfld, CEE_LDFLD , "ldfld" , 0xFFFFFF7B, POP_REF , PUSH_1 , INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Finds the address of a field in the object whose reference is currently
- * on the evaluation stack.
- */
- final val Ldflda = new OpCode()
- opcode(Ldflda, CEE_LDFLDA , "ldflda" , 0xFFFFFF7C, POP_REF , PUSH_I , INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Pushes the value of a static field onto the evaluation stack.
- */
- final val Ldsfld = new OpCode()
- opcode(Ldsfld, CEE_LDSFLD , "ldsfld" , 0xFFFFFF7E, POP_NONE , PUSH_1 , INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Pushes the address of a static field onto the evaluation stack.
- */
- final val Ldsflda = new OpCode()
- opcode(Ldsflda, CEE_LDSFLDA, "ldsflda", 0xFFFFFF7F, POP_NONE , PUSH_I , INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Replaces the value stored in the field of an object reference or pointer with a new value.
- */
- final val Stfld = new OpCode()
- opcode(Stfld, CEE_STFLD , "stfld" , 0xFFFFFF7D, POP_REF_1, PUSH_NONE, INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Replaces the value of a static field with a value from the evaluation stack.
- */
- final val Stsfld = new OpCode()
- opcode(Stsfld, CEE_STSFLD , "stsfld" , 0xFFFFFF80, POP_1 , PUSH_NONE, INLINE_FIELD , FLOW_NEXT)
-
- /**
- * Copies a value of a specified type from the evaluation stack into a supplied memory address.
- */
- final val Stobj = new OpCode()
- opcode(Stobj, CEE_STOBJ , "stobj" , 0xFFFFFF81, POP_I_1, PUSH_NONE, INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I1_Un = new OpCode()
- opcode(Conv_Ovf_I1_Un, CEE_CONV_OVF_I1_UN, "conv.ovf.i1.un", 0xFFFFFF82, POP_1,PUSH_I,INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I2_Un = new OpCode()
- opcode(Conv_Ovf_I2_Un, CEE_CONV_OVF_I2_UN, "conv.ovf.i2.un", 0xFFFFFF83,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I4_Un = new OpCode()
- opcode(Conv_Ovf_I4_Un, CEE_CONV_OVF_I4_UN, "conv.ovf.i4.un", 0xFFFFFF84,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I8_Un = new OpCode()
- opcode(Conv_Ovf_I8_Un, CEE_CONV_OVF_I8_UN, "conv.ovf.i8.un", 0xFFFFFF85,POP_1,PUSH_I8, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I_Un = new OpCode()
- opcode(Conv_Ovf_I_Un, CEE_CONV_OVF_I_UN , "conv.ovf.i.un" , 0xFFFFFF8A,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U1_Un = new OpCode()
- opcode(Conv_Ovf_U1_Un, CEE_CONV_OVF_U1_UN, "conv.ovf.u1.un", 0xFFFFFF86,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U2_Un = new OpCode()
- opcode(Conv_Ovf_U2_Un, CEE_CONV_OVF_U2_UN, "conv.ovf.u2.un", 0xFFFFFF87,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U4_Un = new OpCode()
- opcode(Conv_Ovf_U4_Un, CEE_CONV_OVF_U4_UN, "conv.ovf.u4.un", 0xFFFFFF88,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U8_Un = new OpCode()
- opcode(Conv_Ovf_U8_Un, CEE_CONV_OVF_U8_UN, "conv.ovf.u8.un", 0xFFFFFF89,POP_1,PUSH_I8, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U_Un = new OpCode()
- opcode(Conv_Ovf_U_Un, CEE_CONV_OVF_U_UN , "conv.ovf.u.un" , 0xFFFFFF8B,POP_1,PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts a value type to an object reference (type O).
- */
- final val Box = new OpCode()
- opcode(Box, CEE_BOX , "box" , 0xFFFFFF8C, POP_1 , PUSH_REF , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Pushes an object reference to a new zero-based, one-dimensional array whose elements
- * are of a specific type onto the evaluation stack.
- */
- final val Newarr = new OpCode()
- opcode(Newarr, CEE_NEWARR, "newarr" , 0xFFFFFF8D, POP_I , PUSH_REF , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Pushes the number of elements of a zero-based, one-dimensional array
- * onto the evaluation stack.
- */
- final val Ldlen = new OpCode()
- opcode(Ldlen, CEE_LDLEN, "ldlen", 0xFFFFFF8E, POP_REF, PUSH_I,INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the address of the array element at a specified array index onto
- * the top of the evaluation stack as type & (managed pointer).
- */
- final val Ldelema = new OpCode()
- opcode(Ldelema, CEE_LDELEMA, "ldelema" , 0xFFFFFF8F, POP_REF_I, PUSH_I, INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Loads the element with type natural int at a specified array index onto the top
- * of the evaluation stack as a natural int.
- */
- final val Ldelem_I = new OpCode()
- opcode(Ldelem_I, CEE_LDELEM_I, "ldelem.i" , 0xFFFFFF97, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type int8 at a specified array index onto the top of the
- * evaluation stack as an int32.
- */
- final val Ldelem_I1 = new OpCode()
- opcode(Ldelem_I1, CEE_LDELEM_I1, "ldelem.i1" , 0xFFFFFF90, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type int16 at a specified array index onto the top of
- * the evaluation stack as an int32.
- */
- final val Ldelem_I2 = new OpCode()
- opcode(Ldelem_I2, CEE_LDELEM_I2, "ldelem.i2" , 0xFFFFFF92, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type int32 at a specified array index onto the top of the
- * evaluation stack as an int32.
- */
- final val Ldelem_I4 = new OpCode()
- opcode(Ldelem_I4, CEE_LDELEM_I4, "ldelem.i4" , 0xFFFFFF94, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type int64 at a specified array index onto the top of the
- * evaluation stack as an int64.
- */
- final val Ldelem_I8 = new OpCode()
- opcode(Ldelem_I8, CEE_LDELEM_I8, "ldelem.i8" , 0xFFFFFF96, POP_REF_I, PUSH_I8, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type float32 at a specified array index onto the top of the
- * evaluation stack as type F (float)
- */
- final val Ldelem_R4 = new OpCode()
- opcode(Ldelem_R4, CEE_LDELEM_R4, "ldelem.r4" , 0xFFFFFF98, POP_REF_I, PUSH_R4, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type float64 at a specified array index onto the top of the
- * evaluation stack as type F (float) .
- */
- final val Ldelem_R8 = new OpCode()
- opcode(Ldelem_R8, CEE_LDELEM_R8, "ldelem.r8" , 0xFFFFFF99, POP_REF_I, PUSH_R8, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element containing an object reference at a specified array index onto
- * the top of the evaluation stack as type O (object reference).
- */
- final val Ldelem_Ref = new OpCode()
- opcode(Ldelem_Ref, CEE_LDELEM_REF, "ldelem.ref", 0xFFFFFF9A, POP_REF_I, PUSH_REF, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type unsigned int8 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U1 = new OpCode()
- opcode(Ldelem_U1, CEE_LDELEM_U1, "ldelem.u1" , 0xFFFFFF91, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type unsigned int16 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U2 = new OpCode()
- opcode(Ldelem_U2, CEE_LDELEM_U2, "ldelem.u2" , 0xFFFFFF93, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Loads the element with type unsigned int32 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U4 = new OpCode()
- opcode(Ldelem_U4, CEE_LDELEM_U4, "ldelem.u4" , 0xFFFFFF95, POP_REF_I, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the natural int value on
- * the evaluation stack.
- */
- final val Stelem_I = new OpCode()
- opcode(Stelem_I, CEE_STELEM_I, "stelem.i", 0xFFFFFF9B, POP_REF_I_I, PUSH_NONE, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the int8 value on the evaluation stack.
- */
- final val Stelem_I1 = new OpCode()
- opcode(Stelem_I1, CEE_STELEM_I1, "stelem.i1", 0xFFFFFF9C, POP_REF_I_I, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the int16 value on the evaluation stack.
- */
- final val Stelem_I2 = new OpCode()
- opcode(Stelem_I2, CEE_STELEM_I2, "stelem.i2", 0xFFFFFF9D, POP_REF_I_I, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the int32 value on the evaluation stack.
- */
- final val Stelem_I4 = new OpCode()
- opcode(Stelem_I4, CEE_STELEM_I4, "stelem.i4", 0xFFFFFF9E, POP_REF_I_I, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the int64 value on the evaluation stack.
- */
- final val Stelem_I8 = new OpCode()
- opcode(Stelem_I8, CEE_STELEM_I8,"stelem.i8", 0xFFFFFF9F, POP_REF_I_I8, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the float32 value on the evaluation stack.
- */
- final val Stelem_R4 = new OpCode()
- opcode(Stelem_R4, CEE_STELEM_R4,"stelem.r4", 0xFFFFFFA0, POP_REF_I_R4, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the float64 value on the evaluation stack.
- */
- final val Stelem_R8 = new OpCode()
- opcode(Stelem_R8, CEE_STELEM_R8,"stelem.r8", 0xFFFFFFA1, POP_REF_I_R8, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Replaces the array element at a given index with the object ref value (type O)
- * on the evaluation stack.
- */
- final val Stelem_Ref = new OpCode()
- opcode(Stelem_Ref, CEE_STELEM_REF,"stelem.ref",0xFFFFFFA2,POP_REF_I_REF,PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I1 = new OpCode()
- opcode(Conv_Ovf_I1, CEE_CONV_OVF_I1, "conv.ovf.i1", 0xFFFFFFB3, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int16 and
- * extending it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I2 = new OpCode()
- opcode(Conv_Ovf_I2, CEE_CONV_OVF_I2, "conv.ovf.i2", 0xFFFFFFB5, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I4 = new OpCode()
- opcode(Conv_Ovf_I4, CEE_CONV_OVF_I4, "conv.ovf.i4", 0xFFFFFFB7, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I8 = new OpCode()
- opcode(Conv_Ovf_I8, CEE_CONV_OVF_I8, "conv.ovf.i8", 0xFFFFFFB9, POP_1, PUSH_I8, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U1 = new OpCode()
- opcode(Conv_Ovf_U1, CEE_CONV_OVF_U1, "conv.ovf.u1", 0xFFFFFFB4, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U2 = new OpCode()
- opcode(Conv_Ovf_U2, CEE_CONV_OVF_U2, "conv.ovf.u2", 0xFFFFFFB6, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U4 = new OpCode()
- opcode(Conv_Ovf_U4, CEE_CONV_OVF_U4, "conv.ovf.u4", 0xFFFFFFB8, POP_1, PUSH_I , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U8 = new OpCode()
- opcode(Conv_Ovf_U8, CEE_CONV_OVF_U8, "conv.ovf.u8", 0xFFFFFFBA, POP_1, PUSH_I8, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Retrieves the address (type &) embedded in a typed reference.
- */
- final val Refanyval = new OpCode()
- opcode(Refanyval, CEE_REFANYVAL, "refanyval", 0xFFFFFFC2, POP_1, PUSH_I , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Retrieves the type token embedded in a typed reference .
- */
- final val Refanytype = new OpCode()
- opcode(Refanytype, CEE_REFANYTYPE, "refanytype", 0xFFFFFE1D, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Throws ArithmeticException if value is not a finite number.
- */
- final val Ckfinite = new OpCode()
- opcode(Ckfinite, CEE_CKFINITE, "ckfinite" , 0xFFFFFFC3, POP_1, PUSH_R8 , INLINE_NONE , FLOW_NEXT)
-
- /**
- * Pushes a typed reference to an instance of a specific type onto the evaluation stack.
- */
- final val Mkrefany = new OpCode()
- opcode(Mkrefany, CEE_MKREFANY, "mkrefany" , 0xFFFFFFC6, POP_I, PUSH_1 , INLINE_TYPE , FLOW_NEXT)
-
- /**
- * Converts a metadata token to its runtime representation, pushing it onto the evaluation stack.
- */
- final val Ldtoken = new OpCode()
- opcode(Ldtoken, CEE_LDTOKEN , "ldtoken" , 0xFFFFFFD0, POP_NONE, PUSH_I, INLINE_TOKEN , FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int8, and extends it to int32.
- */
- final val Conv_U1 = new OpCode()
- opcode(Conv_U1, CEE_CONV_U1 , "conv.u1" , 0xFFFFFFD2, POP_1, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int16, and extends it to int32.
- */
- final val Conv_U2 = new OpCode()
- opcode(Conv_U2, CEE_CONV_U2 , "conv.u2" , 0xFFFFFFD1, POP_1, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to natural int.
- */
- final val Conv_I = new OpCode()
- opcode(Conv_I, CEE_CONV_I , "conv.i" , 0xFFFFFFD3, POP_1, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to signed natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I = new OpCode()
- opcode(Conv_Ovf_I, CEE_CONV_OVF_I , "conv.ovf.i", 0xFFFFFFD4, POP_1, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U = new OpCode()
- opcode(Conv_Ovf_U, CEE_CONV_OVF_U , "conv.ovf.u", 0xFFFFFFD5, POP_1, PUSH_I, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Adds two integers, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Add_Ovf = new OpCode()
- opcode(Add_Ovf, CEE_ADD_OVF , "add.ovf" , 0xFFFFFFD6, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Adds two unsigned integer values, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Add_Ovf_Un = new OpCode()
- opcode(Add_Ovf_Un, CEE_ADD_OVF_UN , "add.ovf.un", 0xFFFFFFD7, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Multiplies two integer values, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Mul_Ovf = new OpCode()
- opcode(Mul_Ovf, CEE_MUL_OVF , "mul.ovf" , 0xFFFFFFD8, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Multiplies two unsigned integer values , performs an overflow check ,
- * and pushes the result onto the evaluation stack.
- */
- final val Mul_Ovf_Un = new OpCode()
- opcode(Mul_Ovf_Un, CEE_MUL_OVF_UN , "mul.ovf.un", 0xFFFFFFD9, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Subtracts one integer value from another, performs an overflow check,
- * and pushes the result onto the evaluation stack.
- */
- final val Sub_Ovf = new OpCode()
- opcode(Sub_Ovf, CEE_SUB_OVF , "sub.ovf" , 0xFFFFFFDA, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Subtracts one unsigned integer value from another, performs an overflow check,
- * and pushes the result onto the evaluation stack.
- */
- final val Sub_Ovf_Un = new OpCode()
- opcode(Sub_Ovf_Un, CEE_SUB_OVF_UN, "sub.ovf.un", 0xFFFFFFDB, POP_1_1, PUSH_1, INLINE_NONE , FLOW_NEXT)
-
- /**
- * Transfers control from the fault or finally clause of an exception block back to
- * the Common Language Infrastructure (CLI) exception handler.
- */
- final val Endfinally = new OpCode()
- opcode(Endfinally, CEE_ENDFINALLY, "endfinally", 0xFFFFFFDC, POP_NONE, PUSH_NONE, INLINE_NONE, FLOW_RETURN)
-
- /**
- * Exits a protected region of code, unconditionally tranferring control
- * to a specific target instruction.
- */
- final val Leave = new OpCode()
- opcode(Leave, CEE_LEAVE, "leave", 0xFFFFFFDD, POP_NONE, PUSH_NONE, INLINE_TARGET, FLOW_BRANCH)
-
- /**
- * Exits a protected region of code, unconditionally tranferring control
- * to a target instruction (short form).
- */
- final val Leave_S = new OpCode()
- opcode(Leave_S, CEE_LEAVE_S, "leave.s", 0xFFFFFFDE, POP_NONE, PUSH_NONE, INLINE_TARGET_S, FLOW_BRANCH)
-
- /**
- * Stores a value of type natural int at a supplied address.
- */
- final val Stind_I = new OpCode()
- opcode(Stind_I, CEE_STIND_I, "stind.i", 0xFFFFFFDF, POP_I_I , PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Converts the value on top of the evaluation stack to unsigned natural int,
- * and extends it to natural int.
- */
- final val Conv_U = new OpCode()
- opcode(Conv_U, CEE_CONV_U, "conv.u", 0xFFFFFFE0, POP_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Returns an unmanaged pointer to the argument list of the current method.
- */
- final val Arglist = new OpCode()
- opcode(Arglist, CEE_ARGLIST, "arglist" , 0xFFFFFE00, POP_NONE, PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compares two values. If they are equal, the integer value 1 (int32) is pushed
- * onto the evaluation stack otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Ceq = new OpCode()
- opcode(Ceq, CEE_CEQ, "ceq", 0xFFFFFE01, POP_1_1 , PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compares two values. If the first value is greater than the second,
- * the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Cgt = new OpCode()
- opcode(Cgt, CEE_CGT, "cgt", 0xFFFFFE02, POP_1_1 , PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compares two unsigned or unordered values. If the first value is greater than
- * the second, the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Cgt_Un = new OpCode()
- opcode(Cgt_Un, CEE_CGT_UN, "cgt.un", 0xFFFFFE03, POP_1_1 , PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compares two values. If the first value is less than the second,
- * the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Clt = new OpCode()
- opcode(Clt, CEE_CLT, "clt" , 0xFFFFFE04, POP_1_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Compares the unsigned or unordered values value1 and value2. If value1 is
- * less than value2, then the integer value 1 (int32) is pushed onto the
- * evaluation stack otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Clt_Un = new OpCode()
- opcode(Clt_Un, CEE_CLT_UN , "clt.un" , 0xFFFFFE05, POP_1_1 , PUSH_I , INLINE_NONE, FLOW_NEXT)
-
- /**
- * Pushes an unmanaged pointer (type natural int) to the native code implementing
- * a specific method onto the evaluation stack.
- */
- final val Ldftn = new OpCode()
- opcode(Ldftn, CEE_LDFTN , "ldftn" , 0xFFFFFE06, POP_NONE, PUSH_I , INLINE_METHOD, FLOW_NEXT)
-
- /**
- * Pushes an unmanaged pointer (type natural int) to the native code implementing
- * a particular virtual method associated with a specified object onto the evaluation stack.
- */
- final val Ldvirtftn = new OpCode()
- opcode(Ldvirtftn, CEE_LDVIRTFTN, "ldvirtftn", 0xFFFFFE07, POP_REF , PUSH_I , INLINE_METHOD, FLOW_NEXT)
-
- /**
- * Loads an argument (referenced by a specified index value) onto the stack.
- */
- final val Ldarg = new OpCode()
- opcode(Ldarg, CEE_LDARG , "ldarg" , 0xFFFFFE09, POP_NONE, PUSH_1 , INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Load an argument address onto the evaluation stack.
- */
- final val Ldarga = new OpCode()
- opcode(Ldarga, CEE_LDARGA , "ldarga", 0xFFFFFE0A, POP_NONE, PUSH_I, INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Loads the local variable at a specific index onto the evaluation stack.
- */
- final val Ldloc = new OpCode()
- opcode(Ldloc, CEE_LDLOC, "ldloc", 0xFFFFFE0C, POP_NONE, PUSH_1 , INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Loads the address of the local variable at a specific index onto the evaluation stack.
- */
- final val Ldloca = new OpCode()
- opcode(Ldloca, CEE_LDLOCA, "ldloca", 0xFFFFFE0D, POP_NONE, PUSH_I, INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Stores the value on top of the evaluation stack in the argument slot at a specified index.
- */
- final val Starg = new OpCode()
- opcode(Starg, CEE_STARG, "starg", 0xFFFFFE0B, POP_1 , PUSH_NONE, INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Pops the current value from the top of the evaluation stack and stores it in a
- * the local variable list at a specified index.
- */
- final val Stloc = new OpCode()
- opcode(Stloc, CEE_STLOC, "stloc", 0xFFFFFE0E, POP_1 , PUSH_NONE, INLINE_VARIABLE , FLOW_NEXT)
-
- /**
- * Allocates a certain number of bytes from the local dynamic memory pool and pushes the
- * address (a transient pointer, type *) of the first allocated Byte onto the evaluation stack.
- */
- final val Localloc = new OpCode()
- opcode(Localloc, CEE_LOCALLOC, "localloc" , 0xFFFFFE0F, POP_I, PUSH_I, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Transfers control from the filter clause of an exception back to the
- * Common Language Infrastructure (CLI) exception handler.
- */
- final val Endfilter = new OpCode()
- opcode(Endfilter, CEE_ENDFILTER, "endfilter" , 0xFFFFFE11, POP_I , PUSH_NONE, INLINE_NONE, FLOW_RETURN)
-
- /**
- * Indicates that an address currently atop the evaluation stack might not be aligned
- * to the natural size of the immediately following ldind, stind, ldfld, stfld, ldobj,
- * stobj, initblk, or cpblk instruction.
- */
- final val Unaligned = new OpCode()
- opcode(Unaligned, CEE_UNALIGNED, "unaligned.", 0xFFFFFE12, POP_NONE, PUSH_NONE, INLINE_I_S , FLOW_META)
-
- /**
- * Specifies that an address currently atop the evaluation stack might be volatile,
- * and the results of reading that location cannot be cached or that multiple stores
- * to that location cannot be suppressed.
- */
- final val Volatile = new OpCode()
- opcode(Volatile, CEE_VOLATILE, "volatile." , 0xFFFFFE13, POP_NONE, PUSH_NONE, INLINE_NONE, FLOW_META)
-
- /**
- * Performs a postfixed method call instruction such that the current method's stack
- * frame is removed before the actual call instruction is executed.
- */
- final val Tailcall = new OpCode()
- opcode(Tailcall, CEE_TAILCALL, "tail." , 0xFFFFFE14, POP_NONE, PUSH_NONE, INLINE_NONE, FLOW_META)
-
- /**
- * Initializes all the fields of the object at a specific address to a null reference
- * or a 0 of the appropriate primitive type.
- */
- final val Initobj = new OpCode()
- opcode(Initobj, CEE_INITOBJ , "initobj" , 0xFFFFFE15, POP_I , PUSH_NONE, INLINE_TYPE, FLOW_NEXT)
-
- /**
- * Copies a specified number bytes from a source address to a destination address .
- */
- final val Cpblk = new OpCode()
- opcode(Cpblk, CEE_CPBLK , "cpblk" , 0xFFFFFE17, POP_I_I_I, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Initializes a specified block of memory at a specific address to a given size
- * and initial value.
- */
- final val Initblk = new OpCode()
- opcode(Initblk, CEE_INITBLK , "initblk" , 0xFFFFFE18, POP_I_I_I, PUSH_NONE, INLINE_NONE, FLOW_NEXT)
-
- /**
- * Rethrows the current exception.
- */
- final val Rethrow = new OpCode()
- opcode(Rethrow, CEE_RETHROW , "rethrow", 0xFFFFFE1A, POP_NONE , PUSH_NONE, INLINE_NONE, FLOW_THROW)
-
- /**
- * Pushes the size, in bytes, of a supplied value type onto the evaluation stack.
- */
- final val Sizeof = new OpCode()
- opcode(Sizeof, CEE_SIZEOF, "sizeof", 0xFFFFFE1C, POP_NONE , PUSH_I , INLINE_TYPE, FLOW_NEXT)
-
-
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCodes.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCodes.scala
deleted file mode 100644
index 80e4267436..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/OpCodes.scala
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-
-/**
- * Provides field representations of the Microsoft Intermediate Language (MSIL)
- * instructions for emission by the ILGenerator class members (such as Emit).
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-object OpCodes {
-
- //##########################################################################
-
- /**
- * Adds two values and pushes the result onto the evaluation stack.
- */
- final val Add = OpCode.Add
-
- /**
- * Fills space if bytecodes are patched. No meaningful operation is performed
- * although a processing cycle can be consumed.
- */
- final val Nop = OpCode.Nop
-
- /**
- * Signals the Common Language Infrastructure (CLI) to inform the debugger that
- * a break point has been tripped.
- */
- final val Break = OpCode.Break
-
- /**
- * Loads the argument at index 0 onto the evaluation stack.
- */
- final val Ldarg_0 = OpCode.Ldarg_0
-
- /**
- * Loads the argument at index 1 onto the evaluation stack.
- */
- final val Ldarg_1 = OpCode.Ldarg_1
-
- /**
- * Loads the argument at index 2 onto the evaluation stack.
- */
- final val Ldarg_2 = OpCode.Ldarg_2
-
- /**
- * Loads the argument at index 3 onto the evaluation stack.
- */
- final val Ldarg_3 = OpCode.Ldarg_3
-
- /**
- * Loads the local variable at index 0 onto the evaluation stack.
- */
- final val Ldloc_0 = OpCode.Ldloc_0
-
- /**
- * Loads the local variable at index 1 onto the evaluation stack.
- */
- final val Ldloc_1 = OpCode.Ldloc_1
-
- /**
- * Loads the local variable at index 2 onto the evaluation stack.
- */
- final val Ldloc_2 = OpCode.Ldloc_2
-
- /**
- * Loads the local variable at index 3 onto the evaluation stack.
- */
- final val Ldloc_3 = OpCode.Ldloc_3
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 0.
- */
- final val Stloc_0 = OpCode.Stloc_0
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 1.
- */
- final val Stloc_1 = OpCode.Stloc_1
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 2.
- */
- final val Stloc_2 = OpCode.Stloc_2
-
- /**
- * Pops the current value from the top of the evaluation stack and
- * stores it in a the local variable list at index 3.
- */
- final val Stloc_3 = OpCode.Stloc_3
-
- /**
- * Loads the argument (referenced by a specified short form index)
- * onto the evaluation stack.
- */
- final val Ldarg_S = OpCode.Ldarg_S
-
- /**
- * Load an argument address, in short form, onto the evaluation stack.
- */
- final val Ldarga_S = OpCode.Ldarga_S
-
- /**
- * Loads the local variable at a specific index onto the evaluation stack,
- * short form.
- */
- final val Ldloc_S = OpCode.Ldloc_S
-
- /**
- * Loads the address of the local variable at a specific index onto
- * the evaluation stack, short form.
- */
- final val Ldloca_S = OpCode.Ldloca_S
-
- /**
- * Stores the value on top of the evaluation stack in the argument slot
- * at a specified index, short form.
- */
- final val Starg_S = OpCode.Starg_S
-
- /**
- * Pops the current value from the top of the evaluation stack and stores it
- * in a the local variable list at index (short form).
- */
- final val Stloc_S = OpCode.Stloc_S
-
- /**
- * Pushes a null reference (type O) onto the evaluation stack.
- */
- final val Ldnull = OpCode.Ldnull
-
- /**
- * Pushes the integer value of -1 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_M1 = OpCode.Ldc_I4_M1
-
- /**
- * Pushes the integer value of 0 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_0 = OpCode.Ldc_I4_0
-
- /**
- * Pushes the integer value of 1 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_1 = OpCode.Ldc_I4_1
-
- /**
- * Pushes the integer value of 2 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_2 = OpCode.Ldc_I4_2
-
- /**
- * Pushes the integer value of 3 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_3 = OpCode.Ldc_I4_3
-
- /**
- * Pushes the integer value of 4 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_4 = OpCode.Ldc_I4_4
-
- /**
- * Pushes the integer value of 5 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_5 = OpCode.Ldc_I4_5
-
- /**
- * Pushes the integer value of 6 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_6 = OpCode.Ldc_I4_6
-
- /**
- * Pushes the integer value of 7 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_7 = OpCode.Ldc_I4_7
-
- /**
- * Pushes the integer value of 8 onto the evaluation stack as an int32.
- */
- final val Ldc_I4_8 = OpCode.Ldc_I4_8
-
- /**
- * Pushes the supplied int8 value onto the evaluation stack as an int32, short form.
- */
- final val Ldc_I4_S = OpCode.Ldc_I4_S
-
- /**
- * Pushes a supplied value of type int32 onto the evaluation stack as an int32.
- */
- final val Ldc_I4 = OpCode.Ldc_I4
-
- /**
- * Pushes a supplied value of type int64 onto the evaluation stack as an int64.
- */
- final val Ldc_I8 = OpCode.Ldc_I8
-
- /**
- * Pushes a supplied value of type float32 onto the evaluation stack as type F (float).
- */
- final val Ldc_R4 = OpCode.Ldc_R4
-
- /**
- * Pushes a supplied value of type float64 onto the evaluation stack as type F (float).
- */
- final val Ldc_R8 = OpCode.Ldc_R8
-
- /**
- * Copies the current topmost value on the evaluation stack, and then pushes the copy
- * onto the evaluation stack.
- */
- final val Dup = OpCode.Dup
-
- /**
- * Removes the value currently on top of the evaluation stack.
- */
- final val Pop = OpCode.Pop
-
- /**
- * Exits current method and jumps to specified method.
- */
- final val Jmp = OpCode.Jmp
-
- /**
- * Calls the method indicated by the passed method descriptor.
- */
- final val Call = OpCode.Call
-
- /**
- * constrained. prefix
- */
- final val Constrained = OpCode.Constrained
-
- /**
- * readonly. prefix
- */
- final val Readonly = OpCode.Readonly
-
- /**
- * Calls the method indicated on the evaluation stack (as a pointer to an entry point)
- * with arguments described by a calling convention.
- */
- final val Calli = OpCode.Calli
-
- /**
- * Returns from the current method, pushing a return value (if present) from the caller's
- * evaluation stack onto the callee's evaluation stack.
- */
- final val Ret = OpCode.Ret
-
- /**
- * Unconditionally transfers control to a target instruction (short form).
- */
- final val Br_S = OpCode.Br_S
-
- /**
- * Transfers control to a target instruction if value is false, a null reference, or zero.
- */
- final val Brfalse_S = OpCode.Brfalse_S
-
- /**
- * Transfers control to a target instruction (short form) if value is true, not null, or non-zero.
- */
- final val Brtrue_S = OpCode.Brtrue_S
-
- /**
- * Transfers control to a target instruction (short form) if two values are equal.
- */
- final val Beq_S = OpCode.Beq_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * or equal to the second value.
- */
- final val Bge_S = OpCode.Bge_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * the second value.
- */
- final val Bgt_S = OpCode.Bgt_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * or equal to the second value.
- */
- final val Ble_S = OpCode.Ble_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * the second value.
- */
- final val Blt_S = OpCode.Blt_S
-
- /**
- * Transfers control to a target instruction (short form) when two unsigned integer values
- * or unordered float values are not equal.
- */
- final val Bne_Un_S = OpCode.Bne_Un_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greather
- * than the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bge_Un_S = OpCode.Bge_Un_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is greater than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bgt_Un_S = OpCode.Bgt_Un_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * or equal to the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Ble_Un_S = OpCode.Ble_Un_S
-
- /**
- * Transfers control to a target instruction (short form) if the first value is less than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Blt_Un_S = OpCode.Blt_Un_S
-
- /**
- * Unconditionally transfers control to a target instruction.
- */
- final val Br = OpCode.Br
-
- /**
- * Transfers control to a target instruction if value is false, a null reference
- * (Nothing in Visual Basic), or zero.
- */
- final val Brfalse = OpCode.Brfalse
-
- /**
- * Transfers control to a target instruction if value is true, not null, or non-zero.
- */
- final val Brtrue = OpCode.Brtrue
-
- /**
- * Transfers control to a target instruction if two values are equal.
- */
- final val Beq = OpCode.Beq
-
- /**
- * Transfers control to a target instruction if the first value is greater than or
- * equal to the second value.
- */
- final val Bge = OpCode.Bge
-
- /**
- * Transfers control to a target instruction if the first value is greater than the second value.
- */
- final val Bgt = OpCode.Bgt
-
- /**
- * Transfers control to a target instruction if the first value is less than or equal
- * to the second value.
- */
- final val Ble = OpCode.Ble
-
- /**
- * Transfers control to a target instruction if the first value is less than the second value.
- */
- final val Blt = OpCode.Blt
-
- /**
- * Transfers control to a target instruction when two unsigned integer values or
- * unordered float values are not equal.
- */
- final val Bne_Un = OpCode.Bne_Un
-
- /**
- * Transfers control to a target instruction if the first value is greather than
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bge_Un = OpCode.Bge_Un
-
- /**
- * Transfers control to a target instruction if the first value is greater than the
- * second value, when comparing unsigned integer values or unordered float values.
- */
- final val Bgt_Un = OpCode.Bgt_Un
-
- /**
- * Transfers control to a target instruction if the first value is less than or equal to
- * the second value, when comparing unsigned integer values or unordered float values.
- */
- final val Ble_Un = OpCode.Ble_Un
-
- /**
- * Transfers control to a target instruction if the first value is less than the second value,
- * when comparing unsigned integer values or unordered float values.
- */
- final val Blt_Un = OpCode.Blt_Un
-
- /**
- * Implements a jump table.
- */
- final val Switch = OpCode.Switch
-
- /**
- * Loads a value of type int8 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I1 = OpCode.Ldind_I1
-
- /**
- * Loads a value of type int16 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I2 = OpCode.Ldind_I2
-
- /**
- * Loads a value of type int32 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_I4 = OpCode.Ldind_I4
-
- /**
- * Loads a value of type int64 as an int64 onto the evaluation stack indirectly.
- */
- final val Ldind_I8 = OpCode.Ldind_I8
-
- /**
- * Loads a value of type natural int as a natural int onto the evaluation stack indirectly.
- */
- final val Ldind_I = OpCode.Ldind_I
-
- /**
- * Loads a value of type float32 as a type F (float) onto the evaluation stack indirectly.
- */
- final val Ldind_R4 = OpCode.Ldind_R4
-
- /**
- * Loads a value of type float64 as a type F (float) onto the evaluation stack indirectly.
- */
- final val Ldind_R8 = OpCode.Ldind_R8
-
- /**
- * Loads an object reference as a type O (object reference) onto the evaluation stack indirectly.
- */
- final val Ldind_Ref = OpCode.Ldind_Ref
-
- /**
- * Loads a value of type unsigned int8 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U1 = OpCode.Ldind_U1
-
- /**
- * Loads a value of type unsigned int16 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U2 = OpCode.Ldind_U2
-
- /**
- * Loads a value of type unsigned int32 as an int32 onto the evaluation stack indirectly.
- */
- final val Ldind_U4 = OpCode.Ldind_U4
-
- /**
- * Stores a object reference value at a supplied address.
- */
- final val Stind_Ref = OpCode.Stind_Ref
-
- /**
- * Stores a value of type int8 at a supplied address.
- */
- final val Stind_I1 = OpCode.Stind_I1
-
- /**
- * Stores a value of type int16 at a supplied address.
- */
- final val Stind_I2 = OpCode.Stind_I2
-
- /**
- * Stores a value of type int32 at a supplied address.
- */
- final val Stind_I4 = OpCode.Stind_I4
-
- /**
- * Stores a value of type int64 at a supplied address.
- */
- final val Stind_I8 = OpCode.Stind_I8
-
- /**
- * Stores a value of type float32 at a supplied address.
- */
- final val Stind_R4 = OpCode.Stind_R4
-
- /**
- * Stores a value of type float64 at a supplied address.
- */
- final val Stind_R8 = OpCode.Stind_R8
-
- /**
- * Subtracts one value from another and pushes the result onto the evaluation stack.
- */
- final val Sub = OpCode.Sub
-
- /**
- * Multiplies two values and pushes the result on the evaluation stack.
- */
- final val Mul = OpCode.Mul
-
- /**
- * Divides two values and pushes the result as a floating-point (type F) or
- * quotient (type int32) onto the evaluation stack.
- */
- final val Div = OpCode.Div
-
- /**
- * Divides two unsigned integer values and pushes the result (int32) onto the evaluation stack.
- */
- final val Div_Un = OpCode.Div_Un
-
- /**
- * Divides two values and pushes the remainder onto the evaluation stack.
- */
- final val Rem = OpCode.Rem
-
- /**
- * Divides two unsigned values and pushes the remainder onto the evaluation stack.
- */
- final val Rem_Un = OpCode.Rem_Un
-
- /**
- * Computes the bitwise AND of two values and pushes the result onto the evaluation stack.
- */
- final val And = OpCode.And
-
- /**
- * Compute the bitwise complement of the two integer values on top of the stack and
- * pushes the result onto the evaluation stack.
- */
- final val Or = OpCode.Or
-
- /**
- * Computes the bitwise XOR of the top two values on the evaluation stack,
- * pushing the result onto the evaluation stack.
- */
- final val Xor = OpCode.Xor
-
- /**
- * Shifts an integer value to the left (in zeroes) by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shl = OpCode.Shl
-
- /**
- * Shifts an integer value (in sign) to the right by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shr = OpCode.Shr
-
- /**
- * Shifts an unsigned integer value (in zeroes) to the right by a specified number of bits,
- * pushing the result onto the evaluation stack.
- */
- final val Shr_Un = OpCode.Shr_Un
-
- /**
- * Negates a value and pushes the result onto the evaluation stack.
- */
- final val Neg = OpCode.Neg
-
- /**
- * Computes the bitwise complement of the integer value on top of the stack and pushes
- * the result onto the evaluation stack as the same type.
- */
- final val Not = OpCode.Not
-
- /**
- * Converts the value on top of the evaluation stack to int8, then extends (pads) it to int32.
- */
- final val Conv_I1 = OpCode.Conv_I1
-
- /**
- * Converts the value on top of the evaluation stack to int16, then extends (pads) it to int32.
- */
- final val Conv_I2 = OpCode.Conv_I2
-
- /**
- * Converts the value on top of the evaluation stack to int32.
- */
- final val Conv_I4 = OpCode.Conv_I4
-
- /**
- * Converts the value on top of the evaluation stack to int64.
- */
- final val Conv_I8 = OpCode.Conv_I8
-
- /**
- * Converts the value on top of the evaluation stack to float32.
- */
- final val Conv_R4 = OpCode.Conv_R4
-
- /**
- * Converts the value on top of the evaluation stack to float64.
- */
- final val Conv_R8 = OpCode.Conv_R8
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int32, and extends it to int32.
- */
- final val Conv_U4 = OpCode.Conv_U4
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int64, and extends it to int64.
- */
- final val Conv_U8 = OpCode.Conv_U8
-
- /**
- * Calls a late-bound method on an object, pushing the return value onto the evaluation stack.
- */
- final val Callvirt = OpCode.Callvirt
-
- /**
- * Copies the value type located at the address of an object (type &, * or natural int)
- * to the address of the destination object (type &, * or natural int).
- */
- final val Cpobj = OpCode.Cpobj
-
- /**
- * Copies the value type object pointed to by an address to the top of the evaluation stack.
- */
- final val Ldobj = OpCode.Ldobj
-
- /**
- * Pushes a new object reference to a string literal stored in the metadata.
- */
- final val Ldstr = OpCode.Ldstr
-
- /**
- * Creates a new object or a new instance of a value type, pushing an object reference
- * (type O) onto the evaluation stack.
- */
- final val Newobj = OpCode.Newobj
-
- /**
- * Attempts to cast an object passed by reference to the specified class.
- */
- final val Castclass = OpCode.Castclass
-
- /**
- * Tests whether an object reference (type O) is an instance of a particular class.
- */
- final val Isinst = OpCode.Isinst
-
- /**
- * Converts the unsigned integer value on top of the evaluation stack to float32.
- */
- final val Conv_R_Un = OpCode.Conv_R_Un
-
- /**
- * Converts the boxed representation of a value type to its unboxed form.
- */
- final val Unbox = OpCode.Unbox
-
- /**
- * Throws the exception object currently on the evaluation stack.
- */
- final val Throw = OpCode.Throw
-
- /**
- * Finds the value of a field in the object whose reference is currently
- * on the evaluation stack.
- */
- final val Ldfld = OpCode.Ldfld
-
- /**
- * Finds the address of a field in the object whose reference is currently
- * on the evaluation stack.
- */
- final val Ldflda = OpCode.Ldflda
-
- /**
- * Pushes the value of a static field onto the evaluation stack.
- */
- final val Ldsfld = OpCode.Ldsfld
-
- /**
- * Pushes the address of a static field onto the evaluation stack.
- */
- final val Ldsflda = OpCode.Ldsflda
-
- /**
- * Replaces the value stored in the field of an object reference or pointer with a new value.
- */
- final val Stfld = OpCode.Stfld
-
- /**
- * Replaces the value of a static field with a value from the evaluation stack.
- */
- final val Stsfld = OpCode.Stsfld
-
- /**
- * Copies a value of a specified type from the evaluation stack into a supplied memory address.
- */
- final val Stobj = OpCode.Stobj
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I1_Un = OpCode.Conv_Ovf_I1_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I2_Un = OpCode.Conv_Ovf_I2_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I4_Un = OpCode.Conv_Ovf_I4_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I8_Un = OpCode.Conv_Ovf_I8_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to signed natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I_Un = OpCode.Conv_Ovf_I_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U1_Un = OpCode.Conv_Ovf_U1_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U2_Un = OpCode.Conv_Ovf_U2_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U4_Un = OpCode.Conv_Ovf_U4_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U8_Un = OpCode.Conv_Ovf_U8_Un
-
- /**
- * Converts the unsigned value on top of the evaluation stack to unsigned natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U_Un = OpCode.Conv_Ovf_U_Un
-
- /**
- * Converts a value type to an object reference (type O).
- */
- final val Box = OpCode.Box
-
- /**
- * Pushes an object reference to a new zero-based, one-dimensional array whose elements
- * are of a specific type onto the evaluation stack.
- */
- final val Newarr = OpCode.Newarr
-
- /**
- * Pushes the number of elements of a zero-based, one-dimensional array
- * onto the evaluation stack.
- */
- final val Ldlen = OpCode.Ldlen
-
- /**
- * Loads the address of the array element at a specified array index onto
- * the top of the evaluation stack as type & (managed pointer).
- */
- final val Ldelema = OpCode.Ldelema
-
- /**
- * Loads the element with type natural int at a specified array index onto the top
- * of the evaluation stack as a natural int.
- */
- final val Ldelem_I = OpCode.Ldelem_I
-
- /**
- * Loads the element with type int8 at a specified array index onto the top of the
- * evaluation stack as an int32.
- */
- final val Ldelem_I1 = OpCode.Ldelem_I1
-
- /**
- * Loads the element with type int16 at a specified array index onto the top of
- * the evaluation stack as an int32.
- */
- final val Ldelem_I2 = OpCode.Ldelem_I2
-
- /**
- * Loads the element with type int32 at a specified array index onto the top of the
- * evaluation stack as an int32.
- */
- final val Ldelem_I4 = OpCode.Ldelem_I4
-
- /**
- * Loads the element with type int64 at a specified array index onto the top of the
- * evaluation stack as an int64.
- */
- final val Ldelem_I8 = OpCode.Ldelem_I8
-
- /**
- * Loads the element with type float32 at a specified array index onto the top of the
- * evaluation stack as type F (float)
- */
- final val Ldelem_R4 = OpCode.Ldelem_R4
-
- /**
- * Loads the element with type float64 at a specified array index onto the top of the
- * evaluation stack as type F (float) .
- */
- final val Ldelem_R8 = OpCode.Ldelem_R8
-
- /**
- * Loads the element containing an object reference at a specified array index onto
- * the top of the evaluation stack as type O (object reference).
- */
- final val Ldelem_Ref = OpCode.Ldelem_Ref
-
- /**
- * Loads the element with type unsigned int8 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U1 = OpCode.Ldelem_U1
-
- /**
- * Loads the element with type unsigned int16 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U2 = OpCode.Ldelem_U2
-
- /**
- * Loads the element with type unsigned int32 at a specified array index onto the top
- * of the evaluation stack as an int32.
- */
- final val Ldelem_U4 = OpCode.Ldelem_U4
-
- /**
- * Replaces the array element at a given index with the natural int value on
- * the evaluation stack.
- */
- final val Stelem_I = OpCode.Stelem_I
-
- /**
- * Replaces the array element at a given index with the int8 value on the evaluation stack.
- */
- final val Stelem_I1 = OpCode.Stelem_I1
-
- /**
- * Replaces the array element at a given index with the int16 value on the evaluation stack.
- */
- final val Stelem_I2 = OpCode.Stelem_I2
-
- /**
- * Replaces the array element at a given index with the int32 value on the evaluation stack.
- */
- final val Stelem_I4 = OpCode.Stelem_I4
-
- /**
- * Replaces the array element at a given index with the int64 value on the evaluation stack.
- */
- final val Stelem_I8 = OpCode.Stelem_I8
-
- /**
- * Replaces the array element at a given index with the float32 value on the evaluation stack.
- */
- final val Stelem_R4 = OpCode.Stelem_R4
-
- /**
- * Replaces the array element at a given index with the float64 value on the evaluation stack.
- */
- final val Stelem_R8 = OpCode.Stelem_R8
-
- /**
- * Replaces the array element at a given index with the object ref value (type O)
- * on the evaluation stack.
- */
- final val Stelem_Ref = OpCode.Stelem_Ref
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I1 = OpCode.Conv_Ovf_I1
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int16 and
- * extending it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I2 = OpCode.Conv_Ovf_I2
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I4 = OpCode.Conv_Ovf_I4
-
- /**
- * Converts the signed value on top of the evaluation stack to signed int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I8 = OpCode.Conv_Ovf_I8
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int8 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U1 = OpCode.Conv_Ovf_U1
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int16 and
- * extends it to int32, throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U2 = OpCode.Conv_Ovf_U2
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int32,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U4 = OpCode.Conv_Ovf_U4
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned int64,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U8 = OpCode.Conv_Ovf_U8
-
- /**
- * Retrieves the address (type &) embedded in a typed reference.
- */
- final val Refanyval = OpCode.Refanyval
-
- /**
- * Retrieves the type token embedded in a typed reference .
- */
- final val Refanytype = OpCode.Refanytype
-
- /**
- * Throws ArithmeticException if value is not a finite number.
- */
- final val Ckfinite = OpCode.Ckfinite
-
- /**
- * Pushes a typed reference to an instance of a specific type onto the evaluation stack.
- */
- final val Mkrefany = OpCode.Mkrefany
-
- /**
- * Converts a metadata token to its runtime representation, pushing it onto the evaluation stack.
- */
- final val Ldtoken = OpCode.Ldtoken
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int8, and extends it to int32.
- */
- final val Conv_U1 = OpCode.Conv_U1
-
- /**
- * Converts the value on top of the evaluation stack to unsigned int16, and extends it to int32.
- */
- final val Conv_U2 = OpCode.Conv_U2
-
- /**
- * Converts the value on top of the evaluation stack to natural int.
- */
- final val Conv_I = OpCode.Conv_I
-
- /**
- * Converts the signed value on top of the evaluation stack to signed natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_I = OpCode.Conv_Ovf_I
-
- /**
- * Converts the signed value on top of the evaluation stack to unsigned natural int,
- * throwing OverflowException on overflow.
- */
- final val Conv_Ovf_U = OpCode.Conv_Ovf_U
-
- /**
- * Adds two integers, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Add_Ovf = OpCode.Add_Ovf
-
- /**
- * Adds two unsigned integer values, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Add_Ovf_Un = OpCode.Add_Ovf_Un
-
- /**
- * Multiplies two integer values, performs an overflow check, and pushes the result
- * onto the evaluation stack.
- */
- final val Mul_Ovf = OpCode.Mul_Ovf
-
- /**
- * Multiplies two unsigned integer values , performs an overflow check ,
- * and pushes the result onto the evaluation stack.
- */
- final val Mul_Ovf_Un = OpCode.Mul_Ovf_Un
-
- /**
- * Subtracts one integer value from another, performs an overflow check,
- * and pushes the result onto the evaluation stack.
- */
- final val Sub_Ovf = OpCode.Sub_Ovf
-
- /**
- * Subtracts one unsigned integer value from another, performs an overflow check,
- * and pushes the result onto the evaluation stack.
- */
- final val Sub_Ovf_Un = OpCode.Sub_Ovf_Un
-
- /**
- * Transfers control from the fault or finally clause of an exception block back to
- * the Common Language Infrastructure (CLI) exception handler.
- */
- final val Endfinally = OpCode.Endfinally
-
- /**
- * Exits a protected region of code, unconditionally tranferring control
- * to a specific target instruction.
- */
- final val Leave = OpCode.Leave
-
- /**
- * Exits a protected region of code, unconditionally tranferring control
- * to a target instruction (short form).
- */
- final val Leave_S = OpCode.Leave_S
-
- /**
- * Stores a value of type natural int at a supplied address.
- */
- final val Stind_I = OpCode.Stind_I
-
- /**
- * Converts the value on top of the evaluation stack to unsigned natural int,
- * and extends it to natural int.
- */
- final val Conv_U = OpCode.Conv_U
-
- /**
- * Returns an unmanaged pointer to the argument list of the current method.
- */
- final val Arglist = OpCode.Arglist
-
- /**
- * Compares two values. If they are equal, the integer value 1 (int32) is pushed
- * onto the evaluation stack otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Ceq = OpCode.Ceq
-
- /**
- * Compares two values. If the first value is greater than the second,
- * the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Cgt = OpCode.Cgt
-
- /**
- * Compares two unsigned or unordered values. If the first value is greater than
- * the second, the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Cgt_Un = OpCode.Cgt_Un
-
- /**
- * Compares two values. If the first value is less than the second,
- * the integer value 1 (int32) is pushed onto the evaluation stack
- * otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Clt = OpCode.Clt
-
- /**
- * Compares the unsigned or unordered values value1 and value2. If value1 is
- * less than value2, then the integer value 1 (int32) is pushed onto the
- * evaluation stack otherwise 0 (int32) is pushed onto the evaluation stack.
- */
- final val Clt_Un = OpCode.Clt_Un
-
- /**
- * Pushes an unmanaged pointer (type natural int) to the native code implementing
- * a specific method onto the evaluation stack.
- */
- final val Ldftn = OpCode.Ldftn
-
- /**
- * Pushes an unmanaged pointer (type natural int) to the native code implementing
- * a particular virtual method associated with a specified object onto the evaluation stack.
- */
- final val Ldvirtftn = OpCode.Ldvirtftn
-
- /**
- * Loads an argument (referenced by a specified index value) onto the stack.
- */
- final val Ldarg = OpCode.Ldarg
-
- /**
- * Load an argument address onto the evaluation stack.
- */
- final val Ldarga = OpCode.Ldarga
-
- /**
- * Loads the local variable at a specific index onto the evaluation stack.
- */
- final val Ldloc = OpCode.Ldloc
-
- /**
- * Loads the address of the local variable at a specific index onto the evaluation stack.
- */
- final val Ldloca = OpCode.Ldloca
-
- /**
- * Stores the value on top of the evaluation stack in the argument slot at a specified index.
- */
- final val Starg = OpCode.Starg
-
- /**
- * Pops the current value from the top of the evaluation stack and stores it in a
- * the local variable list at a specified index.
- */
- final val Stloc = OpCode.Stloc
-
- /**
- * Allocates a certain number of bytes from the local dynamic memory pool and pushes the
- * address (a transient pointer, type *) of the first allocated Byte onto the evaluation stack.
- */
- final val Localloc = OpCode.Localloc
-
- /**
- * Transfers control from the filter clause of an exception back to the
- * Common Language Infrastructure (CLI) exception handler.
- */
- final val Endfilter = OpCode.Endfilter
-
- /**
- * Indicates that an address currently atop the evaluation stack might not be aligned
- * to the natural size of the immediately following ldind, stind, ldfld, stfld, ldobj,
- * stobj, initblk, or cpblk instruction.
- */
- final val Unaligned = OpCode.Unaligned
-
- /**
- * Specifies that an address currently atop the evaluation stack might be volatile,
- * and the results of reading that location cannot be cached or that multiple stores
- * to that location cannot be suppressed.
- */
- final val Volatile = OpCode.Volatile
-
- /**
- * Performs a postfixed method call instruction such that the current method's stack
- * frame is removed before the actual call instruction is executed.
- */
- final val Tailcall = OpCode.Tailcall
-
- /**
- * Initializes all the fields of the object at a specific address to a null reference
- * or a 0 of the appropriate primitive type.
- */
- final val Initobj = OpCode.Initobj
-
- /**
- * Copies a specified number bytes from a source address to a destination address .
- */
- final val Cpblk = OpCode.Cpblk
-
- /**
- * Initializes a specified block of memory at a specific address to a given size
- * and initial value.
- */
- final val Initblk = OpCode.Initblk
-
- /**
- * Rethrows the current exception.
- */
- final val Rethrow = OpCode.Rethrow
-
- /**
- * Pushes the size, in bytes, of a supplied value type onto the evaluation stack.
- */
- final val Sizeof = OpCode.Sizeof
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/ParameterBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/ParameterBuilder.scala
deleted file mode 100644
index 8f9d81a8b0..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/ParameterBuilder.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil.Type
-import ch.epfl.lamp.compiler.msil.ConstructorInfo
-import ch.epfl.lamp.compiler.msil.ParameterInfo
-import java.io.IOException
-
-/**
- * Creates or associates parameter information.
- * Parameter attributes need to consistent with the method signature.
- * If you specify Out attributes for a parameter, you should ensure that
- * the type of that method parameter is a ByRef type
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class ParameterBuilder(name: String, tpe: Type, attr: Int, pos: Int)
- extends ParameterInfo(name, tpe, attr, pos)
- with ICustomAttributeSetter
- with Visitable
-{
-
- //##########################################################################
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- //##########################################################################
-
- /** The apply method for a visitor */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseParameterBuilder(this)
- }
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/SingleFileILPrinterVisitor.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/SingleFileILPrinterVisitor.scala
deleted file mode 100644
index 50e9f45373..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/SingleFileILPrinterVisitor.scala
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies in MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.FileWriter
-import java.io.BufferedWriter
-import java.io.PrintWriter
-import java.io.IOException
-import java.util.Iterator
-import java.util.HashMap
-import java.util.Arrays
-
-import ch.epfl.lamp.compiler.msil._
-import ch.epfl.lamp.compiler.msil.emit
-import ch.epfl.lamp.compiler.msil.util.Table
-
-/**
- * The MSIL printer Visitor. It prints a complete
- * assembly in a single file that can be compiled by ilasm.
- *
- * @author Nikolay Mihaylov
- * @author Daniel Lorch
- * @version 1.0
- */
-final class SingleFileILPrinterVisitor(_fileName: String) extends ILPrinterVisitor {
- var fileName: String = _fileName
-
- out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)))
-
- /**
- * Visit an AssemblyBuilder
- */
- @throws(classOf[IOException])
- def caseAssemblyBuilder(assemblyBuilder: AssemblyBuilder) {
- ILPrinterVisitor.currAssembly = assemblyBuilder
-
- // first get the entryPoint
- this.entryPoint = assemblyBuilder.EntryPoint
-
- // all external assemblies
- as = assemblyBuilder.getExternAssemblies()
- scala.util.Sorting.quickSort(as)(assemblyNameComparator) // Arrays.sort(as, assemblyNameComparator)
-
- assemblyBuilder.generatedFiles += fileName
- printAssemblyBoilerplate()
-
- // print each module
- val m: Array[Module] = assemblyBuilder.GetModules()
- nomembers = true
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[ModuleBuilder])
- }
-
- nomembers = false
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[ModuleBuilder])
- }
- // close out file
- out.close()
- ILPrinterVisitor.currAssembly = null
- }
-
- /**
- * Visit a ModuleBuilder
- */
- @throws(classOf[IOException])
- def caseModuleBuilder(module: ModuleBuilder) {
- // print module declaration
- currentModule = module
- if (nomembers) {
- print(".module \'"); print(module.Name); println("\'")
- printAttributes(module)
- }
-
- if (!module.globalsCreated)
- module.CreateGlobalFunctions()
-
- val m: Array[MethodInfo] = module.GetMethods()
- for(i <- 0 until m.length) {
- print(m(i).asInstanceOf[MethodBuilder])
- }
-
- val t: Array[Type] = module.GetTypes()
- for(i <- 0 until t.length) {
- print(t(i).asInstanceOf[TypeBuilder])
- }
- currentModule = null
- }
-
-} // class SingleFileILPrinterVisitor
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/TypeBuilder.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/TypeBuilder.scala
deleted file mode 100644
index 0b0b16da65..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/TypeBuilder.scala
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import ch.epfl.lamp.compiler.msil._
-
-import ch.epfl.lamp.compiler.msil.util.PECustomMod
-
-import java.io.IOException
-
-/**
- * Defines and creates new instances of classes during runtime.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-class TypeBuilder (module: Module, attributes: Int, fullName: String, baseType: Type, interfaces: Array[Type], declType: Type)
- extends Type(module, attributes, fullName, baseType, interfaces, declType, 0)
- with ICustomAttributeSetter
- with Visitable
-{
- import TypeBuilder._
-
- //##########################################################################
- // public members
-
- /** 'Bakes' the type. */
- def CreateType(): Type = {
- fields = fieldBuilders.toArray // (new Array[FieldInfo](fieldBuilders.size())).asInstanceOf[Array[FieldInfo]]
- methods = methodBuilders.toArray // (new Array[MethodInfo](methodBuilders.size())).asInstanceOf[Array[MethodInfo]]
- constructors = constructorBuilders.toArray // (new Array[ConstructorInfo](constructorBuilders.size())).asInstanceOf[Array[ConstructorInfo]]
- nestedTypes = nestedTypeBuilders.toArray // (new Array[Type](nestedTypeBuilders.size())).asInstanceOf[Array[Type]]
-
- raw = false
- if (DeclaringType == null)
- Module.asInstanceOf[ModuleBuilder].addType(this)
- return this
- }
-
- /**
- * Adds a new field to the class, with the given name, attributes and field type. The location has no custom mods.
- */
- def DefineField(name: String, fieldType: Type, attrs: Short): FieldBuilder = {
- val fieldTypeWithCustomMods = new PECustomMod(fieldType, null)
- DefineField(name, fieldTypeWithCustomMods, attrs)
- }
-
- /**
- * Adds a new field to the class, with the given name, attributes and (field type , custom mods) combination.
- */
- def DefineField(name: String, fieldTypeWithMods: PECustomMod, attrs: Short): FieldBuilder = {
- val field: FieldBuilder = new FieldBuilder(name, this, attrs, fieldTypeWithMods)
- fieldBuilders += field
- return field
- }
-
- /**
- * Adds a new method to the class, with the given name and
- * method signature.
- */
- def DefineMethod(name: String, attrs: Short, returnType: Type, paramTypes: Array[Type]): MethodBuilder = {
- val method = new MethodBuilder(name, this, attrs, returnType, paramTypes)
- val methods = methodBuilders.iterator
- while(methods.hasNext) {
- val m = methods.next().asInstanceOf[MethodInfo]
- if (methodsEqual(m, method)) {
- throw new RuntimeException("["+ Assembly() + "] Method has already been defined: " + m)
- }
- }
- methodBuilders += method
- return method
- }
-
- /**
- * Adds a new constructor to the class, with the given attributes
- * and signature.
- */
- def DefineConstructor(attrs: Short, callingConvention: Short, paramTypes: Array[Type]): ConstructorBuilder = {
- val constr = new ConstructorBuilder(this, attrs, paramTypes)
- val iter = constructorBuilders.iterator
- while(iter.hasNext) {
- val c = iter.next().asInstanceOf[ConstructorInfo]
- if (constructorsEqual(c, constr)) {
- throw new RuntimeException("["+ Assembly() + "] Constructor has already been defined: " + c)
- }
- }
- constructorBuilders += constr
- return constr
- }
-
- /**
- * Defines a nested type given its name.
- */
- def DefineNestedType(name: String, attributes: Int, baseType: Type, interfaces: Array[Type]): TypeBuilder = {
- val nested = nestedTypeBuilders.iterator
- while(nested.hasNext) {
- val nt = nested.next
- if (nt.Name.equals(name)) {
- val message = "Nested type " + name + " has already been defined: " + nt
- throw new RuntimeException(message)
- }
- }
- val t = new TypeBuilder(Module, attributes, name, baseType, interfaces, this)
- nestedTypeBuilders += t
- return t
- }
-
- /** Get the field with the corresponding name. */
- override def GetField(name: String): FieldInfo = {
- testRaw(name)
- return super.GetField(name)
- }
-
- /** Get all fields of the current Type. */
- override def GetFields(): Array[FieldInfo] = {
- testRaw("<GetFields>")
- return super.GetFields()
- }
-
- /**
- * Searches for a public instance constructor whose parameters
- * match the types in the specified array.
- */
- override def GetConstructor(params: Array[Type]): ConstructorInfo = {
- testRaw(".ctor" + types2String(params))
- return super.GetConstructor(params)
- }
-
- /**
- * Returns all the public constructors defined for the current Type.
- */
- override def GetConstructors(): Array[ConstructorInfo] = {
- testRaw("<GetConstructors>")
- return super.GetConstructors()
- }
-
- /**
- * Searches for the specified public method whose parameters
- * match the specified argument types.
- */
- override def GetMethod(name: String, params: Array[Type]): MethodInfo = {
- testRaw(name + types2String(params))
- return super.GetMethod(name, params)
- }
-
- /** Returns all the public methods of the current Type. */
- override def GetMethods(): Array[MethodInfo] = {
- testRaw("<GetMethods>")
- return super.GetMethods()
- }
-
- /** Searches for the nested type with the specified name. */
- override def GetNestedType(name: String): Type = {
- testRaw(name)
- super.GetNestedType(name)
- }
-
- /** Returns all the types nested within the current Type. */
- override def GetNestedTypes(): Array[Type] = {
- testRaw("<GetNestedTypes>")
- super.GetNestedTypes()
- }
-
- /** Returns a Type object that represents a one-dimensional array of the current type */
- def MakeArrayType(): Type = {
- Type.mkArray(this, 1)
- }
-
- /** Sets a custom attribute. */
- def SetCustomAttribute(constr: ConstructorInfo, value: Array[Byte]) {
- addCustomAttribute(constr, value)
- }
-
- def setPosition(sourceLine: Int, sourceFilename: String) {
- this.sourceLine = sourceLine
- this.sourceFilename = sourceFilename
- }
-
- def setSourceFilepath(sourceFilepath: String) {
- this.sourceFilepath = sourceFilepath
- }
-
- //##########################################################################
- // protected members
-
- var sourceLine: Int = _
- var sourceFilename: String = _
- var sourceFilepath: String = _
-
- var fieldBuilders = scala.collection.mutable.ArrayBuffer.empty[FieldBuilder]
- var methodBuilders = scala.collection.mutable.ArrayBuffer.empty[MethodBuilder]
- var constructorBuilders = scala.collection.mutable.ArrayBuffer.empty[ConstructorBuilder]
- var nestedTypeBuilders = scala.collection.mutable.ArrayBuffer.empty[TypeBuilder]
-
- // shows if the type is 'raw', i.e. still subject to changes
- private var raw = true
-
- // throws an exception if the type is 'raw',
- // i.e. not finalized by call to CreateType
- protected def testRaw(member: String) {
- if (raw)
- throw new RuntimeException("Not supported for TypeBuilder before CreateType(): " +
- FullName + "::" + member)
- }
-
- //##########################################################################
- // public members not part of the Reflection.Emit.TypeBuilder interface.
-
- /** The apply method for a visitor. */
- @throws(classOf[IOException])
- def apply(v: Visitor) {
- v.caseTypeBuilder(this)
- }
-
- //##########################################################################
-
-} // class TypeBuilder
-
-object TypeBuilder {
- def types2String(types: Array[Type]): String = {
- val s = new StringBuffer("(")
- for(i <- 0 until types.length) {
- if (i > 0) s.append(", ")
- s.append(types(i))
- }
- s.append(")")
- return s.toString()
- }
-
- def methodsEqual(m1: MethodInfo, m2: MethodInfo): Boolean = {
- if (!m1.Name.equals(m2.Name))
- return false
- if (m1.ReturnType != m2.ReturnType)
- return false
- val p1 = m1.GetParameters()
- val p2 = m2.GetParameters()
- if (p1.length != p2.length)
- return false
- for(i <- 0 until p1.length)
- if (p1(i).ParameterType != p2(i).ParameterType)
- return false
- return true
- }
-
- def constructorsEqual(c1: ConstructorInfo, c2: ConstructorInfo): Boolean = {
- if (c1.IsStatic != c2.IsStatic)
- return false
- val p1 = c1.GetParameters()
- val p2 = c2.GetParameters()
- if (p1.length != p2.length)
- return false
- for(i <- 0 until p1.length)
- if (p1(i).ParameterType != p2(i).ParameterType)
- return false
- return true
-}
-
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitable.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitable.scala
deleted file mode 100644
index 28ec801dd4..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitable.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.IOException
-
-/**
- * The Visitable interface
- */
-trait Visitable {
-
- //##########################################################################
-
- /**
- * the visitable method to apply a visitor
- */
- @throws(classOf[IOException])
- def apply(v: Visitor): Unit
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitor.scala b/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitor.scala
deleted file mode 100644
index d4b84cdd4e..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/emit/Visitor.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * System.Reflection.Emit-like API for writing .NET assemblies to MSIL
- */
-
-
-package ch.epfl.lamp.compiler.msil.emit
-
-import java.io.IOException
-
-/**
- * The Visitor interface to walk through the MSIL code Builder hierarchy.
- */
-trait Visitor {
-
- //##########################################################################
-
- /** Visit an AssemblyBuilder */
- @throws(classOf[IOException])
- def caseAssemblyBuilder(assemblyBuilder: AssemblyBuilder): Unit
-
- /** Visit a ModuleBuilder */
- @throws(classOf[IOException])
- def caseModuleBuilder(moduleBuilder: ModuleBuilder): Unit
-
- /** Visit a TypeBuilder */
- @throws(classOf[IOException])
- def caseTypeBuilder(typeBuilder: TypeBuilder): Unit
-
- /** Visit a FieldBuilder */
- @throws(classOf[IOException])
- def caseFieldBuilder(fieldBuilder: FieldBuilder): Unit
-
- /** Visit a ConstructorBuilder */
- @throws(classOf[IOException])
- def caseConstructorBuilder(constructorBuilder: ConstructorBuilder): Unit
-
- /** Visit a MethodBuilder */
- @throws(classOf[IOException])
- def caseMethodBuilder(methodBuilder: MethodBuilder): Unit
-
- /** Visit a ParameterBuilder */
- @throws(classOf[IOException])
- def caseParameterBuilder(parameterBuilder: ParameterBuilder): Unit
-
- /** Visit an ILGenerator */
- @throws(classOf[IOException])
- def caseILGenerator(iLGenerator: ILGenerator): Unit
-
- /** Visit an OpCode */
- @throws(classOf[IOException])
- def caseOpCode(opCode: OpCode): Unit
-
- /** Visit a LocalBuilder */
- @throws(classOf[IOException])
- def caseLocalBuilder(localBuilder: LocalBuilder): Unit
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/tests/CustomAttributesTest.java b/src/msil/ch/epfl/lamp/compiler/msil/tests/CustomAttributesTest.java
deleted file mode 100644
index 9a6e28a545..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/tests/CustomAttributesTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package ch.epfl.lamp.compiler.msil.tests;
-
-import ch.epfl.lamp.compiler.msil.*;
-import ch.epfl.lamp.compiler.msil.util.Table;
-
-import java.io.PrintStream;
-
-public class CustomAttributesTest {
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("You must supply a filename!");
- System.exit(1);
- }
-
- Assembly assem = Assembly.LoadFrom(args[0]);
- Type.initMSCORLIB(assem);
-
- testCustomAttributes();
- }
-
- public static void testCustomAttributes() {
- Object[] attrs = Type.GetType("System.ObsoleteAttribute")
- .GetCustomAttributes(false);
- assert attrs != null;
- for (int i = 0; i < attrs.length; i++) {
- System.out.println("\t" + attrs[i]);
- }
- }
-
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/tests/JavaTypeTest.java b/src/msil/ch/epfl/lamp/compiler/msil/tests/JavaTypeTest.java
deleted file mode 100644
index 96ec1bfeea..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/tests/JavaTypeTest.java
+++ /dev/null
@@ -1,18 +0,0 @@
-
-package ch.epfl.lamp.compiler.msil.tests;
-
-import ch.epfl.lamp.compiler.msil.*;
-import ch.epfl.lamp.compiler.msil.util.VJSAssembly;
-
-public class JavaTypeTest {
-
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("usage: java test.JavaTypeTest classname");
- System.exit(1);
- }
-
- Type type = VJSAssembly.VJSLIB.GetType(args[0]);
- MembersTest.dumpType(System.out, type);
- }
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/tests/MembersTest.java b/src/msil/ch/epfl/lamp/compiler/msil/tests/MembersTest.java
deleted file mode 100644
index 37a5c6ea90..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/tests/MembersTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-
-package ch.epfl.lamp.compiler.msil.tests;
-
-import ch.epfl.lamp.compiler.msil.*;
-import ch.epfl.lamp.compiler.msil.util.Table;
-
-import java.io.PrintStream;
-
-public class MembersTest {
-
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println
- ("usage: java test.MembersTest assembly [classname]");
- System.exit(1);
- }
-
- Assembly mscorlib = Assembly.LoadFrom("mscorlib.dll");
- Type.initMSCORLIB(mscorlib);
- Assembly assem = Assembly.LoadFrom(args[0]);
- if (args.length > 1) {
- Type type = assem.GetType(args[1]);
- if (type != null)
- dumpMember(System.out, type);
- else System.err.println("Cannot find type " + args[1]
- + " in " + assem);
- } else {
- Type[] types = assem.GetTypes();
- System.out.println("Number of types in assembly " + assem
- + " -> " + types.length);
- dumpCustomAttributes(System.out, "assembly: ", assem);
- Module[] modules = assem.GetModules();
- for (int i = 0; i < modules.length; i++) {
- dumpCustomAttributes(System.out, "module " + modules[i] + ": ",
- modules[i]);
- }
- dumpMembers(System.out, types);
- }
- }
-
- public static final void dumpMember(PrintStream out, MemberInfo member) {
- try {
- if (member.MemberType() == MemberTypes.TypeInfo
- || member.MemberType() == MemberTypes.NestedType) {
- Type type = (Type)member;
- dumpCustomAttributes(out, "", type);
- out.print(TypeAttributes.accessModsToString(type.Attributes));
- out.print(type.IsInterface() ? " interface " : " class ");
- out.print(type);
- if (type.BaseType() != null)
- out.println(" extends " + type.BaseType());
- Type[] ifaces = type.GetInterfaces();
- if (ifaces.length > 0) {
- out.print("\timplements ");
- for (int i = 0; i < ifaces.length; i++) {
- out.print(ifaces[i]);
- if (i < (ifaces.length - 1))
- out.print(", ");
- }
- out.println();
- }
- out.println("{");
- int all = BindingFlags.Public | BindingFlags.DeclaredOnly// | BindingFlags.NonPublic
- | BindingFlags.Instance | BindingFlags.Static;
- dumpMembers(out, type.GetNestedTypes());
- dumpMembers(out, type.GetFields(all));
- dumpMembers(out, type.GetConstructors(all));
- dumpMembers(out, type.GetMethods(all));
- dumpMembers(out, type.GetProperties(all));
- dumpMembers(out, type.GetEvents());
- out.println("}");
- } else {
- dumpCustomAttributes(out, "", member);
- out.print(MemberTypes.toString(member.MemberType()));
- out.print(": "); out.print(member);
- out.println();
- }
- } catch (Throwable e) {
- String message = MemberTypes.toString(member.MemberType())
- + ": " + member;
- throw new RuntimeException(message, e);
- }
- }
-
- public static void dumpCustomAttributes(PrintStream out,
- String prefix,
- ICustomAttributeProvider att)
- {
- Object[] attrs = att.GetCustomAttributes(false);
- for (int j = 0; j < attrs.length; j++)
- out.println(prefix + attrs[j]);
- }
-
- public static void dumpMembers(PrintStream out, MemberInfo[] members) {
- for (int i = 0; i < members.length; i++) {
- dumpMember(out, members[i]);
- }
- }
-
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/tests/TableDump.java b/src/msil/ch/epfl/lamp/compiler/msil/tests/TableDump.java
deleted file mode 100644
index 1df389b011..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/tests/TableDump.java
+++ /dev/null
@@ -1,311 +0,0 @@
-
-package ch.epfl.lamp.compiler.msil.tests;
-
-import ch.epfl.lamp.compiler.msil.PEFile;
-import ch.epfl.lamp.compiler.msil.util.Table;
-import ch.epfl.lamp.compiler.msil.util.Table.*;
-
-import java.io.PrintStream;
-import java.io.FileNotFoundException;
-
-public class TableDump extends PEFile {
-
- //##########################################################################
-
- public TableDump(String filename) throws FileNotFoundException {
- super(filename);
- }
-
- /***/
- public void dump(PrintStream out) {
- out.println("CLI RVA: " + CLI_RVA);
- out.println("Optional header size: " + optHeaderSize);
- out.println("Number of sections: " + numOfSections);
- out.println();
-
- for (int i = 0; i < sections.length; i++) {
- sections[i].dump(out);
- out.println();
- }
-
- out.println("MetaData Offset: 0x" + Integer.toHexString(posMetadata));
- out.println("Number of streams: " + numOfStreams);
-
- out.println("#~ stream"); Meta.dump(out); out.println();
- out.println("#Strings stream"); Strings.dump(out); out.println();
- if (US != null) {
- out.println("#US stream"); US.dump(out); out.println();
- }
- out.println("#GUID stream"); GUID.dump(out); out.println();
- out.println("#Blob stream"); Blob.dump(out); out.println();
-
- out.println("Heap Sizes IndexedSeq = 0x0" + Integer.toHexString(heapSizes));
- out.println();
-
- for(int i = 0; i < Table.MAX_NUMBER; i++)
- if(getTable(i).rows > 0) {
- dump(out, getTable(i));
- out.println();
- }
-
- }
-
- /** Dumps the contents of this table. */
- public void dump(PrintStream out, Table table) {
- out.println("Table:" + " ID = 0x" + byte2hex(table.id));
- out.println("\tname = " + table.getTableName());
- out.println("\trows = " + table.rows);
- //out.println("\tStart pos in file = 0x" + Long.toHexString(table.start));
- for (int i = 1; i <= table.rows; i++)
- dumpRow(out, table, i);
- }
-
- public void dumpIndex(PrintStream out, int tableSetId, int index) {
- int tableId = Table.getTableId(tableSetId, index);
- int row = Table.getTableIndex(tableSetId, index);
- out.print(getTable(tableId).getTableName());
- out.print('[');
- out.print(getTable(tableId).isShort ? short2hex(row) : int2hex(row));
- out.print(']');
- }
-
- public void dumpRow(PrintStream out, Table table, int row) {
- table.readRow(row);
- out.print(table.getTableName());
- out.print("[" + short2hex(row) + "]: ");
- dumpRow(out, table);
- out.println();
- }
-
- /** Prints the current content of the fields of the class. */
- public void dumpRow(PrintStream out, Table table) {
- if (table instanceof ModuleDef) {
- ModuleDef t = (ModuleDef)table;
- out.print("Generation = 0x" + short2hex(t.Generation));
- out.print("; Name = " + getString(t.Name));
- //out.print("; Mvid = (" + bytes2hex(getGUID(Mvid)) + ")");
- } else if (table instanceof TypeRef) {
- TypeRef t = (TypeRef)table;
- out.print("FullName = " + t.getFullName());
- out.print("; ResolutionScope = 0x" + int2hex(t.ResolutionScope));
- } else if (table instanceof TypeDef) {
- TypeDef t = (TypeDef)table;
- out.print("Flags = 0x"); out.print(int2hex(t.Flags));
- out.print("; FullName = "); out.print(t.getFullName());
- out.print("; Extends = ");
- dumpIndex(out, Table._TypeDefOrRef, t.Extends);
- out.print("; FieldList = "); out.print(t.FieldList);
- out.print("; MethodList = "); out.print(t.MethodList);
- } else if (table instanceof FieldTrans) {
- FieldTrans t = (FieldTrans)table;
- out.print("Field = "); out.print(t.Field);
- } else if (table instanceof FieldDef) {
- FieldDef t = (FieldDef)table;
- out.print("Flags = 0x" + short2hex(t.Flags));
- out.print("; Name = " + t.getName());
- out.print("; Signature = (" +
- bytes2hex(getBlob(t.Signature)) + ")");
- } else if (table instanceof MethodTrans) {
- MethodTrans t = (MethodTrans)table;
- out.print("Method = "); out.print(t.Method);
- } else if (table instanceof MethodDef) {
- MethodDef t = (MethodDef)table;
- out.print("Flags = 0x" + short2hex(t.Flags));
- out.print("; Name = " + t.getName());
- out.print("; ParamList = " + t.ParamList);
- out.print("; Signature = (" +
- bytes2hex(getBlob(t.Signature)) + ")");
- } else if (table instanceof ParamDef) {
- ParamDef t = (ParamDef)table;
- out.print("Flags = 0x" + short2hex(t.Flags));
- out.print("; Name = " + t.getName());
- out.print("; Sequence = " + t.Sequence);
- } else if (table instanceof InterfaceImpl) {
- InterfaceImpl t = (InterfaceImpl)table;
- out.print("Class = 0x" + short2hex(t.Class));// + " (ref to: ");
- //TypeDef td = (TypeDef) getTable(TypeDef.ID);
- //td.readRow(Class);
- //td.dumpRow(out);
- out.print("; Interface = 0x" + short2hex(t.Interface));
- } else if (table instanceof MemberRef) {
- MemberRef t = (MemberRef)table;
- out.print("Name = " + t.getName());
- out.print("; Signature = (" +
- bytes2hex(getBlob(t.Signature)) + ")");
- out.print("; Class = " + t.Class);
- } else if (table instanceof Constant) {
- Constant t = (Constant)table;
- out.print("Parent = "); dumpIndex(out, Table._HasConstant, t.Parent);
- out.print("; Type = 0x" + byte2hex(t.Type));
- out.print("; Value = (" + bytes2hex(getBlob(t.Value)));
- out.print("); Value = " + t.getValue());
- } else if (table instanceof CustomAttribute) {
- CustomAttribute t = (CustomAttribute)table;
- //out.print("Parent = 0x" + int2hex(t.Parent));
- out.print("Parent = ");
- dumpIndex(out, Table._HasCustomAttribute, t.Parent);
- //out.print("; Type = 0x" + short2hex(t.Type));
- out.print("; Type = ");
- dumpIndex(out, Table._CustomAttributeType, t.Type);
- out.print("; Value = (" + bytes2hex(t.getValue()) + ")");
- } else if (table instanceof FieldMarshal) {
- FieldMarshal t = (FieldMarshal)table;
- out.print("NativeType = (");
- out.print(bytes2hex(getBlob(t.NativeType)) + ")");
- } else if (table instanceof DeclSecurity) {
- DeclSecurity t = (DeclSecurity)table;
- out.print("Action = 0x" + short2hex(t.Action));
- out.print("; PermissionSet = (" +
- bytes2hex(getBlob(t.PermissionSet)) + ")");
- } else if (table instanceof ClassLayout) {
- ClassLayout t = (ClassLayout)table;
- out.print("PackingSize = 0x" + short2hex(t.PackingSize));
- out.print("; ClassSize = 0x" + int2hex(t.ClassSize));
- out.print(": Parent = " + t.Parent + " (ref to: ");
- dumpRow(out, this.TypeDef(t.Parent));
- out.print(")");
- } else if (table instanceof FieldLayout) {
- FieldLayout t = (FieldLayout)table;
- out.print("Offset = 0x" + int2hex(t.Offset));
- out.print("; Field = (ref to: ");
- dumpRow(out, this.FieldDef(t.Field));
- out.print(")");
- } else if (table instanceof StandAloneSig) {
- StandAloneSig t = (StandAloneSig)table;
- out.print("StandAloneSig: Signature = (" +
- bytes2hex(getBlob(t.Signature)) + ")");
- } else if (table instanceof EventMap) {
- EventMap t = (EventMap)table;
- out.print("Parent = 0x" + int2hex(t.Parent) + " (ref to: ");
- dumpRow(out, this.TypeDef(t.Parent));
- out.print("); EventList = 0x"); out.print(int2hex(t.EventList));
- } else if (table instanceof EventDef) {
- EventDef t = (EventDef)table;
- out.print("EventFlags = 0x" + short2hex(t.EventFlags));
- out.print("; Name = " + t.getName());
- out.print("; EventType = 0x" + int2hex(t.EventType));
- } else if (table instanceof PropertyMap) {
- PropertyMap t = (PropertyMap)table;
- out.print("Parent = " + t.Parent + " (ref to: ");
- dumpRow(out, this.TypeDef(t.Parent));
- out.print(")");
- } else if (table instanceof PropertyDef) {
- PropertyDef t = (PropertyDef)table;
- out.print("Flags = 0x" + short2hex(t.Flags));
- out.print("; Name = " + t.getName());
- out.print("; Type = (" + bytes2hex(getBlob(t.Type)) + ")");
- } else if (table instanceof MethodSemantics) {
- MethodSemantics t = (MethodSemantics)table;
- out.print("Semantics = 0x" + short2hex(t.Semantics));
- out.print("; Method = 0x" + int2hex(t.Method) + " (ref to: ");
- dumpRow(out, this.MethodDef(t.Method));
- out.print("); Association = 0x" + int2hex(t.Association));
- } else if (table instanceof MethodImpl) {
- MethodImpl t = (MethodImpl)table;
- out.print("Class = (ref to: ");
- dumpRow(out, this.TypeDef(t.Class));
- out.print(")");
- } else if (table instanceof ModuleRef) {
- ModuleRef t = (ModuleRef)table;
- out.print("Name = " + t.getName());
- } else if (table instanceof TypeSpec) {
- TypeSpec t = (TypeSpec)table;
- out.print("Signature = (" +
- bytes2hex(getBlob(t.Signature)) + ")");
- } else if (table instanceof ImplMap) {
- ImplMap t = (ImplMap)table;
- out.print("ImportName = " + getString(t.ImportName));
- } else if (table instanceof FieldRVA) {
- FieldRVA t = (FieldRVA)table;
- out.print("RVA = 0x" + int2hex(t.RVA));
- out.print("; Field = (ref to: ");
- dumpRow(out, this.FieldDef(t.Field));
- out.print(")");
- } else if (table instanceof AssemblyDef) {
- AssemblyDef t = (AssemblyDef)table;
- out.print("Flags = 0x" + int2hex(t.Flags));
- out.print(" ; Name = " + getString(t.Name));
- out.print("; Culture = " + getString(t.Culture));
- out.print(" ; Version = " + t.MajorVersion + ".");
- out.print(t.MinorVersion + "." + t.BuildNumber);
- out.print("." + t.RevisionNumber);
- out.print("; HashAlgId = 0x" + int2hex(t.HashAlgId));
- out.print("; PublicKey = (");
- out.print(bytes2hex(getBlob(t.PublicKey)) + ")");
- } else if (table instanceof AssemblyProcessor) {
- AssemblyProcessor t = (AssemblyProcessor)table;
- out.print("Processor = 0x" + int2hex(t.Processor));
- } else if (table instanceof AssemblyOS) {
- AssemblyOS t = (AssemblyOS)table;
- out.print("!?!");
- } else if (table instanceof AssemblyRef) {
- AssemblyRef t = (AssemblyRef)table;
- out.print("Flags = 0x" + int2hex(t.Flags));
- out.print("; Name = " + getString(t.Name));
- out.print("; Culture = " + getString(t.Culture));
- out.print("; Version = " + t.MajorVersion + "." + t.MinorVersion);
- out.print("." + t.BuildNumber + "." + t.RevisionNumber);
- out.print("; PublicKeyOrToken = (" +
- bytes2hex(getBlob(t.PublicKeyOrToken)) + ")");
- out.print("; HashValue = (" +
- bytes2hex(getBlob(t.HashValue)) + ")");
- } else if (table instanceof AssemblyRefProcessor) {
- AssemblyRefProcessor t = (AssemblyRefProcessor)table;
- out.print("!?!");
- } else if (table instanceof AssemblyRefOS) {
- AssemblyRefOS t = (AssemblyRefOS)table;
- out.print("!?!");
- } else if (table instanceof FileDef) {
- FileDef t = (FileDef)table;
- out.print("Flags = 0x" + int2hex(t.Flags));
- out.print("; Name = " + t.getName());
- out.print("; HashValue = (" + bytes2hex(getBlob(t.HashValue)) +")");
- } else if (table instanceof ExportedType) {
- ExportedType t = (ExportedType)table;
- out.print("FullName = " + t.getFullName());
- } else if (table instanceof ManifestResource) {
- ManifestResource t = (ManifestResource)table;
- out.print("Name = " + getString(t.Name));
- out.print("; Flags = 0x" + int2hex(t.Flags));
- } else if (table instanceof NestedClass) {
- NestedClass t = (NestedClass)table;
- out.print(this.TypeDef(t.EnclosingClass).getFullName());
- out.print("/");
- out.print(this.TypeDef(t.NestedClass).getFullName());
- } else
- throw new RuntimeException("Unknown table " + table.getClass());
- }
-
- //##########################################################################
-
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("You must supply a filename!");
- System.exit(1);
- }
-
- TableDump file = null;
- try {
- file = new TableDump(args[0]);
- } catch (FileNotFoundException e) { e.printStackTrace(); }
-
- if (args.length > 1) {
- nextarg:
- for (int i = 1; i < args.length; i++) {
- String name = args[i];
- for (int tableId = 0; tableId < Table.MAX_NUMBER; tableId++) {
- Table table = file.getTable(tableId);
- if ((table.rows > 0) && name.equals(table.getTableName())) {
- file.dump(System.out, table);
- System.out.println();
- continue nextarg;
- }
- }
- System.err.println("No such table: " + name);
- }
- } else
- file.dump(System.out);
- }
-
- //##########################################################################
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/tests/Test.java b/src/msil/ch/epfl/lamp/compiler/msil/tests/Test.java
deleted file mode 100644
index 2c5946a734..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/tests/Test.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-package test;
-
-import ch.epfl.lamp.compiler.msil.*;
-import ch.epfl.lamp.compiler.msil.util.Table;
-
-import java.io.PrintStream;
-
-public class Test {
- public static void main(String[] args) {
- if (args.length < 1) {
- System.err.println("You must supply a filename!");
- System.exit(1);
- }
-
- Assembly assem = Assembly.LoadFrom(args[0]);
- Type.initMSCORLIB(assem);
-
- //"System.Collections.ArrayList"
- if (args.length >= 2) {
- Type t = Type.GetType(args[1]);
- dumpType(System.out, t);
- } else {
- dumpAssembly(assem);
- }
- }
-
-
- public static void dumpAssembly(Assembly assem) {
- Module[] modules = assem.GetModules();
-// System.out.println("Modules in assembly " + assem +
-// " (" + modules.length + ")");
-// for (int i = 0; i < modules.length; i++) {
-// System.out.println("\t" + modules[i]);
-// }
-
- Type[] types = modules[0].GetTypes();
-// System.out.println("Types in assembly " + assem +
-// " (" + types.length + ")");
- for (int i = 0; i < types.length; i++) {
- System.out.println("#" + i + " -> " + types[i]);
- types[i].completeType();
- }
- }
-
- public static final void dumpType(PrintStream out, Type type) {
- out.println("Type = " + type);
- out.println("Name = " + type.Name);
- out.println("Namespace = " + type.Namespace);
- out.println("FullName = " + type.FullName);
- out.println("Attributes = " + TypeAttributes.toString(type.Attributes));
- out.println("BaseType = " + type.BaseType);
- Type[] ifaces = type.GetInterfaces();
- if (ifaces != null) {
- for (int i = 0; i < ifaces.length; i++)
- out.println("\timplements " + ifaces[i]);
- }
- out.println("Assembly = " + type.Assembly);
- out.println("Module = " + type.Module);
- out.println("DeclaringType = " + type.DeclaringType);
- out.println("IsInterface = " + type.IsInterface);
- out.println("IsAbstract = " + type.IsAbstract);
-
- FieldInfo[] fields = type.GetFields(BindingFlags.Instance
- | BindingFlags.Static
- | BindingFlags.NonPublic);
- out.println("\nFields (" + fields.length + "):");
- for (int i = 0; i < fields.length; i++) {
- out.println("\t" + fields[i]);
- out.println("\t\tDeclaringType = " + fields[i].DeclaringType);
- out.println("\t\tReflectedType = " + fields[i].ReflectedType);
- }
-
- ConstructorInfo[] constrs = type.GetConstructors();
- out.println("\nConstructors (" + constrs.length + "):");
- for (int i = 0; i < constrs.length; i++) {
- out.println("\t" + constrs[i]);
- }
-
-// MethodInfo[] methods = type.GetMethods(BindingFlags.Instance
-// | BindingFlags.Static
-// | BindingFlags.Public
-// | BindingFlags.NonPublic);
- MethodInfo[] methods = type.GetMethods();
- out.println("\nMethods (" + methods.length + "):");
- for (int i = 0; i < methods.length; i++) {
- out.println("\t" + methods[i]);
- out.println("\t\tDeclaringType = " + methods[i].DeclaringType);
- out.println("\t\tReflectedType = " + methods[i].ReflectedType);
- }
- }
-}
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/PECustomMod.java b/src/msil/ch/epfl/lamp/compiler/msil/util/PECustomMod.java
deleted file mode 100644
index 56519e8487..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/PECustomMod.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package ch.epfl.lamp.compiler.msil.util;
-
-import ch.epfl.lamp.compiler.msil.Type;
-import ch.epfl.lamp.compiler.msil.CustomModifier;
-
-/**
- * A PECustomMod holds the info parsed from metadata per the CustomMod production in Sec. 23.2.7, Partition II.
- * */
-public final class PECustomMod {
-
- public final Type marked;
- public final CustomModifier[] cmods;
-
- /** Terminology:
- the CustomModifier(s) are markers,
- and the msil.Type is a type marked by those markers. */
- public PECustomMod(Type marked, CustomModifier[] cmods) {
- this.marked = marked;
- this.cmods = cmods;
- }
-
-}
-
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/PESection.java b/src/msil/ch/epfl/lamp/compiler/msil/util/PESection.java
deleted file mode 100644
index 454a94e55c..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/PESection.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * System.Reflection-like API for acces to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil.util;
-
-import ch.epfl.lamp.compiler.msil.PEFile;
-
-import java.io.PrintStream;
-
-/** Describes a section from a PE/COFF file
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class PESection {
-
- private final PEFile file;
- private final long sectionStart;
-
- public final String name;
- public final int virtAddr;
- public final int virtSize;
- public final int realAddr;
- public final int realSize;
- public final int flags;
-
- private static final byte[] buf = new byte[8];
-
- public PESection(PEFile file) {
- this.file = file;
- sectionStart = file.pos();
- file.read(buf);
- int i;
- for(i = 7; (i >= 0) && (0 == buf[i]); i--);
- name = new String(buf, 0, i + 1);
- virtSize = file.readInt();
- virtAddr = file.readInt();
- realSize = file.readInt();
- realAddr = file.readInt();
- file.skip(3 * PEFile.INT_SIZE);
- flags = file.readInt();
- }
-
-
- public void dump(PrintStream out) {
- out.println("Section name: " + name +
- " (name.length=" + name.length() + ")");
- out.println("Virtual Address: 0x" + PEFile.int2hex(virtAddr));
- out.println("Virtual Size: 0x" + PEFile.int2hex(virtSize));
- out.println("Real Address: 0x" + PEFile.int2hex(realAddr));
- out.println("Real Size: 0x" + PEFile.int2hex(realSize));
- out.println("Flags: 0x" + PEFile.int2hex(flags));
- }
-
-} // class PESection
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java b/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java
deleted file mode 100644
index 649d9e74f2..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * System.Reflection-like API for acces to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil.util;
-
-import ch.epfl.lamp.compiler.msil.PEFile;
-import ch.epfl.lamp.compiler.msil.PEFile.Sig;
-
-import java.io.PrintStream;
-import java.io.IOException;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-/**
- * Implements support for CLI streams within a PE file.
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public final class PEStream implements Signature {
-
- //##########################################################################
- // Members
-
- /** The name of the stream. */
- public final String name;
-
- /** The offset of the stream from the beginning of the file. */
- public final int offset;
-
- /** The size of the stream in bytes; shall be multiple of 4. */
- public final int size;
-
- private final PEFile file;
-
- private final ByteBuffer buffer;
-
- //##########################################################################
-
- /** The PEStream class constructor.
- * @param file - the PEFile to which this stream belongs
- */
- public PEStream(PEFile file) {
- this.file = file;
- offset = file.fromRVA(file.rvaMetadata + file.readInt());
- size = file.readInt();
- buffer = file.getBuffer(offset, size);
-
- int i = 0;
- byte [] _buf = new byte [16];
- do {
- _buf[i] = (byte) file.readByte();
- i++;
- } while(0 != _buf[i-1]);
- name = new String(_buf, 0, i - 1);
-
- file.align(PEFile.INT_SIZE, file.posMetadata);
- //assert size % 4 == 0;
- }
-
- /** Move to the specified position in the stream. */
- private void seek(int pos) {
- try {
- buffer.position(pos);
- } catch (IllegalArgumentException e) {
- System.err.println("\nSeek failed in file " + file
- + " for position " + pos
- + " of stream " + name + " (" + buffer + ")");
- throw e;
- }
- }
-
- /** Return a string from the specified position in the stream. */
- public String getString(int pos) {
- seek(pos);
- buffer.mark();
- int i;
- for (i = 0; getByte() != 0; i++);
- byte[] buf = new byte[i];
- buffer.reset(); // go back to the marked position
- buffer.get(buf);
- try {
- return new String(buf, "UTF-8");
- } catch (java.io.UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-
- /** Read a byte from the stream. */
- public int getByte() {
- return (buffer.get() + 0x0100) & 0xff;
- }
-
- /** Return the GUID at the given position in the stream. */
- public byte[] getGUID(int pos) {
- seek(pos);
- byte[] buf = new byte[32]; // 128-bit GUID
- try {
- buffer.get(buf);
- } catch (Exception e) {
- System.err.println();
- System.err.println("PEStream.getBlob(): Exception for pos = " +
- pos + " and buf.length = " + buf.length);
- System.err.println("\tbuffer = " + buffer);
- e.printStackTrace();
- throw new RuntimeException();
- }
- return buf;
- }
-
- public int readLength() {
- int length = getByte();
- if ((length & 0x80) != 0) {
- length = ((length & 0x7f) << 8) | getByte();
- if ((length & 0x4000) != 0)
- length = ((length & 0x3fff) << 16) | (getByte()<<8) | getByte();
- }
- return length;
- }
-
- /** Return a blob from the specified position in the stream. */
- public byte[] getBlob(int pos) {
- seek(pos);
- // the length indicates the number of bytes
- // AFTER the encoded size of the blob
- int length = readLength();
- byte[] buf = new byte[length];
- buffer.get(buf);
- return buf;
- }
-
- /***/
- public Sig getSignature(int pos) {
- seek(pos);
- return file.newSignature(buffer);
- }
-
- /**
- */
- public Object getConstant(int type, int pos) {
- Object val = null;
- seek(pos);
- int length = readLength(); // skip over the blob length field
- switch (type) {
- case ELEMENT_TYPE_BOOLEAN:
- assert length == 1;
- return buffer.get() == 0 ? Boolean.FALSE : Boolean.TRUE;
- case ELEMENT_TYPE_CHAR:
- assert length == 2 : "length == " + length;
- return new Character(buffer.getChar());
- case ELEMENT_TYPE_I1:
- case ELEMENT_TYPE_U1: // TODO U1 not the same as I1
- assert length == 1;
- return new Byte(buffer.get());
- case ELEMENT_TYPE_I2:
- case ELEMENT_TYPE_U2:
- assert length == 2;
- return new Short(buffer.getShort());
- case ELEMENT_TYPE_I4:
- case ELEMENT_TYPE_U4:
- assert length == 4;
- return new Integer(buffer.getInt());
- case ELEMENT_TYPE_I8:
- case ELEMENT_TYPE_U8:
- assert length == 8;
- return new Long(buffer.getLong());
- case ELEMENT_TYPE_R4:
- assert length == 4;
- return new Float(buffer.getFloat());
- case ELEMENT_TYPE_R8:
- assert length == 8;
- return new Double(buffer.getDouble());
- case ELEMENT_TYPE_STRING:
-// length /= 2;
-// char[] chars = new char[length];
-// for (int i = 0; i < length; i++)
-// chars[i] = buffer.getChar();
-// val = new String(chars);
- try {
- return new String(getBlob(pos), "UTF-16LE");
- } catch(java.io.UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- default: throw new RuntimeException("Illegal constant type: " + type);
- }
- }
-
- public void dump(PrintStream out) {
- out.println("Stream name: " + name + " (length " +
- name.length() + " characters)");
- out.println("Stream offset: 0x" + PEFile.int2hex(offset));
- out.println("Stream size: 0x" + PEFile.int2hex(size));
- }
-
- //##########################################################################
-} // class PEStream
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/Signature.java b/src/msil/ch/epfl/lamp/compiler/msil/util/Signature.java
deleted file mode 100644
index d5dc0ff32c..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/Signature.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * System.Reflection-like API for acces to .NET assemblies (DLL & EXE)
- */
-
-
-package ch.epfl.lamp.compiler.msil.util;
-
-import ch.epfl.lamp.compiler.msil.Type;
-
-/**
- * Signatures
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public interface Signature {
-
- //##########################################################################
-
- /** Marks end of a list. */
- public static final int ELEMENT_TYPE_END = 0x00;
- /** void */
- public static final int ELEMENT_TYPE_VOID = 0x01;
- /** boolean */
- public static final int ELEMENT_TYPE_BOOLEAN = 0x02;
- /** char */
- public static final int ELEMENT_TYPE_CHAR = 0x03;
- /** signed byte */
- public static final int ELEMENT_TYPE_I1 = 0x04;
- /** byte */
- public static final int ELEMENT_TYPE_U1 = 0x05;
- /** short */
- public static final int ELEMENT_TYPE_I2 = 0x06;
- /** unsigned short */
- public static final int ELEMENT_TYPE_U2 = 0x07;
- /** int */
- public static final int ELEMENT_TYPE_I4 = 0x08;
- /** unsigned int */
- public static final int ELEMENT_TYPE_U4 = 0x09;
- /** long */
- public static final int ELEMENT_TYPE_I8 = 0x0a;
- /** unsigned long */
- public static final int ELEMENT_TYPE_U8 = 0x0b;
- /** float */
- public static final int ELEMENT_TYPE_R4 = 0x0c;
- /** double */
- public static final int ELEMENT_TYPE_R8 = 0x0d;
- /** string */
- public static final int ELEMENT_TYPE_STRING = 0x0e;
- /** Followed by <type> token. */
- public static final int ELEMENT_TYPE_PTR = 0x0f;
- /** Followed by <type> token. */
- public static final int ELEMENT_TYPE_BYREF = 0x10;
- /** Followed by <type> token */
- public static final int ELEMENT_TYPE_VALUETYPE = 0x11;
- /** Followed by <type> token */
- public static final int ELEMENT_TYPE_CLASS = 0x12;
-
- public static final int ELEMENT_TYPE_VAR = 0x13;
-
- /**
- * <type> <rank> <boundsCount> <bound1> ... <loCount> <lo1> ...
- */
- public static final int ELEMENT_TYPE_ARRAY = 0x14;
-
- public static final int ELEMENT_TYPE_GENERICINST = 0x15;
- /***/
- public static final int ELEMENT_TYPE_TYPEDBYREF = 0x16;
- /** System.IntPtr */
- public static final int ELEMENT_TYPE_I = 0x18;
- /** System.UIntPtr */
- public static final int ELEMENT_TYPE_U = 0x19;
- /** Followed by full method signature. */
- public static final int ELEMENT_TYPE_FNPTR = 0x1b;
- /** System.Object. */
- public static final int ELEMENT_TYPE_OBJECT = 0x1c;
- /** Single-dim array with 0 lower bound. */
- public static final int ELEMENT_TYPE_SZARRAY = 0x1d;
-
- public static final int ELEMENT_TYPE_MVAR = 0x1e;
-
- /** Required modifier : followed by a TypeDef or TypeRef token. */
- public static final int ELEMENT_TYPE_CMOD_REQD = 0x1f;
- /** Optional modifier : followed by a TypeDef or TypeRef token. */
- public static final int ELEMENT_TYPE_CMOD_OPT = 0x20;
- /** Implemented within the CLI. */
- public static final int ELEMENT_TYPE_INTERNAL = 0x21;
- /** Or'd with following element types. */
- public static final int ELEMENT_TYPE_MODIFIER = 0x40;
- /** Sentinel for varargs method signature. */
- public static final int ELEMENT_TYPE_SENTINEL = 0x41;
- /**Denotes a local variable that points at a pinned object. */
- public static final int ELEMENT_TYPE_PINNED = 0x45;
-
- //##########################################################################
- // signature designators
-
- public static final int HASTHIS = 0x20;
- public static final int EXPLICITTHIS = 0x40;
- public static final int DEFAULT = 0x00;
- public static final int VARARG = 0x05;
- public static final int GENERIC = 0x10;
- public static final int SENTINEL = 0x41;
- public static final int C = 0x01;
- public static final int STDCALL = 0x02;
- public static final int THISCALL = 0x03;
- public static final int FASTCALL = 0x04;
- public static final int FIELD = 0x06;
- public static final int PROPERTY = 0x08;
- public static final int LOCAL_SIG = 0x07;
-
- //##########################################################################
- // extra IDs used in the serialization format of named arguments
- // to custom attributes. Reverse-engineered from compiled C# example
-
- /** What follows is a string with the full name of the type. */
- public static final int X_ELEMENT_TYPE_TYPE = 0x50;
-
- /** What follows is a string with the full name of the enumeration type*/
- public static final int X_ELEMENT_TYPE_ENUM = 0x55;
-
- /** The named argument specifies a field. */
- public static final int X_ELEMENT_KIND_FIELD = 0x53;
-
- /** The named argument specifies a property. */
- public static final int X_ELEMENT_KIND_PROPERTY = 0x54;
-
- //##########################################################################
-} // interface Signature
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java b/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java
deleted file mode 100644
index 1f43b8c2fa..0000000000
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java
+++ /dev/null
@@ -1,1859 +0,0 @@
-/*
- * System.Reflection-like API for acces to .NET Assemblies
- */
-
-
-package ch.epfl.lamp.compiler.msil.util;
-
-import ch.epfl.lamp.compiler.msil.PEFile;
-import ch.epfl.lamp.compiler.msil.PEFile.Sig;
-
-import java.io.PrintStream;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-
-/**
- * Represents a table in a .NET assembly
- *
- * @author Nikolay Mihaylov
- * @version 1.0
- */
-public abstract class Table {
-
- //##########################################################################
-
- public static final int MAX_NUMBER = 64;
-
- public static final long VALID_TABLES_MASK = 0x03ff3fb7ff57L;
-
- //##########################################################################
- // fields and methods for handling predefined sets of tables
-
- public static final int TABLE_SET_LENGTH = 13;
-
- public static final int _TypeDefOrRef = 0;
- public static final int _HasConstant = 1;
- public static final int _HasCustomAttribute = 2;
- public static final int _HasFieldMarshal = 3;
- public static final int _HasDeclSecurity = 4;
- public static final int _MemberRefParent = 5;
- public static final int _HasSemantics = 6;
- public static final int _MethodDefOrRef = 7;
- public static final int _MemberForwarded = 8;
- public static final int _Implementation = 9;
- public static final int _CustomAttributeType = 10;
- public static final int _ResolutionScope = 11;
- public static final int _TypeOrMethodDef = 12;
-
-
- public static final int[][] TableSet = new int[TABLE_SET_LENGTH][];
-
- static {
- TableSet[_TypeDefOrRef] =
- new int[] {TypeDef.ID, TypeRef.ID, TypeSpec.ID};
- TableSet[_HasConstant] =
- new int[] {FieldDef.ID, ParamDef.ID, PropertyDef.ID};
- TableSet[_HasCustomAttribute] =
- new int[] {MethodDef.ID, FieldDef.ID, TypeRef.ID, TypeDef.ID,
- ParamDef.ID, InterfaceImpl.ID, MemberRef.ID, ModuleDef.ID,
- -1, PropertyDef.ID, EventDef.ID, -1, ModuleRef.ID,
- TypeSpec.ID, AssemblyDef.ID, AssemblyRef.ID,
- FileDef.ID, ExportedType.ID, ManifestResource.ID};
- TableSet[_HasFieldMarshal] =
- new int[] {FieldDef.ID, ParamDef.ID};
- TableSet[_HasDeclSecurity] =
- new int[] {TypeDef.ID, MethodDef.ID, AssemblyDef.ID};
- TableSet[_MemberRefParent] =
- new int[] {-1, TypeRef.ID, ModuleRef.ID, MethodDef.ID, TypeSpec.ID};
- TableSet[_HasSemantics] =
- new int[] {EventDef.ID, PropertyDef.ID};
- TableSet[_MethodDefOrRef] =
- new int[] {MethodDef.ID, MemberRef.ID};
- TableSet[_MemberForwarded] =
- new int[] {FieldDef.ID, MethodDef.ID};
- TableSet[_Implementation] =
- new int[] {FileDef.ID, AssemblyRef.ID, ExportedType.ID};
- TableSet[_CustomAttributeType] =
- new int[] {-1, -1, MethodDef.ID, MemberRef.ID, -1};
- TableSet[_ResolutionScope] =
- new int[] {ModuleDef.ID, ModuleRef.ID, AssemblyRef.ID, TypeRef.ID};
- TableSet[_TypeOrMethodDef] =
- new int[]{TypeDef.ID, MethodDef.ID};
- }
-
- public static final int[] NoBits =
- new int[]{2, 2, 5, 1, 2, 3, 1, 1, 1, 2, 3, 2, 1};
-
- public static int getMask(int tableSetId) {
- return (1 << NoBits[tableSetId]) - 1;
- }
-
- public static int getTableId(int tableSet, int index) {
- return TableSet[tableSet][index & getMask(tableSet)];
- }
-
- public static int getTableIndex(int tableSet, int index) {
- return index >> NoBits[tableSet];
- }
-
- public static int encodeIndex(int index, int tableSetId, int tableId) {
- int[] tableSet = TableSet[tableSetId];
- for (int i = 0; i < tableSet.length; i++) {
- if (tableSet[i] == tableId)
- return (index << NoBits[tableSetId]) | i;
- }
- throw new RuntimeException("Cannot find table #" + tableId +
- " in table set #" + tableSetId);
- }
-
- //##########################################################################
-
- private static final String [] tableName = {
- "Module", "TypeRef", "TypeDef", " FieldTrans",
- "Field", "MethodTrans", "Method", "",
- "Param", "InterfaceImpl", "MemberRef", "Constant",
- "CustomAttribute", "FieldMarshal", "DeclSecurity","ClassLayout",
- "FieldLayout", "StandAloneSig", "EventMap", "",
- "Event", "PropertyMap", "", "Property",
- "MethodSemantics", "MethodImpl", "ModuleRef", "TypeSpec",
- "ImplMap", "FieldRVA", "", "",
- "Assembly", "AssemblyProcessor","AssemblyOS", "AssemblyRef",
- "AssemblyRefProcessor","AssemblyRefOS", "File", "ExportedType",
- "ManifestResource", "NestedClass", "GenericParam", "MethodSpec",
- "GenericParamConstraint", "", "", "",
- "", "", "", "",
- "", "", "", "",//0x30-0x37
- "", "", "", "",
- "", "", "", "" //0x37-0x3f
- };
-
- /** Creates a table with the given id and number of rows.
- */
- public static Table newTable(PEFile file, int id, int rows) {
- Table table = null;
- switch(id) {
- case ModuleDef.ID: table = new ModuleDef(file, rows); break;
- case TypeRef.ID: table = new TypeRef(file, rows); break;
- case TypeDef.ID: table = new TypeDef(file, rows); break;
- case FieldTrans.ID: table = new FieldTrans(file, rows); break;
- case FieldDef.ID: table = new FieldDef(file, rows); break;
- case MethodTrans.ID: table = new MethodTrans(file, rows); break;
- case MethodDef.ID: table = new MethodDef(file, rows); break;
- case ParamDef.ID: table = new ParamDef(file, rows); break;
- case InterfaceImpl.ID: table = new InterfaceImpl(file, rows); break;
- case MemberRef.ID: table = new MemberRef(file, rows); break;
- case Constant.ID: table = new Constant(file, rows); break;
- case CustomAttribute.ID: table = new CustomAttribute(file, rows); break;
- case FieldMarshal.ID: table = new FieldMarshal(file, rows); break;
- case DeclSecurity.ID: table = new DeclSecurity(file, rows); break;
- case ClassLayout.ID: table = new ClassLayout(file, rows); break;
- case FieldLayout.ID: table = new FieldLayout(file, rows); break;
- case StandAloneSig.ID: table = new StandAloneSig(file, rows); break;
- case EventMap.ID: table = new EventMap(file, rows); break;
- case EventDef.ID: table = new EventDef(file, rows); break;
- case PropertyMap.ID: table = new PropertyMap(file, rows); break;
- case PropertyDef.ID: table = new PropertyDef(file, rows); break;
- case MethodSemantics.ID: table = new MethodSemantics(file, rows); break;
- case MethodImpl.ID: table = new MethodImpl(file, rows); break;
- case ModuleRef.ID: table = new ModuleRef(file, rows); break;
- case TypeSpec.ID: table = new TypeSpec(file, rows); break;
- case ImplMap.ID: table = new ImplMap(file, rows); break;
- case FieldRVA.ID: table = new FieldRVA(file, rows); break;
- case AssemblyDef.ID: table = new AssemblyDef(file, rows); break;
- case AssemblyProcessor.ID: table = new AssemblyProcessor(file, rows); break;
- case AssemblyOS.ID: table = new AssemblyOS(file, rows); break;
- case AssemblyRef.ID: table = new AssemblyRef(file, rows); break;
- case AssemblyRefProcessor.ID:
- table = new AssemblyRefProcessor(file, rows); break;
- case AssemblyRefOS.ID: table = new AssemblyRefOS(file, rows); break;
- case FileDef.ID: table = new FileDef(file, rows); break;
- case ExportedType.ID: table = new ExportedType(file, rows); break;
- case ManifestResource.ID: table = new ManifestResource(file, rows); break;
- case NestedClass.ID: table = new NestedClass(file, rows); break;
- case GenericParam.ID:
- table = new GenericParam(file, rows);
- break;
- case MethodSpec.ID:
- table = new MethodSpec(file, rows);
- break;
- case GenericParamConstraint.ID:
- table = new GenericParamConstraint(file, rows);
- break;
- default:
- table = new Empty(id);
- }
-// System.out.println("created table " + table.getName() + " with "
-// + table.rows + " rows");
- return table;
- }
-
-
- //##########################################################################
- // public fields
-
- /** Number of rows in the table. */
- public final int rows;
-
- /** Table ID as specified in Partition II. */
- public final int id;
-
- /** The file to which the table belongs. */
- protected final PEFile file;
-
- /** Memory mapped buffer wrapping the table. */
- protected ByteBuffer buffer;
-
- /**
- * specified wheter a new memory-mapped byte buffer should be created
- * for this table.
- */
- protected boolean newMapping = false;
-
- /** Tells wheter the table is indexed by 2-byte (short) integer
- * or by 4-byte integer. */
- public final boolean isShort;
-
- private int rowSize = -1;
-
- // the starting position of the table relative to the beginning of the file
- private long start = -1;
-
- // the number of the row who can be accessed via the fields of the table
- private int currentRow = 0;
-
- //##########################################################################
-
- protected Table(PEFile file, int id, int rows) {
- this.file = file;
- this.id = id;
- this.rows = rows;//file.readInt();
- this.isShort = rows < (1 << 16);
-// assert ((1L << id) & VALID_TABLES_MASK) != 0
-// : "Table does not have a vaid ID: " + byte2hex(id);
- }
-
- /**
- * Additional table initialization.
- * @return the starting position of the next table in the stream.
- */
- public final long init(long start) {
- if (rows < 1)
- return start;
- if (this.start == -1)
- this.start = start;
- else throw new RuntimeException
- ("Cannot re-initialize table \'" + getTableName() + "\'");
- rowSize = getRowSize();
- int size = rows * rowSize();
- buffer = this.newMapping ? file.mapBuffer(start, size)
- : file.getBuffer(start, size);
- return start + size;
- }
-
-
- public final String getTableName() {
- return 0 <= id && id < MAX_NUMBER ? tableName[id] : "<NoTable>";
- }
-
- /**
- * @return the size of the row in bytes
- */
- public final int rowSize() {
- return rowSize;
- }
-
- /**
- * if the underlying buffer is memory-mapped, load its contents into memory
- */
- public void load() {
- if (buffer instanceof MappedByteBuffer)
- ((MappedByteBuffer)buffer).load();
- }
-
- /***/
- public final int readByte() {
- return (buffer.get() + 0x100) & 0xff;
- }
-
- /***/
- public final int readShort() {
- return (buffer.getShort() + 0x10000) & 0xffff;
- }
-
- /***/
- public final int readInt() {
- return buffer.getInt();
- }
-
- /***/
- public final int readStringIndex() {
- return file.StringIsShort ? readShort() : readInt();
- }
-
- /***/
- public final int readBlobIndex() {
- return file.BlobIsShort ? readShort() : readInt();
- }
-
- /***/
- public final int readGUIDIndex() {
- return file.GUIDIsShort ? readShort() : readInt();
- }
-
- /***/
- public final int readTableIndex(int tableId) {
- return file.getTable(tableId).isShort ? readShort() : readInt();
- }
-
- /***/
- public final int readTableSetIndex(int tableSetId) {
- return file.indexSize[tableSetId] == 2 ? readShort() : readInt();
- }
-
- /** Read the specified row and populate the fields of the instance. */
- public final void readRow(int row) {
- seekRow(row);
- int lastSeek = buffer.position();
- populateFields();
- int rowSizeRead = (int) (buffer.position() - lastSeek);
- if (rowSizeRead != rowSize())
- throw new RuntimeException("Table ID=0x" + PEFile.byte2hex(id) +
- ": read row size = " + rowSizeRead +
- "; expected row size = " + rowSize());
- currentRow = row;
- }
-
- /** Seeks in the file the position of the specified row. */
- protected final void seekRow(int row) {
- assert row > 0 && row <= rows
- : "Index " + row + " is not within the table with #rows = " + rows;
- buffer.position((row - 1)* rowSize());
- }
-
- public final int currentRow() { return currentRow; }
-
- public final void nextRow() { readRow(currentRow() + 1); }
-
- //##########################################################################
- // abstract members
-
- /** Assigns values to the fields of the class. */
- protected abstract void populateFields();
-
- /** Returns the size of a row in bytes. */
- protected abstract int getRowSize();
-
- //##########################################################################
- // a table with 0 rows
-
- private static final class Empty extends Table {
- public Empty(int id) {
- super(null, id, 0);
- }
- protected int getRowSize() { return 0; }
- protected void populateFields() {
- throw new RuntimeException("Table 0x" + PEFile.byte2hex(id));
- }
- }
-
- //##########################################################################
- // table Module; ID=0x00; p115, 21.27
-
- public static final class ModuleDef extends Table {
- public static final int ID = 0x00;
-
- /** 2-byte value; reserved - shall be 0. */
- public int Generation;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #GUID; used to distinguish between
- * two version of the same module. */
- public int Mvid;
-
- /** Index into #GUID; reserved - shall be 0. */
- public int EncId;
-
- /** Index into #GUID; reseved - shall be 0. */
- public int EncBaseId;
-
- public ModuleDef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Generation = readShort();
- Name = readStringIndex();
- Mvid = readGUIDIndex();
- EncId = readGUIDIndex();
- EncBaseId = readGUIDIndex();
- }
-
- protected int getRowSize() {
- return 2 + file.getStringIndexSize() + 3*file.getGUIDIndexSize();
- }
-
- public String getName() {
- return file.getString(Name);
- }
-
- } // class ModuleDef
-
- //##########################################################################
- // table TypeRef; ID=0x01; p125, 21.35
-
- public static final class TypeRef extends Table {
- public static final int ID = 0x1;
-
- /** A ResolutionScope coded index. */
- public int ResolutionScope;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #String. */
- public int Namespace;
-
- public TypeRef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- ResolutionScope = readTableSetIndex(_ResolutionScope);
- Name = readStringIndex();
- Namespace = readStringIndex();
- }
-
- protected int getRowSize() {
- return file.getTableSetIndexSize(_ResolutionScope) +
- 2 * file.getStringIndexSize();
- }
-
- public String getFullName() {
- String namespace = file.getString(Namespace);
- return namespace.length() == 0 ? file.getString(Name)
- : namespace + "." + file.getString(Name);
- }
-
- } // class TypeRef
-
- //##########################################################################
- // table TypeDef; ID=0x02; p120, 21.34
-
- public static final class TypeDef extends Table {
- public static final int ID = 0x02;
-
- /** 4-byte bitmask of type TypeAttributes (22.1.14). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #String. */
- public int Namespace;
-
- /** TypeDefOrRef coded index. */
- public int Extends;
-
- /** Index into Field table.
- */
- public int FieldList;
-
- /** Index into Method table. */
- public int MethodList;
-
-
- public TypeDef(PEFile file, int rows) {
- super(file, ID, rows);
- this.newMapping = true;
- }
-
- public String getFullName() {
- String namespace = file.getString(Namespace);
- return namespace.length() == 0 ? file.getString(Name)
- : namespace + "." + file.getString(Name);
- }
-
- protected void populateFields() {
- Flags = readInt();
- Name = readStringIndex();
- Namespace = readStringIndex();
- Extends = readTableSetIndex(_TypeDefOrRef);
- FieldList = readTableIndex(FieldDef.ID);
- MethodList = readTableIndex(MethodDef.ID);
- }
-
- protected int getRowSize() {
- return 4 + 2*file.getStringIndexSize() +
- file.getTableSetIndexSize(_TypeDefOrRef) +
- file.getTableIndexSize(FieldDef.ID) +
- file.getTableIndexSize(MethodDef.ID);
- }
-
- } // class TypeDef
-
- //##########################################################################
- // Table FieldTrans; ID=0x03; undocumented
-
- /**
- * Undocumented table. Appears to be used for translating the Field entry
- * in the TypeDef(0x02) table into the real entry in the Fields(0x06) table
- */
- public static final class FieldTrans extends Table {
- public static final int ID = 0x03;
-
- public int Field;
-
- public FieldTrans(PEFile file, int rows) {
- super(file, ID, rows);
- newMapping = true;
- }
-
- protected void populateFields() {
- Field = readTableIndex(FieldDef.ID);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(FieldDef.ID);
- }
-
- }
-
- //##########################################################################
- // table Field; ID=0x04; p102, 21.15
-
- public static final class FieldDef extends Table {
- public static final int ID = 0x04;
-
- /** 2-byte bitmask of type FieldAttributes (22.1.5). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #Blob. */
- public int Signature;
-
- public FieldDef(PEFile file, int rows) {
- super(file, ID, rows);
- newMapping = true;
- }
-
- protected void populateFields() {
- Flags = readShort();
- Name = readStringIndex();
- Signature = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 2 + file.getStringIndexSize() + file.getBlobIndexSize();
- }
-
- public String getName() { return file.getString(Name); }
-
- public Sig getSignature() { return file.getSignature(Signature); }
-
- } //class FieldDef
-
- //##########################################################################
- // Table MethodTrans; ID=0x05; undocumented
-
- /**
- * Undocumented table. Appears to be used for translating the Method entry
- * in the TypeDef(0x02) table into the real entry in the Methods(0x06) table
- */
- public static final class MethodTrans extends Table {
- public static final int ID = 0x05;
-
- public int Method;
-
- public MethodTrans(PEFile file, int rows) {
- super(file, ID, rows);
- newMapping = true;
- }
-
- protected void populateFields() {
- Method = readTableIndex(FieldDef.ID);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(MethodDef.ID);
- }
-
- }
-
- //##########################################################################
- // table MethodDef; ID=0x06; p110, 21.24
-
- public static final class MethodDef extends Table {
- public static final int ID = 0x06;
-
- /** 4-byte constant. */
- public int RVA;
-
- /** 2-byte bitmask of type MethodImplAttributes (22.1.10). */
- public int ImplFlags;
-
- /** 2-byte bitmask of type MethodAttributes (22.1.9). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #Blob. */
- public int Signature;
-
- /** Index into Param Table. */
- public int ParamList;
-
- public MethodDef(PEFile file, int rows) {
- super(file, ID, rows);
- newMapping = true;
- }
-
- protected void populateFields() {
- RVA = readInt();
- ImplFlags = readShort();
- Flags = readShort();
- Name = readStringIndex();
- Signature = readBlobIndex();
- ParamList = readTableIndex(ParamDef.ID);
- }
-
- protected int getRowSize() {
- return 8 + file.getStringIndexSize() + file.getBlobIndexSize() +
- file.getTableIndexSize(ParamDef.ID);
- }
-
- public String getName() { return file.getString(Name); }
-
- public Sig getSignature() { return file.getSignature(Signature); }
- } // class Method
-
- //##########################################################################
- // table Param; ID=0x08; p116, 21.30
-
- public static final class ParamDef extends Table {
- public static final int ID = 0x08;
-
- /** 2-byte bitmask of type ParamAttributes (22.1.12). */
- public int Flags;
-
- /** 2-byte constant. */
- public int Sequence;
-
- /** Index into #String. */
- public int Name;
-
- public ParamDef(PEFile file, int rows) {
- super(file, ID, rows);
- newMapping = true;
- }
-
- protected void populateFields() {
- Flags = readShort();
- Sequence = readShort();
- Name = readStringIndex();
- }
-
- protected int getRowSize() { return 4 + file.getStringIndexSize(); }
-
- public String getName() { return file.getString(Name); }
-
- } // class Param
-
- //##########################################################################
- // table InterfaceImpl, ID=0x09; p107, 21.21
-
- public static final class InterfaceImpl extends Table {
- public static final int ID = 0x09;
-
- /** Index into TypeDef table. */
- public int Class;
-
- /** Index into TypeDefOrRef table set. */
- public int Interface;
-
- public InterfaceImpl(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Class = readTableIndex(TypeDef.ID);
- Interface = readTableSetIndex(_TypeDefOrRef);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(TypeDef.ID) +
- file.getTableSetIndexSize(_TypeDefOrRef);
- }
-
- /** finds the index of the first entry
- * @param targetIndex - index in the TypeDef table - the type to look for
- * @return the index of the first interface for the given type;
- * 0 if the type doesn't implement any interfaces
- */
-
- // binary search implementation
-// public int findType(int targetIndex) {
-// int l = 1, h = rows;
-// int classIndex;
-// while (l <= h) {
-// int mid = (l + h) / 2;
-// seekRow(mid);
-// classIndex = readTableIndex(TypeDef.ID);
-// if (targetIndex <= classIndex) h = mid - 1;
-// else l = mid + 1;
-// }
-// return (targetIndex == classIndex) ? h : 0;
-// }
-
- //linear search implementation
- public int findType(int targetIndex) {
- for (int i = 1; i <= rows; i++) {
- seekRow(i);
- if (targetIndex == readTableIndex(TypeDef.ID))
- return i;
- }
- return 0;
- }
-
- } // class InterfaceImpl
-
- //##########################################################################
- // table MemberRef; ID=0x0a; p109, 21.23
-
- public static final class MemberRef extends Table {
- public static final int ID = 0x0a;
-
- /** Index into MemberRefParent table set. */
- public int Class;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #Blob. */
- public int Signature;
-
- public MemberRef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Class = readTableSetIndex(_MemberRefParent);
- Name = readStringIndex();
- Signature = readBlobIndex();
- }
-
- protected int getRowSize() {
- return file.getTableSetIndexSize(_MemberRefParent) +
- file.getStringIndexSize() + file.getBlobIndexSize();
- }
-
- public String getName() {
- return file.getString(Name);
- }
-
- public Sig getSignature() {
- return file.getSignature(Signature);
- }
-
- } // class MemberRef
-
- //##########################################################################
- // table Constant; ID=0x0b; p95, 21.9
-
- public static final class Constant extends Table {
- public static final int ID = 0x0b;
-
- /** 1-byte constant followed by 1-byte padding 0 (see 22.1.15). */
- public int Type;
-
- /** Index into HasConst table set. */
- public int Parent;
-
- /** Index into #Blob. */
- public int Value;
-
- public Constant(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Type = readShort();
- Parent = readTableSetIndex(_HasConstant);
- Value = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 2 + file.getTableSetIndexSize(_HasConstant) +
- file.getBlobIndexSize();
- }
-
- public Object getValue() {
- if (Type == Signature.ELEMENT_TYPE_CLASS)
- return null;
- return file.Blob.getConstant(Type, Value);
- }
-
-
- } // class Constant
-
- //##########################################################################
- // table CustomAttribute; ID=0x0c; p95, 21.10
-
- public static final class CustomAttribute extends Table {
- public static final int ID = 0x0c;
-
- /** Index into any metadata table, except the CustomAttribute itself;
- * more precisely - index into HasCustomAttribute table set.
- */
- public int Parent;
-
- /** Index into the CustomAttributeType table set. */
- public int Type;
-
- /** Index into #Blob. */
- public int Value;
-
- public CustomAttribute(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Parent = readTableSetIndex(_HasCustomAttribute);
- Type = readTableSetIndex(_CustomAttributeType);
- Value = readBlobIndex();
- }
-
- protected int getRowSize() {
- return file.getTableSetIndexSize(_HasCustomAttribute) +
- file.getTableSetIndexSize(_CustomAttributeType) +
- file.getBlobIndexSize();
- }
-
- public byte[] getValue() {
- return Value == 0 ? null : file.getBlob(Value);
- }
- } // class CustomAttribute
-
- //##########################################################################
- // table FieldMarshal; ID=0x0d; p105, 21.17
-
- public static final class FieldMarshal extends Table {
- public static final int ID = 0x0d;
-
- /** Index into HasFieldMarshal table set. */
- public int Parent;
-
- /** Index into #Blob. */
- public int NativeType;
-
- public FieldMarshal(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Parent = readTableSetIndex(_HasFieldMarshal);
- NativeType = readBlobIndex();
- }
-
- protected int getRowSize() {
- return file.getTableSetIndexSize(_HasFieldMarshal) +
- file.getBlobIndexSize();
- }
-
- } // class FieldMarshal
-
- //##########################################################################
- // table DeclSecurity; ID=0x0e; p97, 21.11
-
- public static final class DeclSecurity extends Table {
- public static final int ID = 0x0e;
-
- /** 2-byte value. */
- public int Action;
-
- /** Index into HasDeclSecurity table set. */
- public int Parent;
-
- /** Index into #Blob. */
- public int PermissionSet;
-
- public DeclSecurity(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Action = readShort();
- Parent = readTableSetIndex(_HasDeclSecurity);
- PermissionSet = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 2 + file.getTableSetIndexSize(_HasDeclSecurity) +
- file.getBlobIndexSize();
- }
-
- } // class DeclSecurity
-
- //##########################################################################
- // table ClassLayout; ID=0x0f, p92, 21.8
-
- public static final class ClassLayout extends Table {
- public static final int ID = 0x0f;
-
- /** 2-byte constant. */
- public int PackingSize;
-
- /** 4-byte constant. */
- public int ClassSize;
-
- /** Index into TypeDef table. */
- public int Parent;
-
- public ClassLayout(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- PackingSize = readShort();
- ClassSize = readInt();
- Parent = readTableIndex(TypeDef.ID);
- }
-
- protected int getRowSize() {
- return 6 + file.getTableIndexSize(TypeDef.ID);
- }
-
- } // class ClassLayout
-
- //##########################################################################
- // table FieldLayout; ID=0x10; p104, 21.16
-
- public static final class FieldLayout extends Table {
- public static final int ID = 0x10;
-
- /** 4-byte constant. */
- public int Offset;
-
- /** Index into the Field table. */
- public int Field;
-
- public FieldLayout(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Offset = readInt();
- Field = readTableIndex(FieldDef.ID);
- }
-
- protected int getRowSize() {
- return 4 + file.getTableIndexSize(FieldDef.ID);
- }
-
- } // class FieldLayout
-
- //##########################################################################
- // table StandAloneSig; ID=0x11; p119, 21.33
-
- public static final class StandAloneSig extends Table {
- public static final int ID = 0x11;
-
- /** Index into #Blob. */
- public int Signature;
-
- public StandAloneSig(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Signature = readBlobIndex();
- }
-
- protected int getRowSize() { return file.getBlobIndexSize(); }
-
- } // class StandAloneSig
-
- //##########################################################################
- // table EventMap; ID=0x12; p99, 21.12
-
- public static final class EventMap extends Table {
- public static final int ID = 0x12;
-
- /** Index into the TypeDef table. */
- public int Parent;
-
- /** Index into the Event table. */
- public int EventList;
-
- public EventMap(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Parent = readTableIndex(TypeDef.ID);
- EventList = readTableIndex(EventDef.ID);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(TypeDef.ID) +
- file.getTableIndexSize(EventDef.ID);
- }
-
- } // class EventMap
-
- //##########################################################################
- // table Event; ID=0x14; p99, 21.13
-
- public static final class EventDef extends Table {
- public static final int ID = 0x14;
-
- /** 2-byte bitmask of type EventAttribute (22.1.4). */
- public int EventFlags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into TypeDefOrRef table set. [This corresponds to the Type
- * of the event; it is not the Type that owns the event]
- */
- public int EventType;
-
- public EventDef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- EventFlags = readShort();
- Name = readStringIndex();
- EventType = readTableSetIndex(_TypeDefOrRef);
- }
-
- protected int getRowSize() {
- return 2 + file.getStringIndexSize() +
- file.getTableSetIndexSize(_TypeDefOrRef);
- }
-
- public String getName() { return file.getString(Name); }
-
- } // class EventDef
-
- //##########################################################################
- // table PropertyMap; ID=0x15; p119, 21.32
-
- public static final class PropertyMap extends Table {
- public static final int ID = 0x15;
-
- /** Index into the TypeDef table. */
- public int Parent;
-
- /** Index into the Property table. */
- public int PropertyList;
-
- public PropertyMap(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Parent = readTableIndex(TypeDef.ID);
- PropertyList = readTableIndex(PropertyDef.ID);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(TypeDef.ID) +
- file.getTableIndexSize(PropertyDef.ID);
- }
-
- } // class PropertyMap
-
- //##########################################################################
- // table Property; ID=0x17; p117, 21.31
-
- public static final class PropertyDef extends Table {
- public static final int ID = 0x17;
-
- /** 2-byte bitmask of type PropertyAttributes (22.1.13). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #Blob. (Indexes the signature in the #Blob) */
- public int Type;
-
- public PropertyDef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Flags = readShort();
- Name = readStringIndex();
- Type = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 2 + file.getStringIndexSize() +
- file.getBlobIndexSize();
- }
-
- public String getName() { return file.getString(Name); }
-
- public Sig getSignature() { return file.getSignature(Type); }
-
- } // class PropertyDef
-
- //##########################################################################
- // table MethodSemantics; ID=0x18; p114, 21.26
-
- public static final class MethodSemantics extends Table {
- public static final int ID = 0x18;
-
- /** 2-byte bitmaks of type MethodSemanticsAttribute (22.1.11). */
- public int Semantics;
-
- /** Index into the Method table. */
- public int Method;
-
- /** Index into Event or Property table (HasSemantics table set). */
- public int Association;
-
- public MethodSemantics(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Semantics = readShort();
- Method = readTableIndex(MethodDef.ID);
- Association = readTableSetIndex(_HasSemantics);
- }
-
- protected int getRowSize() {
- return 2 + file.getTableIndexSize(MethodDef.ID) +
- file.getTableSetIndexSize(_HasSemantics);
- }
-
- public boolean isGetter() { return (Semantics & Getter) != 0; }
- public boolean isSetter() { return (Semantics & Setter) != 0; }
- public boolean isOther() { return (Semantics & Other) != 0; }
- public boolean isAddOn() { return (Semantics & AddOn) != 0; }
- public boolean isRemoveOn() { return (Semantics & RemoveOn) != 0; }
- public boolean isFire() { return (Semantics & Fire) != 0; }
-
- private static final short Setter = (short)0x0001;
- private static final short Getter = (short)0x0002;
- private static final short Other = (short)0x0004;
- private static final short AddOn = (short)0x0008;
- private static final short RemoveOn = (short)0x0010;
- private static final short Fire = (short)0x0020;
-
- } // class MethodSemantics
-
-
- //##########################################################################
- // table MethodImpl; ID=0x19; p113, 21.25
-
- public static final class MethodImpl extends Table {
- public static final int ID = 0x19;
-
- /** Index into the TypeDef table. */
- public int Class;
-
- /** Index into MethodDefOrRef table set. */
- public int MethodBody;
-
- /** Index into MethodDefOrRef table set. */
- public int MethodDeclaration;
-
- public MethodImpl(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Class = readTableIndex(TypeDef.ID);
- MethodBody = readTableSetIndex(_MethodDefOrRef);
- MethodDeclaration = readTableSetIndex(_MethodDefOrRef);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(TypeDef.ID) +
- 2 * file.getTableSetIndexSize(_MethodDefOrRef);
- }
-
- } // class MethodImpl
-
- //##########################################################################
- // table ModuleRef; ID=0x1a; p116, 21.28
-
- public static final class ModuleRef extends Table {
- public static final int ID = 0x1a;
-
- /** Index into #String. */
- public int Name;
-
- public ModuleRef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Name = readStringIndex();
- }
-
- protected int getRowSize() { return file.getStringIndexSize(); }
-
- public String getName() { return file.getString(Name); }
-
- } // class ModuleRef
-
- //##########################################################################
- // table TypeSpec; ID=0x1b; p126, 21.36
-
- public static final class TypeSpec extends Table {
- public static final int ID = 0x1b;
-
- /** Index into #Blob, where the blob is formatted
- * as specified in 22.2.15
- */
- public int Signature;
-
- public TypeSpec(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Signature = readBlobIndex();
- }
-
- protected int getRowSize() { return file.getBlobIndexSize(); }
-
- public Sig getSignature() { return file.getSignature(Signature); }
- } // class TypeSpec
-
- //##########################################################################
- // table ImplMap; ID=0x1c; p107, 21.20
-
- public static final class ImplMap extends Table {
- public static final int ID = 0x1c;
-
- /** 2-byte bitmask of type PInvokeAttributes (22.1.7). */
- public int MappingFlags;
-
- /** Index into MemberForwarded table set. */
- public int MemberForwarded;
-
- /** Index into #String. */
- public int ImportName;
-
- /** Index into the ModuleRef table. */
- public int ImportScope;
-
- public ImplMap(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- MappingFlags = readShort();
- MemberForwarded = readTableSetIndex(_MemberForwarded);
- ImportName = readStringIndex();
- ImportScope = readTableIndex(ModuleRef.ID);
- }
-
- protected int getRowSize() {
- return 2 + file.getTableSetIndexSize(_MemberForwarded) +
- file.getStringIndexSize() +
- file.getTableIndexSize(ModuleRef.ID);
- }
-
- } // class ImplMap
-
- //##########################################################################
- // table FieldRVA; ID=0x1d; p106, 21.18
-
- public static final class FieldRVA extends Table {
- public static final int ID = 0x1d;
-
- /** 4-byte constant. */
- public int RVA;
-
- /** Index into the Field table. */
- public int Field;
-
- public FieldRVA(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- RVA = readInt();
- Field = readTableIndex(Table.FieldDef.ID);
- }
-
- protected int getRowSize() {
- return 4 + file.getTableIndexSize(FieldDef.ID);
- }
-
- }
-
- //##########################################################################
- // table Assembly; ID=0x20; p90, 21.2
-
- public static final class AssemblyDef extends Table {
- public static final int ID = 0x20;
-
- /** 4-byte constatnt of type AssemblyHashAlgorithm, clause 22.1.1 */
- public int HashAlgId;
-
- /** 2-byte constant */
- public int MajorVersion;
-
- /** 2-byte constant */
- public int MinorVersion;
-
- /** 2-byte constant */
- public int BuildNumber;
-
- /** 2-byte constant */
- public int RevisionNumber;
-
- /** 4-byte constant */
- public int Flags;
-
- /** index into #Blob */
- public int PublicKey;
-
- /** index into #String */
- public int Name;
-
- /** index into #String */
- public int Culture;
-
- public AssemblyDef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- HashAlgId = readInt();
- MajorVersion = readShort();
- MinorVersion = readShort();
- BuildNumber = readShort();
- RevisionNumber = readShort();
- Flags = readInt();
- PublicKey = readBlobIndex();
- Name = readStringIndex();
- Culture = readStringIndex();
- }
-
- protected int getRowSize() {
- return 16 + file.getBlobIndexSize() + 2*file.getStringIndexSize();
- }
-
- } // class AssemblyDef
-
- //##########################################################################
- // table AssemblyProcessor; ID=0x21; p91, 21.4
-
- public static final class AssemblyProcessor extends Table {
- public static final int ID = 0x21;
-
- /** 4-byte constant. */
- public int Processor;
-
- public AssemblyProcessor(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Processor = readInt();
- }
-
- protected int getRowSize() { return 4; }
-
- }
-
- //##########################################################################
- // table AssemblyOS; ID = 0x22; p90, 21.3
-
- public static final class AssemblyOS extends Table {
- public static final int ID = 0x22;
-
- /** 4-byte constant. */
- public int OSPlatformID;
-
- /** 4-byte constant. */
- public int OSMajorVersion;
-
- /** 4-byte constant. */
- public int OSMinorVersion;
-
- public AssemblyOS(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- OSPlatformID = readInt();
- OSMajorVersion = readInt();
- OSMinorVersion = readInt();
- }
-
- protected int getRowSize() { return 12; }
-
- }
-
- //##########################################################################
- // table AssemblyRef; ID = 0x23; pp91, 21.5
-
- public static final class AssemblyRef extends Table {
- public static final int ID = 0x23;
-
- /** 2-byte constant. */
- public int MajorVersion;
-
- /** 2-byte constant. */
- public int MinorVersion;
-
- /** 2-byte constant. */
- public int BuildNumber;
-
- /** 2-byte constant. */
- public int RevisionNumber;
-
- /** 4-byte bitmask of type AssemblyFlags (22.1.2). */
- public int Flags;
-
- /** index into #Blob. */
- public int PublicKeyOrToken;
-
- /** index into #String. */
- public int Name;
-
- /** index into #String. */
- public int Culture;
-
- /** index into #Blob. */
- public int HashValue;
-
- public AssemblyRef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- MajorVersion = readShort();
- MinorVersion = readShort();
- BuildNumber = readShort();
- RevisionNumber = readShort();
- Flags = readInt();
- PublicKeyOrToken = readBlobIndex();
- Name = readStringIndex();
- Culture = readStringIndex();
- HashValue = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 12 + 2*file.getBlobIndexSize() + 2*file.getStringIndexSize();
- }
-
- public String getName() { return file.getString(Name); }
- }
-
- //##########################################################################
- // table AssemblyRefProcessor; ID=0x24; p92, 21.7
-
- public static final class AssemblyRefProcessor extends Table {
- public static final int ID = 0x24;
-
- /** 4-byte constant. */
- public int Processor;
-
- /** Index into the AssemblyRef table. */
- public int AssemblyRef;
-
- public AssemblyRefProcessor(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Processor = readInt();
- AssemblyRef = readTableIndex(Table.AssemblyRef.ID);
- }
-
- protected int getRowSize() {
- return 4 + file.getTableIndexSize(Table.AssemblyRef.ID);
- }
-
- } // class AssemblyRefProcessor
-
- //##########################################################################
- // table AssemblyRefOS; ID=0x25; p92, 21.6
-
- public static final class AssemblyRefOS extends Table {
- public static final int ID = 0x25;
-
- /** 4-byte constant. */
- public int OSPlatformId;
-
- /** 4-byte constant. */
- public int OSMajorVersion;
-
- /** 4-byte constant. */
- public int OSMinorVersion;
-
- /** Index into the AssemblyRef table. */
- public int AssemblyRef;
-
- public AssemblyRefOS(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- OSPlatformId = readInt();
- OSMajorVersion = readInt();
- OSMinorVersion = readInt();
- AssemblyRef = readTableIndex(Table.AssemblyRef.ID);
- }
-
- protected int getRowSize() {
- return 12 + file.getTableIndexSize(Table.AssemblyRef.ID);
- }
-
- } // class AssemblyRefOS
-
- //##########################################################################
- // table File; ID=0x26; p106, 21.19
-
- public static final class FileDef extends Table {
- public static final int ID = 0x26;
-
- /** 4-byte bitmask of type FileAttributes (22.1.6). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into #Blob. */
- public int HashValue;
-
- public FileDef(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Flags = readInt();
- Name = readStringIndex();
- HashValue = readBlobIndex();
- }
-
- protected int getRowSize() {
- return 4 + file.getStringIndexSize() + file.getBlobIndexSize();
- }
-
- public String getName() {
- return file.getString(Name);
- }
-
- } // class FileDef
-
- //##########################################################################
- // table ExportedType; ID=0x27; p100, 21.14
-
- public static final class ExportedType extends Table {
- public static final int ID = 0x27;
-
- /** 4-byte bitmask of type TypeAttribute (22.1.6). */
- public int Flags;
-
- /** 4-byte index into a TypeDef table of
- * another module in this assembly.
- */
- public int TypeDefId;
-
- /** Index into #String. */
- public int TypeName;
-
- /** Index into #Stream. */
- public int TypeNamespace;
-
- /** Index into one of two tables as follows:
- * - 'File' table, where that entry says which module
- * in the current assembly holds the TypeDef
- * - 'ExportedType' table, where that entry is
- * the enclosing Type of the current nested Type
- */
- public int Implementation;
-
- public ExportedType(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Flags = readInt();
- TypeDefId = readInt();
- TypeName = readStringIndex();
- TypeNamespace = readStringIndex();
- Implementation = readTableSetIndex(_Implementation);
- }
-
- protected int getRowSize() {
- return 8 + 2*file.getStringIndexSize() +
- file.getTableSetIndexSize(_Implementation);
- }
-
- public String getFullName() {
- String namespace = file.getString(TypeNamespace);
- return namespace.length() == 0 ? file.getString(TypeName)
- : namespace + "." + file.getString(TypeName);
- }
-
- } // class ExportedType
-
- //##########################################################################
- // table ManifestResource; ID=0x28; p108, 21.22
-
- public static final class ManifestResource extends Table {
- public static final int ID = 0x28;
-
- /** 4-byte constant. */
- public int Offset;
-
- /** 4-byte bitmask of type ManifestResourceAttributes (22.1.8). */
- public int Flags;
-
- /** Index into #String. */
- public int Name;
-
- /** Index into the Implementation table set. */
- public int Implementation;
-
- public ManifestResource(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- Offset = readInt();
- Flags = readInt();
- Name = readStringIndex();
- Implementation = readTableSetIndex(_Implementation);
- }
-
- protected int getRowSize() {
- return 8 + file.getStringIndexSize() +
- file.getTableSetIndexSize(_Implementation);
- }
-
- } // class ManifestResource
-
- //##########################################################################
- // table NestedClass; ID=0x29; p116, 21.29
-
- public static final class NestedClass extends Table {
- public static final int ID = 0x29;
-
- /** Index into the TypeDef table. */
- public int NestedClass;
-
- /** Index into the TypeDef table. */
- public int EnclosingClass;
-
- public NestedClass(PEFile file, int rows) { super(file, ID, rows); }
-
- protected void populateFields() {
- NestedClass = readTableIndex(TypeDef.ID);
- EnclosingClass = readTableIndex(TypeDef.ID);
- }
-
- protected int getRowSize() {
- return 2 * file.getTableIndexSize(TypeDef.ID);
- }
-
- } // class NestedClass
-
- //##########################################################################
- // table GenericParam; ID=0x2a; p137, 22.20
-
- public static final class GenericParam extends Table {
- public static final int ID = 0x2a;
-
- public int Number;
- public int Flags;
- public int Owner; // a TypeOrMethodDef (Sec 24.2.6) coded index
- public int Name; // a non-null index into the String heap
-
- private java.util.Map /*<Integer, java.util.Set<Integer>>*/ GenericParamIdxesForMethodDefIdx =
- new java.util.HashMap();
- private java.util.Map /*<Integer, java.util.Set<Integer>>*/ GenericParamIdxesForTypeDefIdx =
- new java.util.HashMap();
-
- private void addToMap(int key, int value, java.util.Map IdxesForIdx) {
- java.util.Set /*<Integer>*/ bucket = (java.util.Set)IdxesForIdx.get(Integer.valueOf(key));
- if(bucket == null) {
- bucket = new java.util.HashSet();
- IdxesForIdx.put(Integer.valueOf(key), bucket);
- }
- bucket.add(Integer.valueOf(value));
- }
-
- /** Indexes of rows in the GenericParam table representing type parameters defined by the type given by
- * its row index TypeDefIdx (in the TypeDef table).
- * No need to position the current record before invoking this method. */
- public int[] getTVarIdxes(int TypeDefIdx) {
- if(!mapsPopulated) {
- initMaps();
- }
- java.util.Set bucket = (java.util.Set)GenericParamIdxesForTypeDefIdx.get(Integer.valueOf(TypeDefIdx));
- if(bucket == null) {
- bucket = java.util.Collections.EMPTY_SET;
- }
- int[] res = new int[bucket.size()];
- java.util.Iterator /*<Integer>*/ it = bucket.iterator();
- for(int i = 0; i < bucket.size(); i++) {
- res[i] = ((Integer)it.next()).intValue();
- }
- return res;
- }
-
- /** Indexes of rows in the GenericParam table representing type parameters defined by the method given by
- * its row index MethodDefIdx (in the MethodDef table)
- * No need to position the current record before invoking this method. */
- public int[] getMVarIdxes(int MethodDefIdx) {
- if(!mapsPopulated) {
- initMaps();
- }
- java.util.Set bucket = (java.util.Set)GenericParamIdxesForMethodDefIdx.get(Integer.valueOf(MethodDefIdx));
- if(bucket == null) {
- bucket = java.util.Collections.EMPTY_SET;
- }
- int[] res = new int[bucket.size()];
- java.util.Iterator /*<Integer>*/ it = bucket.iterator();
- for(int i = 0; i < bucket.size(); i++) {
- res[i] = ((Integer)it.next()).intValue();
- }
- return res;
- }
-
- private boolean mapsPopulated = false;
-
- private void initMaps() {
- mapsPopulated = true;
- for (int currentParamRow = 1; currentParamRow <= rows; currentParamRow++) {
- int currentOwner = file.GenericParam(currentParamRow).Owner;
- int targetTableId = Table.getTableId(Table._TypeOrMethodDef, currentOwner);
- int targetRow = currentOwner >> Table.NoBits[Table._TypeOrMethodDef];
- if(targetTableId == TypeDef.ID){
- addToMap(targetRow, currentParamRow, GenericParamIdxesForTypeDefIdx);
- } else if(targetTableId == MethodDef.ID) {
- addToMap(targetRow, currentParamRow, GenericParamIdxesForMethodDefIdx);
- } else {
- throw new RuntimeException();
- }
- }
- }
-
- public GenericParam(PEFile file, int rows) {
- super(file, ID, rows);
- this.newMapping = true;
- }
-
- protected void populateFields() {
- Number = readShort();
- Flags = readShort();
- Owner = readTableSetIndex(_TypeOrMethodDef);
- Name = readStringIndex();
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean isInvariant() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x0003) == 0;
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean isCovariant() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x0003) == 1;
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean isContravariant() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x0003) == 2;
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean isReferenceType() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x001C) == 4;
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean isValueType() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x001C) == 8;
- }
-
- /** This method assumes populateFields() has been just called to set Flags for the current record */
- public boolean hasDefaultConstructor() {
- /* 23.1.7 Flags for Generic Parameters [GenericParamAttributes tributes] */
- return (Flags & 0x001C) == 0x0010;
- }
-
- protected int getRowSize() {
- return 2 + 2 + file.getTableSetIndexSize(_TypeOrMethodDef) + file.getStringIndexSize();
- /* Columns:
- Number (2 bytes),
- Flags (2 bytes),
- Owner (coded token of type TypeOrMethodDef),
- Name (offset in the #Strings stream).
- */
- }
-
- public String getName() {
- return file.getString(Name);
- }
-
- } // class GenericParam
-
-
- //##########################################################################
- // table GenericParamConstraint; ID=0x2c; p139, 22.20
-
- public static final class GenericParamConstraint extends Table {
- public static final int ID = 0x2c;
-
- public int Owner; // an index into the GenericParam table
- public int Constraint; // a TypeDefOrRef (Sec 24.2.6) coded index
-
- public GenericParamConstraint(PEFile file, int rows) {
- super(file, ID, rows);
- this.newMapping = true;
- }
-
- protected void populateFields() {
- Owner = readTableIndex(GenericParam.ID);
- Constraint = readTableSetIndex(_TypeDefOrRef);
- }
-
- protected int getRowSize() {
- return file.getTableIndexSize(GenericParam.ID) + file.getTableSetIndexSize(_TypeDefOrRef);
- /* Columns:
- Owner (RID in the GenericParam table),
- Constraint (coded token of type TypeDefOrRef).
- */
- }
-
- private boolean mapPopulated = false;
-
- /** Indexes of rows (in the TypeDef, TypeRef, or TypeSpec tables) denoting the base class (if any)
- * and interfaces (if any) that the generic parameter (of TVar or MVar kind) should support, where
- * that generic parameter is represented by its index into the GenericParam table. */
- public int[] getTypeDefOrRefIdxes(int genParamIdx) {
- if(!mapPopulated) {
- initMap();
- }
- java.util.Set bucket = (java.util.Set)TypeDefOrRefIdxesForGenParamIdx.get(Integer.valueOf(genParamIdx));
- if(bucket == null) {
- bucket = java.util.Collections.EMPTY_SET;
- }
- int[] res = new int[bucket.size()];
- java.util.Iterator /*<Integer>*/ it = bucket.iterator();
- for(int i = 0; i < bucket.size(); i++) {
- res[i] = ((Integer)it.next()).intValue();
- }
- return res;
- }
-
-
- private void initMap() {
- mapPopulated = true;
- for (int currentConstraintRow = 1; currentConstraintRow <= rows; currentConstraintRow++) {
- int targetGenericParam = file.GenericParamConstraint(currentConstraintRow).Owner;
- int value = file.GenericParamConstraint.Constraint;
- addToMap(targetGenericParam, value);
- }
- }
-
- private java.util.Map /*<Integer, java.util.Set<Integer>>*/ TypeDefOrRefIdxesForGenParamIdx =
- new java.util.HashMap();
-
- private void addToMap(int key, int value) {
- java.util.Set /*<Integer>*/ bucket = (java.util.Set)TypeDefOrRefIdxesForGenParamIdx.get(Integer.valueOf(key));
- if(bucket == null) {
- bucket = new java.util.HashSet();
- TypeDefOrRefIdxesForGenParamIdx.put(Integer.valueOf(key), bucket);
- }
- bucket.add(Integer.valueOf(value));
- }
-
- } // class GenericParamConstraint
-
- //##########################################################################
- // table MethodSpec; ID=0x2b; p149, in Sec. 22.29 of Partition II
-
- public static final class MethodSpec extends Table {
- public static final int ID = 0x2b;
-
- /* an index into the MethodDef or MemberRef table, specifying which generic method this row is an instantiation of.
- A MethodDefOrRef (Sec. 24.2.6) coded index */
- public int Method;
-
- /* an index into the Blob heap (Sec. 23.2.15), holding the signature of this instantiation */
- public int Instantiation;
-
- public MethodSpec(PEFile file, int rows) {
- super(file, ID, rows);
- this.newMapping = true;
- }
-
- protected void populateFields() {
- Method = readTableSetIndex(_MethodDefOrRef);
- Instantiation = readBlobIndex();
- }
-
- protected int getRowSize() {
- return file.getTableSetIndexSize(_MethodDefOrRef) + file.getBlobIndexSize();
- }
-
-
- } // class MethodSpec
- //##########################################################################
-
-} // class Table
diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala
index bb0732dcc6..7495f97efd 100644
--- a/src/partest/scala/tools/partest/CompilerTest.scala
+++ b/src/partest/scala/tools/partest/CompilerTest.scala
@@ -49,7 +49,7 @@ abstract class CompilerTest extends DirectTest {
}
class SymsInPackage(pkgName: String) {
- def pkg = rootMirror.getRequiredPackage(pkgName)
+ def pkg = rootMirror.getPackage(pkgName)
def classes = allMembers(pkg) filter (_.isClass)
def modules = allMembers(pkg) filter (_.isModule)
def symbols = classes ++ terms filterNot (_ eq NoSymbol)
diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
index 7000e8280b..0ec3f60bf5 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala
@@ -84,7 +84,6 @@ class ConsoleFileManager extends FileManager {
latestReflectFile = testClassesDir / "reflect"
latestCompFile = testClassesDir / "compiler"
latestPartestFile = testClassesDir / "partest"
- latestFjbgFile = testParent / "lib" / "fjbg.jar"
}
else if (testBuild.isDefined) {
val dir = Path(testBuild.get)
@@ -94,7 +93,6 @@ class ConsoleFileManager extends FileManager {
latestReflectFile = dir / "lib/scala-reflect.jar"
latestCompFile = dir / "lib/scala-compiler.jar"
latestPartestFile = dir / "lib/scala-partest.jar"
- latestFjbgFile = testParent / "lib" / "fjbg.jar"
}
else {
def setupQuick() {
@@ -152,8 +150,6 @@ class ConsoleFileManager extends FileManager {
// run setup based on most recent time
pairs(pairs.keys max)()
-
- latestFjbgFile = prefixFile("lib/fjbg.jar")
}
LATEST_LIB = latestLibFile.getAbsolutePath
@@ -174,7 +170,6 @@ class ConsoleFileManager extends FileManager {
var latestReflectFile: File = _
var latestCompFile: File = _
var latestPartestFile: File = _
- var latestFjbgFile: File = _
def latestScalapFile: File = (latestLibFile.parent / "scalap.jar").jfile
var testClassesDir: Directory = _
// initialize above fields
diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
index 4b0ed1f82a..d3a40718c6 100644
--- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala
@@ -51,9 +51,9 @@ class ReflectiveRunner {
new ConsoleFileManager
import fileManager.
- { latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile, latestActorsFile }
+ { latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestScalapFile, latestActorsFile }
val files =
- Array(latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestFjbgFile, latestScalapFile, latestActorsFile) map (x => io.File(x))
+ Array(latestCompFile, latestReflectFile, latestLibFile, latestPartestFile, latestScalapFile, latestActorsFile) map (x => io.File(x))
val sepUrls = files map (_.toURL)
var sepLoader = new URLClassLoader(sepUrls, null)
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 0c8e81a220..8f256aa1f5 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -59,8 +59,6 @@ private[reflect] trait BuildUtils { self: Universe =>
def flagsFromBits(bits: Long): FlagSet
- def emptyValDef: ValDef
-
def This(sym: Symbol): Tree
def Select(qualifier: Tree, sym: Symbol): Select
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index c98107f9b5..cfa6315797 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -75,11 +75,26 @@ trait Trees { self: Universe =>
def isDef: Boolean
/** Is this tree one of the empty trees?
+ *
* Empty trees are: the `EmptyTree` null object, `TypeTree` instances that don't carry a type
* and the special `emptyValDef` singleton.
+ *
+ * In the compiler the `isEmpty` check and the derived `orElse` method are mostly used
+ * as a check for a tree being a null object (`EmptyTree` for term trees and empty TypeTree for type trees).
+ *
+ * Unfortunately `emptyValDef` is also considered to be `isEmpty`, but this is deemed to be
+ * a conceptual mistake pending a fix in https://issues.scala-lang.org/browse/SI-6762.
+ *
+ * @see `canHaveAttrs`
*/
def isEmpty: Boolean
+ /** Can this tree carry attributes (i.e. symbols, types or positions)?
+ * Typically the answer is yes, except for the `EmptyTree` null object and
+ * two special singletons: `emptyValDef` and `pendingSuperCall`.
+ */
+ def canHaveAttrs: Boolean
+
/** The canonical way to test if a Tree represents a term.
*/
def isTerm: Boolean
@@ -1611,14 +1626,23 @@ trait Trees { self: Universe =>
* This node always occurs in the following context:
*
* (`new` tpt).<init>[targs](args)
+ *
+ * For example, an AST representation of:
+ *
+ * new Example[Int](2)(3)
+ *
+ * is the following code:
+ *
+ * Apply(
+ * Apply(
+ * TypeApply(
+ * Select(New(TypeTree(typeOf[Example])), nme.CONSTRUCTOR)
+ * TypeTree(typeOf[Int])),
+ * List(Literal(Constant(2)))),
+ * List(Literal(Constant(3))))
* @group Extractors
*/
abstract class NewExtractor {
- /** A user level `new`.
- * One should always use this factory method to build a user level `new`.
- *
- * @param tpt a class type
- */
def apply(tpt: Tree): New
def unapply(new_ : New): Option[Tree]
}
@@ -1720,6 +1744,16 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* fun[args]
+ *
+ * Should only be used with `fun` nodes which are terms, i.e. which have `isTerm` returning `true`.
+ * Otherwise `AppliedTypeTree` should be used instead.
+ *
+ * def foo[T] = ???
+ * foo[Int] // represented as TypeApply(Ident(<foo>), List(TypeTree(<Int>)))
+ *
+ * List[Int] as in `val x: List[Int] = ???`
+ * // represented as AppliedTypeTree(Ident(<List>), List(TypeTree(<Int>)))
+ *
* @group Extractors
*/
abstract class TypeApplyExtractor {
@@ -1890,6 +1924,12 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* qualifier.selector
+ *
+ * Should only be used with `qualifier` nodes which are terms, i.e. which have `isTerm` returning `true`.
+ * Otherwise `SelectFromTypeTree` should be used instead.
+ *
+ * foo.Bar // represented as Select(Ident(<foo>), <Bar>)
+ * Foo#Bar // represented as SelectFromTypeTree(Ident(<Foo>), <Bar>)
* @group Extractors
*/
abstract class SelectExtractor {
@@ -2122,7 +2162,6 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- // [Eugene++] don't see why we need it, when we have Select
type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
/** A tag that preserves the identity of the `SelectFromTypeTree` abstract type from erasure.
@@ -2142,6 +2181,12 @@ trait Trees { self: Universe =>
* qualifier # selector
*
* Note: a path-dependent type p.T is expressed as p.type # T
+ *
+ * Should only be used with `qualifier` nodes which are types, i.e. which have `isType` returning `true`.
+ * Otherwise `Select` should be used instead.
+ *
+ * Foo#Bar // represented as SelectFromTypeTree(Ident(<Foo>), <Bar>)
+ * foo.Bar // represented as Select(Ident(<foo>), <Bar>)
* @group Extractors
*/
abstract class SelectFromTypeTreeExtractor {
@@ -2217,6 +2262,15 @@ trait Trees { self: Universe =>
* This AST node corresponds to the following Scala code:
*
* tpt[args]
+ *
+ * Should only be used with `tpt` nodes which are types, i.e. which have `isType` returning `true`.
+ * Otherwise `TypeApply` should be used instead.
+ *
+ * List[Int] as in `val x: List[Int] = ???`
+ * // represented as AppliedTypeTree(Ident(<List>), List(TypeTree(<Int>)))
+ *
+ * def foo[T] = ???
+ * foo[Int] // represented as TypeApply(Ident(<foo>), List(TypeTree(<Int>)))
* @group Extractors
*/
abstract class AppliedTypeTreeExtractor {
@@ -2366,123 +2420,155 @@ trait Trees { self: Universe =>
*/
val emptyValDef: ValDef
+ /** An empty superclass constructor call corresponding to:
+ * super.<init>()
+ * This is used as a placeholder in the primary constructor body in class templates
+ * to denote the insertion point of a call to superclass constructor after the typechecker
+ * figures out the superclass of a given template.
+ * @group Trees
+ */
+ val pendingSuperCall: Apply
+
// ---------------------- factories ----------------------------------------------
/** A factory method for `ClassDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ClassDef constructor to create a class and then initialize its position and symbol manually", "2.10.1")
def ClassDef(sym: Symbol, impl: Template): ClassDef
/** A factory method for `ModuleDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ModuleDef constructor to create an object and then initialize its position and symbol manually", "2.10.1")
def ModuleDef(sym: Symbol, impl: Template): ModuleDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ValDef constructor to create a val and then initialize its position and symbol manually", "2.10.1")
def ValDef(sym: Symbol, rhs: Tree): ValDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical ValDef constructor to create a val with an empty right-hand side and then initialize its position and symbol manually", "2.10.1")
def ValDef(sym: Symbol): ValDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, rhs: Tree): DefDef
/** A factory method for `ValDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
/** A factory method for `TypeDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical TypeDef constructor to create a type alias and then initialize its position and symbol manually", "2.10.1")
def TypeDef(sym: Symbol, rhs: Tree): TypeDef
/** A factory method for `TypeDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical TypeDef constructor to create an abstract type or type parameter and then initialize its position and symbol manually", "2.10.1")
def TypeDef(sym: Symbol): TypeDef
/** A factory method for `LabelDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical LabelDef constructor to create a label and then initialize its position and symbol manually", "2.10.1")
def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
/** A factory method for `Block` nodes.
* Flattens directly nested blocks.
* @group Factories
*/
+ @deprecated("Use the canonical Block constructor, explicitly specifying its expression if necessary. Flatten directly nested blocks manually if needed", "2.10.1")
def Block(stats: Tree*): Block
/** A factory method for `CaseDef` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical CaseDef constructor passing EmptyTree for guard", "2.10.1")
def CaseDef(pat: Tree, body: Tree): CaseDef
/** A factory method for `Bind` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical Bind constructor to create a bind and then initialize its symbol manually", "2.10.1")
def Bind(sym: Symbol, body: Tree): Bind
/** A factory method for `Try` nodes.
* @group Factories
*/
+ @deprecated("Use canonical CaseDef constructors to to create exception catching expressions and then wrap them in Try", "2.10.1")
def Try(body: Tree, cases: (Tree, Tree)*): Try
/** A factory method for `Throw` nodes.
* @group Factories
*/
+ @deprecated("Use the canonical New constructor to create an object instantiation expression and then wrap it in Throw", "2.10.1")
def Throw(tpe: Type, args: Tree*): Throw
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).<init>(as)`
* @group Factories
*/
+ @deprecated("Use Apply(...Apply(Select(New(tpt), nme.CONSTRUCTOR), args1)...argsN) instead", "2.10.1")
def New(tpt: Tree, argss: List[List[Tree]]): Tree
/** 0-1 argument list new, based on a type.
* @group Factories
*/
+ @deprecated("Use New(TypeTree(tpe), args.toList) instead", "2.10.1")
def New(tpe: Type, args: Tree*): Tree
/** 0-1 argument list new, based on a symbol.
* @group Factories
*/
+ @deprecated("Use New(sym.toType, args) instead", "2.10.1")
def New(sym: Symbol, args: Tree*): Tree
/** A factory method for `Apply` nodes.
* @group Factories
*/
+ @deprecated("Use Apply(Ident(sym), args.toList) instead", "2.10.1")
def Apply(sym: Symbol, args: Tree*): Tree
/** 0-1 argument list new, based on a type tree.
* @group Factories
*/
+ @deprecated("Use Apply(Select(New(tpt), nme.CONSTRUCTOR), args) instead", "2.10.1")
def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree
/** A factory method for `Super` nodes.
* @group Factories
*/
+ @deprecated("Use Super(This(sym), mix) instead", "2.10.1")
def Super(sym: Symbol, mix: TypeName): Tree
/** A factory method for `This` nodes.
@@ -2494,6 +2580,7 @@ trait Trees { self: Universe =>
* The string `name` argument is assumed to represent a [[scala.reflect.api.Names#TermName `TermName`]].
* @group Factories
*/
+ @deprecated("Use Select(tree, newTermName(name)) instead", "2.10.1")
def Select(qualifier: Tree, name: String): Select
/** A factory method for `Select` nodes.
@@ -2504,6 +2591,7 @@ trait Trees { self: Universe =>
/** A factory method for `Ident` nodes.
* @group Factories
*/
+ @deprecated("Use Ident(newTermName(name)) instead", "2.10.1")
def Ident(name: String): Ident
/** A factory method for `Ident` nodes.
@@ -2843,7 +2931,8 @@ trait Trees { self: Universe =>
trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
/** Transforms a `ValDef`. */
def transformValDef(tree: ValDef): ValDef =
- if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
+ if (tree eq emptyValDef) tree
+ else transform(tree).asInstanceOf[ValDef]
/** Transforms a list of `ValDef` nodes. */
def transformValDefs(trees: List[ValDef]): List[ValDef] =
trees mapConserve (transformValDef(_))
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 6bf12f06de..eba10e8ffb 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -60,7 +60,7 @@ trait BaseTypeSeqs {
elems(i) match {
case rtp @ RefinedType(variants, decls) =>
// can't assert decls.isEmpty; see t0764
- //if (!decls.isEmpty) assert(false, "computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
+ //if (!decls.isEmpty) abort("computing closure of "+this+":"+this.isInstanceOf[RefinedType]+"/"+closureCache(j))
//Console.println("compute closure of "+this+" => glb("+variants+")")
pending += i
try {
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 9da6ad652a..175943d264 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -45,8 +45,6 @@ trait BuildUtils { self: SymbolTable =>
def flagsFromBits(bits: Long): FlagSet = bits
- def emptyValDef: ValDef = self.emptyValDef
-
def This(sym: Symbol): Tree = self.This(sym)
def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 9a846179b9..8c048ed7f8 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -14,7 +14,7 @@ import scala.reflect.api.{Universe => ApiUniverse}
trait Definitions extends api.StandardDefinitions {
self: SymbolTable =>
- import rootMirror.{getModule, getClassByName, getRequiredClass, getRequiredModule, getRequiredPackage, getClassIfDefined, getModuleIfDefined, getPackageObject, getPackageObjectIfDefined, requiredClass, requiredModule}
+ import rootMirror.{getModule, getPackage, getClassByName, getRequiredClass, getRequiredModule, getClassIfDefined, getModuleIfDefined, getPackageObject, getPackageObjectIfDefined, requiredClass, requiredModule}
object definitions extends DefinitionsClass
@@ -169,11 +169,11 @@ trait Definitions extends api.StandardDefinitions {
// It becomes tricky to create dedicated objects for other symbols because
// of initialization order issues.
- lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang)
+ lazy val JavaLangPackage = getPackage("java.lang")
lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClass
- lazy val ScalaPackage = getRequiredPackage(nme.scala_)
+ lazy val ScalaPackage = getPackage("scala")
lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClass
- lazy val RuntimePackage = getRequiredPackage("scala.runtime")
+ lazy val RuntimePackage = getPackage("scala.runtime")
lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClass
// convenient one-argument parameter lists
@@ -684,9 +684,7 @@ trait Definitions extends api.StandardDefinitions {
def scalaRepeatedType(arg: Type) = appliedType(RepeatedParamClass, arg)
def seqType(arg: Type) = appliedType(SeqClass, arg)
- def ClassType(arg: Type) =
- if (phase.erasedTypes || forMSIL) ClassClass.tpe
- else appliedType(ClassClass, arg)
+ def ClassType(arg: Type) = if (phase.erasedTypes) ClassClass.tpe else appliedType(ClassClass, arg)
def EnumType(sym: Symbol) =
// given (in java): "class A { enum E { VAL1 } }"
@@ -704,34 +702,6 @@ trait Definitions extends api.StandardDefinitions {
def classExistentialType(clazz: Symbol): Type =
newExistentialType(clazz.typeParams, clazz.tpe_*)
- //
- // .NET backend
- //
-
- lazy val ComparatorClass = getRequiredClass("scala.runtime.Comparator")
- // System.MulticastDelegate
- lazy val DelegateClass: ClassSymbol = getClassByName(sn.Delegate)
- var Delegate_scalaCallers: List[Symbol] = List() // Syncnote: No protection necessary yet as only for .NET where reflection is not supported.
- // Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
- // var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _
- lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap()
-
- def isCorrespondingDelegate(delegateType: Type, functionType: Type): Boolean = {
- isSubType(delegateType, DelegateClass.tpe) &&
- (delegateType.member(nme.apply).tpe match {
- case MethodType(delegateParams, delegateReturn) =>
- isFunctionType(functionType) &&
- (functionType.normalize match {
- case TypeRef(_, _, args) =>
- (delegateParams.map(pt => {
- if (pt.tpe == AnyClass.tpe) definitions.ObjectClass.tpe else pt})
- ::: List(delegateReturn)) == args
- case _ => false
- })
- case _ => false
- })
- }
-
// members of class scala.Any
lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
@@ -1164,27 +1134,5 @@ trait Definitions extends api.StandardDefinitions {
val _ = symbolsNotPresentInBytecode
isInitialized = true
} //init
-
- var nbScalaCallers: Int = 0
- def newScalaCaller(delegateType: Type): MethodSymbol = {
- assert(forMSIL, "scalaCallers can only be created if target is .NET")
- // object: reference to object on which to call (scala-)method
- val paramTypes: List[Type] = List(ObjectClass.tpe)
- val name = newTermName("$scalaCaller$$" + nbScalaCallers)
- // tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
- // type parameter =-> a MethodType in this case
- // TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
- val newCaller = enterNewMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC)
- // val newCaller = newPolyMethod(DelegateClass, name,
- // tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
- Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
- nbScalaCallers += 1
- newCaller
- }
-
- def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol) {
- assert(Delegate_scalaCallers contains scalaCaller)
- Delegate_scalaCallerTargets += (scalaCaller -> methSym)
- }
}
}
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 6ad9a63822..29f1c7e1ca 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -333,6 +333,8 @@ trait Importers extends api.Importers { self: SymbolTable =>
new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl))
case from.emptyValDef =>
emptyValDef
+ case from.pendingSuperCall =>
+ pendingSuperCall
case from.ValDef(mods, name, tpt, rhs) =>
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 80aa06d020..6e76a7afb3 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -172,14 +172,15 @@ trait Mirrors extends api.Mirrors {
case _ => MissingRequirementError.notFound("package " + fullname)
}
- def getPackage(fullname: Name): ModuleSymbol =
+ def getPackage(fullname: TermName): ModuleSymbol =
ensurePackageSymbol(fullname.toString, getModuleOrClass(fullname), allowModules = true)
- def getRequiredPackage(fullname: String): ModuleSymbol =
+ @deprecated("Use getPackage", "2.11.0") def getRequiredPackage(fullname: String): ModuleSymbol =
getPackage(newTermNameCached(fullname))
- def getPackageObject(fullname: String): ModuleSymbol =
- (getPackage(newTermName(fullname)).info member nme.PACKAGE) match {
+ def getPackageObject(fullname: String): ModuleSymbol = getPackageObject(newTermName(fullname))
+ def getPackageObject(fullname: TermName): ModuleSymbol =
+ (getPackage(fullname).info member nme.PACKAGE) match {
case x: ModuleSymbol => x
case _ => MissingRequirementError.notFound("package object " + fullname)
}
@@ -187,8 +188,8 @@ trait Mirrors extends api.Mirrors {
def getPackageObjectIfDefined(fullname: String): Symbol =
getPackageObjectIfDefined(newTermNameCached(fullname))
- def getPackageObjectIfDefined(fullname: Name): Symbol =
- wrapMissing(getPackageObject(fullname.toTermName))
+ def getPackageObjectIfDefined(fullname: TermName): Symbol =
+ wrapMissing(getPackageObject(fullname))
override def staticPackage(fullname: String): ModuleSymbol =
ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 333651162e..cea9215ae2 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -10,22 +10,7 @@ import scala.io.Codec
import java.security.MessageDigest
import scala.language.implicitConversions
-trait LowPriorityNames {
- self: Names =>
-
- implicit def nameToNameOps(name: Name): NameOps[Name] = new NameOps[Name](name)
-}
-
-/** The class Names ...
- *
- * @author Martin Odersky
- * @version 1.0, 05/02/2005
- */
-trait Names extends api.Names with LowPriorityNames {
- implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName
-
-// Operations -------------------------------------------------------------
-
+trait Names extends api.Names {
private final val HASH_SIZE = 0x8000
private final val HASH_MASK = 0x7FFF
private final val NAME_SIZE = 0x20000
@@ -399,9 +384,13 @@ trait Names extends api.Names with LowPriorityNames {
def debugString = { val s = decode ; if (isTypeName) s + "!" else s }
}
+ implicit def AnyNameOps(name: Name): NameOps[Name] = new NameOps(name)
implicit def TermNameOps(name: TermName): NameOps[TermName] = new NameOps(name)
implicit def TypeNameOps(name: TypeName): NameOps[TypeName] = new NameOps(name)
+ /** FIXME: This is a good example of something which is pure "value class" but cannot
+ * reap the benefits because an (unused) $outer pointer so it is not single-field.
+ */
final class NameOps[T <: Name](name: T) {
def stripSuffix(suffix: Name): T = if (name endsWith suffix) dropRight(suffix.length) else name
def dropRight(n: Int): T = name.subName(0, name.length - n).asInstanceOf[T]
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index faa161d6b1..f8c670827a 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -38,7 +38,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (t eq EmptyTree) ()
+ if (!t.canHaveAttrs) ()
else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index c36724e388..2a3525206f 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -435,7 +435,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree =>
xprintTree(this, tree)
}
- if (printTypes && tree.isTerm && !tree.isEmpty) {
+ if (printTypes && tree.isTerm && tree.canHaveAttrs) {
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
@@ -540,8 +540,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(")")
case EmptyTree =>
print("EmptyTree")
- case emptyValDef: AnyRef if emptyValDef eq self.emptyValDef =>
+ case self.emptyValDef =>
print("emptyValDef")
+ case self.pendingSuperCall =>
+ print("pendingSuperCall")
case tree: Tree =>
val hasSymbolField = tree.hasSymbolField && tree.symbol != NoSymbol
val isError = hasSymbolField && tree.symbol.name.toString == nme.ERROR.toString
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index a5810c9c83..c5521ae650 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -18,8 +18,6 @@ trait StdNames {
def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str))
- implicit def lowerTermNames(n: TermName): String = n.toString
-
/** Tensions: would like the keywords to be the very first names entered into the names
* storage so their ids count from 0, which simplifies the parser. Switched to abstract
* classes to avoid all the indirection which is generated with implementation-containing
@@ -37,11 +35,7 @@ trait StdNames {
kws = kws + result
result
}
- def result: Set[TermName] = {
- val result = kws
- kws = null
- result
- }
+ def result: Set[TermName] = try kws finally kws = null
}
private final object compactify extends (String => String) {
@@ -201,6 +195,8 @@ trait StdNames {
}
abstract class TypeNames extends Keywords with TypeNamesApi {
+ override type NameType = TypeName
+
protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
final val BYNAME_PARAM_CLASS_NAME: NameType = "<byname>"
@@ -262,6 +258,8 @@ trait StdNames {
}
abstract class TermNames extends Keywords with TermNamesApi {
+ override type NameType = TermName
+
protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
/** Base strings from which synthetic names are derived. */
@@ -586,7 +584,7 @@ trait StdNames {
val canEqual_ : NameType = "canEqual"
val checkInitialized: NameType = "checkInitialized"
val classOf: NameType = "classOf"
- val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
+ val clone_ : NameType = "clone"
val conforms: NameType = "conforms"
val copy: NameType = "copy"
val currentMirror: NameType = "currentMirror"
@@ -600,20 +598,20 @@ trait StdNames {
val equalsNumChar : NameType = "equalsNumChar"
val equalsNumNum : NameType = "equalsNumNum"
val equalsNumObject : NameType = "equalsNumObject"
- val equals_ : NameType = if (forMSIL) "Equals" else "equals"
+ val equals_ : NameType = "equals"
val error: NameType = "error"
val ex: NameType = "ex"
val experimental: NameType = "experimental"
val f: NameType = "f"
val false_ : NameType = "false"
val filter: NameType = "filter"
- val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize"
+ val finalize_ : NameType = "finalize"
val find_ : NameType = "find"
val flagsFromBits : NameType = "flagsFromBits"
val flatMap: NameType = "flatMap"
val foreach: NameType = "foreach"
val get: NameType = "get"
- val hashCode_ : NameType = if (forMSIL) "GetHashCode" else "hashCode"
+ val hashCode_ : NameType = "hashCode"
val hash_ : NameType = "hash"
val implicitly: NameType = "implicitly"
val in: NameType = "in"
@@ -647,6 +645,7 @@ trait StdNames {
val notifyAll_ : NameType = "notifyAll"
val notify_ : NameType = "notify"
val null_ : NameType = "null"
+ val pendingSuperCall: NameType = "pendingSuperCall"
val prefix : NameType = "prefix"
val productArity: NameType = "productArity"
val productElement: NameType = "productElement"
@@ -677,7 +676,7 @@ trait StdNames {
val thisPrefix : NameType = "thisPrefix"
val toArray: NameType = "toArray"
val toObjectArray : NameType = "toObjectArray"
- val toString_ : NameType = if (forMSIL) "ToString" else "toString"
+ val toString_ : NameType = "toString"
val toTypeConstructor: NameType = "toTypeConstructor"
val tpe : NameType = "tpe"
val tree : NameType = "tree"
@@ -931,33 +930,6 @@ trait StdNames {
@deprecated("Use a method in tpnme", "2.10.0") def interfaceName(implname: Name): TypeName = tpnme.interfaceName(implname)
}
- abstract class SymbolNames {
- protected val stringToTermName = null
- protected val stringToTypeName = null
- protected implicit def createNameType(s: String): TypeName = newTypeNameCached(s)
-
- val BoxedBoolean : TypeName
- val BoxedCharacter : TypeName
- val BoxedNumber : TypeName
- val Delegate : TypeName
- val IOOBException : TypeName // IndexOutOfBoundsException
- val InvTargetException : TypeName // InvocationTargetException
- val MethodAsObject : TypeName
- val NPException : TypeName // NullPointerException
- val Object : TypeName
- val Throwable : TypeName
- val ValueType : TypeName
-
- val GetCause : TermName
- val GetClass : TermName
- val GetClassLoader : TermName
- val GetMethod : TermName
- val Invoke : TermName
- val JavaLang : TermName
-
- val Boxed: immutable.Map[TypeName, TypeName]
- }
-
class JavaKeywords {
private val kw = new KeywordSetBuilder
@@ -1015,7 +987,11 @@ trait StdNames {
final val keywords = kw.result
}
- private abstract class JavaNames extends SymbolNames {
+ sealed abstract class SymbolNames {
+ protected val stringToTermName = null
+ protected val stringToTypeName = null
+ protected implicit def createNameType(s: String): TypeName = newTypeNameCached(s)
+
final val BoxedBoolean: TypeName = "java.lang.Boolean"
final val BoxedByte: TypeName = "java.lang.Byte"
final val BoxedCharacter: TypeName = "java.lang.Character"
@@ -1025,14 +1001,12 @@ trait StdNames {
final val BoxedLong: TypeName = "java.lang.Long"
final val BoxedNumber: TypeName = "java.lang.Number"
final val BoxedShort: TypeName = "java.lang.Short"
- final val Delegate: TypeName = tpnme.NO_NAME
final val IOOBException: TypeName = "java.lang.IndexOutOfBoundsException"
final val InvTargetException: TypeName = "java.lang.reflect.InvocationTargetException"
final val MethodAsObject: TypeName = "java.lang.reflect.Method"
final val NPException: TypeName = "java.lang.NullPointerException"
final val Object: TypeName = "java.lang.Object"
final val Throwable: TypeName = "java.lang.Throwable"
- final val ValueType: TypeName = tpnme.NO_NAME
final val GetCause: TermName = newTermName("getCause")
final val GetClass: TermName = newTermName("getClass")
@@ -1053,39 +1027,5 @@ trait StdNames {
)
}
- private class MSILNames extends SymbolNames {
- final val BoxedBoolean: TypeName = "System.IConvertible"
- final val BoxedCharacter: TypeName = "System.IConvertible"
- final val BoxedNumber: TypeName = "System.IConvertible"
- final val Delegate: TypeName = "System.MulticastDelegate"
- final val IOOBException: TypeName = "System.IndexOutOfRangeException"
- final val InvTargetException: TypeName = "System.Reflection.TargetInvocationException"
- final val MethodAsObject: TypeName = "System.Reflection.MethodInfo"
- final val NPException: TypeName = "System.NullReferenceException"
- final val Object: TypeName = "System.Object"
- final val Throwable: TypeName = "System.Exception"
- final val ValueType: TypeName = "System.ValueType"
-
- final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */
- final val GetClass: TermName = newTermName("GetType")
- final lazy val GetClassLoader: TermName = throw new UnsupportedOperationException("Scala reflection is not supported on this platform");
- final val GetMethod: TermName = newTermName("GetMethod")
- final val Invoke: TermName = newTermName("Invoke")
- final val JavaLang: TermName = newTermName("System")
-
- val Boxed = immutable.Map[TypeName, TypeName](
- tpnme.Boolean -> "System.Boolean",
- tpnme.Byte -> "System.SByte", // a scala.Byte is signed and a System.SByte too (unlike a System.Byte)
- tpnme.Char -> "System.Char",
- tpnme.Short -> "System.Int16",
- tpnme.Int -> "System.Int32",
- tpnme.Long -> "System.Int64",
- tpnme.Float -> "System.Single",
- tpnme.Double -> "System.Double"
- )
- }
-
- lazy val sn: SymbolNames =
- if (forMSIL) new MSILNames
- else new JavaNames { }
+ lazy val sn: SymbolNames = new SymbolNames { }
}
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index a0e5851a6e..540338dca7 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -117,12 +117,6 @@ abstract class SymbolTable extends macros.Universe
@elidable(elidable.WARNING)
def assertCorrectThread() {}
- /** Are we compiling for Java SE? */
- // def forJVM: Boolean
-
- /** Are we compiling for .NET? */
- def forMSIL: Boolean = false
-
/** A last effort if symbol in a select <owner>.<name> is not found.
* This is overridden by the reflection compiler to make up a package
* when it makes sense (i.e. <owner> is a package and <name> is a term name).
@@ -344,6 +338,11 @@ abstract class SymbolTable extends macros.Universe
@inline final def atPhase[T](ph: Phase)(op: => T): T = enteringPhase(ph)(op)
@deprecated("Use enteringPhaseNotLaterThan", "2.10.0")
@inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = enteringPhaseNotLaterThan(target)(op)
+
+ /**
+ * Adds the `sm` String interpolator to a [[scala.StringContext]].
+ */
+ implicit val StringContextStripMarginOps: StringContext => StringContextStripMarginOps = util.StringContextStripMarginOps
}
object SymbolTableStats {
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index ad7dbe5ef1..8e776b8590 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -77,7 +77,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT)
def isJava: Boolean = isJavaDefined
def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable
- def isVar: Boolean = isTerm && !isModule && !isMethod && isMutable
+ def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
@@ -243,12 +243,24 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newImport(pos: Position): TermSymbol =
newTermSymbol(nme.IMPORT, pos)
+ def newModuleVarSymbol(accessor: Symbol): TermSymbol = {
+ val newName = nme.moduleVarName(accessor.name.toTermName)
+ val newFlags = MODULEVAR | ( if (this.isClass) PrivateLocal | SYNTHETIC else 0 )
+ val newInfo = accessor.tpe.finalResultType
+ val mval = newVariable(newName, accessor.pos.focus, newFlags) addAnnotation VolatileAttr
+
+ if (this.isClass)
+ mval setInfoAndEnter newInfo
+ else
+ mval setInfo newInfo
+ }
+
final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol]
final def newModuleAndClassSymbol(name: Name, pos: Position, flags0: FlagSet): (ModuleSymbol, ClassSymbol) = {
val flags = flags0 | MODULE
- val m = newModuleSymbol(name, pos, flags)
+ val m = newModuleSymbol(name.toTermName, pos, flags)
val c = newModuleClass(name.toTypeName, pos, flags & ModuleToClassFlags)
connectModuleToClass(m, c)
(m, c)
@@ -3051,7 +3063,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) {
override def name_=(name: Name) {
- assert(false, "Cannot set name of RefinementClassSymbol to " + name)
+ abort("Cannot set name of RefinementClassSymbol to " + name)
super.name_=(name)
}
override def isRefinementClass = true
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 072e94e069..f3aa37bd15 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -127,11 +127,6 @@ abstract class TreeGen extends macros.TreeBuilder {
if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym)
else mkAttributedIdent(sym)
- /** Builds an untyped reference to given symbol. */
- def mkUnattributedRef(sym: Symbol): Tree =
- if (sym.owner.isClass) Select(This(sym.owner), sym)
- else Ident(sym)
-
/** Replaces tree type with a stable type if possible */
def stabilize(tree: Tree): Tree = {
for(tp <- stableTypeFor(tree)) tree.tpe = tp
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 4f60d9cabc..13b761086c 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -184,29 +184,26 @@ abstract class TreeInfo {
def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name.toTermName)) != NoSymbol
tree match {
- case Ident(_) => isVar
- case Select(_, _) => isVar || isGetter
- case _ =>
- methPart(tree) match {
- case Select(qual, nme.apply) => qual.tpe.member(nme.update) != NoSymbol
- case _ => false
- }
+ case Ident(_) => isVar
+ case Select(_, _) => isVar || isGetter
+ case Applied(Select(qual, nme.apply), _, _) => qual.tpe.member(nme.update) != NoSymbol
+ case _ => false
}
}
/** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
* same object?
*/
- def isSelfConstrCall(tree: Tree): Boolean = methPart(tree) match {
- case Ident(nme.CONSTRUCTOR)
- | Select(This(_), nme.CONSTRUCTOR) => true
+ def isSelfConstrCall(tree: Tree): Boolean = tree match {
+ case Applied(Ident(nme.CONSTRUCTOR), _, _) => true
+ case Applied(Select(This(_), nme.CONSTRUCTOR), _, _) => true
case _ => false
}
/** Is tree a super constructor call?
*/
- def isSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
- case Select(Super(_, _), nme.CONSTRUCTOR) => true
+ def isSuperConstrCall(tree: Tree): Boolean = tree match {
+ case Applied(Select(Super(_, _), nme.CONSTRUCTOR), _, _) => true
case _ => false
}
@@ -332,6 +329,9 @@ abstract class TreeInfo {
def preSuperFields(stats: List[Tree]): List[ValDef] =
stats collect { case vd: ValDef if isEarlyValDef(vd) => vd }
+ def hasUntypedPreSuperFields(stats: List[Tree]): Boolean =
+ preSuperFields(stats) exists (_.tpt.isEmpty)
+
def isEarlyDef(tree: Tree) = tree match {
case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER
case ValDef(mods, _, _, _) => mods hasFlag PRESUPER
@@ -392,22 +392,6 @@ abstract class TreeInfo {
case _ => false
}
- /** If this tree represents a type application (after unwrapping
- * any applies) the first type argument. Otherwise, EmptyTree.
- */
- def firstTypeArg(tree: Tree): Tree = tree match {
- case Apply(fn, _) => firstTypeArg(fn)
- case TypeApply(_, targ :: _) => targ
- case _ => EmptyTree
- }
-
- /** If this tree represents a type application the type arguments. Otherwise Nil.
- */
- def typeArguments(tree: Tree): List[Tree] = tree match {
- case TypeApply(_, targs) => targs
- case _ => Nil
- }
-
/** If this tree has type parameters, those. Otherwise Nil.
*/
def typeParameters(tree: Tree): List[TypeDef] = tree match {
@@ -522,31 +506,126 @@ abstract class TreeInfo {
def isSynthCaseSymbol(sym: Symbol) = sym hasAllFlags SYNTH_CASE_FLAGS
def hasSynthCaseSymbol(t: Tree) = t.symbol != null && isSynthCaseSymbol(t.symbol)
+ def isTraitRef(tree: Tree): Boolean = {
+ val sym = if (tree.tpe != null) tree.tpe.typeSymbol else null
+ ((sym ne null) && sym.initialize.isTrait)
+ }
- /** The method part of an application node
+ /** Applications in Scala can have one of the following shapes:
+ *
+ * 1) naked core: Ident(_) or Select(_, _) or basically anything else
+ * 2) naked core with targs: TypeApply(core, targs) or AppliedTypeTree(core, targs)
+ * 3) apply or several applies wrapping a core: Apply(core, _), or Apply(Apply(core, _), _), etc
+ *
+ * This class provides different ways to decompose applications and simplifies their analysis.
+ *
+ * ***Examples***
+ * (TypeApply in the examples can be replaced with AppliedTypeTree)
+ *
+ * Ident(foo):
+ * * callee = Ident(foo)
+ * * core = Ident(foo)
+ * * targs = Nil
+ * * argss = Nil
+ *
+ * TypeApply(foo, List(targ1, targ2...))
+ * * callee = TypeApply(foo, List(targ1, targ2...))
+ * * core = foo
+ * * targs = List(targ1, targ2...)
+ * * argss = Nil
+ *
+ * Apply(foo, List(arg1, arg2...))
+ * * callee = foo
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg1, arg2...))
+ *
+ * Apply(Apply(foo, List(arg21, arg22, ...)), List(arg11, arg12...))
+ * * callee = foo
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg11, arg12...), List(arg21, arg22, ...))
+ *
+ * Apply(Apply(TypeApply(foo, List(targs1, targs2, ...)), List(arg21, arg22, ...)), List(arg11, arg12...))
+ * * callee = TypeApply(foo, List(targs1, targs2, ...))
+ * * core = foo
+ * * targs = Nil
+ * * argss = List(List(arg11, arg12...), List(arg21, arg22, ...))
*/
- def methPart(tree: Tree): Tree = tree match {
- case Apply(fn, _) => methPart(fn)
- case TypeApply(fn, _) => methPart(fn)
- case AppliedTypeTree(fn, _) => methPart(fn)
- case _ => tree
+ class Applied(val tree: Tree) {
+ /** The tree stripped of the possibly nested applications.
+ * The original tree if it's not an application.
+ */
+ def callee: Tree = {
+ def loop(tree: Tree): Tree = tree match {
+ case Apply(fn, _) => loop(fn)
+ case tree => tree
+ }
+ loop(tree)
+ }
+
+ /** The `callee` unwrapped from type applications.
+ * The original `callee` if it's not a type application.
+ */
+ def core: Tree = callee match {
+ case TypeApply(fn, _) => fn
+ case AppliedTypeTree(fn, _) => fn
+ case tree => tree
+ }
+
+ /** The type arguments of the `callee`.
+ * `Nil` if the `callee` is not a type application.
+ */
+ def targs: List[Tree] = callee match {
+ case TypeApply(_, args) => args
+ case AppliedTypeTree(_, args) => args
+ case _ => Nil
+ }
+
+ /** (Possibly multiple lists of) value arguments of an application.
+ * `Nil` if the `callee` is not an application.
+ */
+ def argss: List[List[Tree]] = {
+ def loop(tree: Tree): List[List[Tree]] = tree match {
+ case Apply(fn, args) => loop(fn) :+ args
+ case _ => Nil
+ }
+ loop(tree)
+ }
+
+ /** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
+ * has depth 3. Continues through type applications (without counting them.)
+ */
+ def applyDepth: Int = {
+ def loop(tree: Tree): Int = tree match {
+ case Apply(fn, _) => 1 + loop(fn)
+ case TypeApply(fn, _) => loop(fn)
+ case AppliedTypeTree(fn, _) => loop(fn)
+ case _ => 0
+ }
+ loop(tree)
+ }
}
- /** The depth of the nested applies: e.g. Apply(Apply(Apply(_, _), _), _)
- * has depth 3. Continues through type applications (without counting them.)
+ /** Returns a wrapper that knows how to destructure and analyze applications.
*/
- def applyDepth(tree: Tree): Int = tree match {
- case Apply(fn, _) => 1 + applyDepth(fn)
- case TypeApply(fn, _) => applyDepth(fn)
- case AppliedTypeTree(fn, _) => applyDepth(fn)
- case _ => 0
- }
- def firstArgument(tree: Tree): Tree = tree match {
- case Apply(fn, args) =>
- val f = firstArgument(fn)
- if (f == EmptyTree && !args.isEmpty) args.head else f
- case _ =>
- EmptyTree
+ def dissectApplied(tree: Tree) = new Applied(tree)
+
+ /** Destructures applications into important subparts described in `Applied` class,
+ * namely into: core, targs and argss (in the specified order).
+ *
+ * Trees which are not applications are also accepted. Their callee and core will
+ * be equal to the input, while targs and argss will be Nil.
+ *
+ * The provided extractors don't expose all the API of the `Applied` class.
+ * For advanced use, call `dissectApplied` explicitly and use its methods instead of pattern matching.
+ */
+ object Applied {
+ def unapply(applied: Applied): Option[(Tree, List[Tree], List[List[Tree]])] =
+ Some((applied.core, applied.targs, applied.argss))
+
+ def unapply(tree: Tree): Option[(Tree, List[Tree], List[List[Tree]])] =
+ unapply(dissectApplied(tree))
}
/** Does list of trees start with a definition of
@@ -643,7 +722,7 @@ abstract class TreeInfo {
}
def unapply(tree: Tree) = refPart(tree) match {
- case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, typeArguments(tree)))
+ case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, dissectApplied(tree).targs))
case _ => None
}
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index f944e1d5d1..6dc1ff157c 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -37,6 +37,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def isDef = false
def isEmpty = false
+ def canHaveAttrs = true
/** The canonical way to test if a Tree represents a term.
*/
@@ -229,14 +230,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def isDef = true
}
- case object EmptyTree extends TermTree {
- val asList = List(this)
- super.tpe_=(NoType)
- override def tpe_=(t: Type) =
- if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
- override def isEmpty = true
- }
-
abstract class MemberDef extends DefTree with MemberDefApi {
def mods: Modifiers
def keyword: String = this match {
@@ -392,6 +385,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
case class TypeApply(fun: Tree, args: List[Tree])
extends GenericApply with TypeApplyApi {
+
+ assert(fun.isTerm, fun)
+
override def symbol: Symbol = fun.symbol
override def symbol_=(sym: Symbol) { fun.symbol = sym }
}
@@ -437,7 +433,11 @@ trait Trees extends api.Trees { self: SymbolTable =>
object This extends ThisExtractor
case class Select(qualifier: Tree, name: Name)
- extends RefTree with SelectApi
+ extends RefTree with SelectApi {
+
+ // !!! assert disabled due to test case pos/annotDepMethType.scala triggering it.
+ // assert(qualifier.isTerm, qualifier)
+ }
object Select extends SelectExtractor
case class Ident(name: Name) extends RefTree with IdentContextApi {
@@ -469,7 +469,10 @@ trait Trees extends api.Trees { self: SymbolTable =>
object SingletonTypeTree extends SingletonTypeTreeExtractor
case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
- extends RefTree with TypTree with SelectFromTypeTreeApi
+ extends RefTree with TypTree with SelectFromTypeTreeApi {
+
+ assert(qualifier.isType, qualifier)
+ }
object SelectFromTypeTree extends SelectFromTypeTreeExtractor
case class CompoundTypeTree(templ: Template)
@@ -478,6 +481,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
case class AppliedTypeTree(tpt: Tree, args: List[Tree])
extends TypTree with AppliedTypeTreeApi {
+
+ assert(tpt.isType, tpt)
+
override def symbol: Symbol = tpt.symbol
override def symbol_=(sym: Symbol) { tpt.symbol = sym }
}
@@ -597,6 +603,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
// TODO: ApplyConstructor ???
+ case self.pendingSuperCall => self.pendingSuperCall
case _ => new Apply(fun, args)
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
@@ -958,12 +965,23 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
- object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
- override def isEmpty = true
+ trait CannotHaveAttrs extends Tree {
+ override def canHaveAttrs = false
+
+ private def unsupported(what: String, args: Any*) =
+ throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString)
+
super.setPos(NoPosition)
- override def setPos(pos: Position) = { assert(false); this }
+ override def setPos(pos: Position) = unsupported("setPos", pos)
+
+ super.setType(NoType)
+ override def tpe_=(t: Type) = if (t != NoType) unsupported("tpe_=", t)
}
+ case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) }
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs
+ object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with CannotHaveAttrs
+
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
@@ -1031,6 +1049,9 @@ trait Trees extends api.Trees { self: SymbolTable =>
def New(tpe: Type, args: Tree*): Tree =
ApplyConstructor(TypeTree(tpe), args.toList)
+ def New(tpe: Type, argss: List[List[Tree]]): Tree =
+ New(TypeTree(tpe), argss)
+
def New(sym: Symbol, args: Tree*): Tree =
New(sym.tpe, args: _*)
@@ -1111,7 +1132,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
traverse(annot); traverse(arg)
case Template(parents, self, body) =>
traverseTrees(parents)
- if (!self.isEmpty) traverse(self)
+ if (self ne emptyValDef) traverse(self)
traverseStats(body, tree.symbol)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 09fc534d8a..58dd7f3a03 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1337,7 +1337,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (!sym.isClass) {
// SI-6640 allow StubSymbols to reveal what's missing from the classpath before we trip the assertion.
sym.failIfStub()
- assert(false, sym)
+ abort(s"ThisType($sym) for sym which is not a class")
}
override def isTrivial: Boolean = sym.isPackageClass
@@ -6797,7 +6797,7 @@ trait Types extends api.Types { self: SymbolTable =>
case ExistentialType(tparams, quantified) :: rest =>
mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _))
case _ =>
- assert(false, tps); None
+ abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
}
def addMember(thistp: Type, tp: Type, sym: Symbol): Unit = addMember(thistp, tp, sym, AnyDepth)
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 5a0454a569..5b01b5ffa5 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -308,7 +308,7 @@ abstract class UnPickler {
if (isModuleRoot) moduleRoot setFlag pflags
else owner.newLinkedModule(clazz, pflags)
case VALsym =>
- if (isModuleRoot) { assert(false); NoSymbol }
+ if (isModuleRoot) { abort(s"VALsym at module root: owner = $owner, name = $name") }
else owner.newTermSymbol(name.toTermName, NoPosition, pflags)
case _ =>
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
index 0c1640ceb9..6dc6a0f7b8 100644
--- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala
+++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala
@@ -19,8 +19,7 @@ trait UnCurry {
case MethodType(params, MethodType(params1, restpe)) =>
apply(MethodType(params ::: params1, restpe))
case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) =>
- assert(false, "unexpected curried method types with intervening existential")
- tp0
+ abort("unexpected curried method types with intervening existential")
case MethodType(h :: t, restpe) if h.isImplicit =>
apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe))
case NullaryMethodType(restpe) =>
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index bbc95feaab..1c29cabe24 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -7,6 +7,7 @@
package scala.reflect.internal.util
import scala.reflect.ClassTag
+import scala.reflect.internal.FatalError
import scala.reflect.macros.Attachments
object Position {
@@ -269,7 +270,7 @@ class OffsetPosition(override val source: SourceFile, override val point: Int) e
/** new for position ranges */
class RangePosition(source: SourceFile, override val start: Int, point: Int, override val end: Int)
extends OffsetPosition(source, point) {
- if (start > end) assert(false, "bad position: "+show)
+ if (start > end) sys.error("bad position: "+show)
override def isRange: Boolean = true
override def isOpaqueRange: Boolean = true
override def startOrPoint: Int = start
diff --git a/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala
new file mode 100644
index 0000000000..e7579229b2
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala
@@ -0,0 +1,40 @@
+package scala.reflect
+package internal
+package util
+
+trait StripMarginInterpolator {
+ def stringContext: StringContext
+
+ /**
+ * A safe combination of `[[scala.collection.immutable.StringLike#stripMargin]]
+ * and [[scala.StringContext#raw]].
+ *
+ * The margin of each line is defined by whitespace leading up to a '|' character.
+ * This margin is stripped '''before''' the arguments are interpolated into to string.
+ *
+ * String escape sequences are '''not''' processed; this interpolater is designed to
+ * be used with triple quoted Strings.
+ *
+ * {{{
+ * scala> val foo = "f|o|o"
+ * foo: String = f|o|o
+ * scala> sm"""|${foo}
+ * |"""
+ * res0: String =
+ * "f|o|o
+ * "
+ * }}}
+ */
+ final def sm(args: Any*): String = {
+ def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringLike#isLineBreak
+ def stripTrailingPart(s: String) = {
+ val (pre, post) = s.span(c => !isLineBreak(c))
+ pre + post.stripMargin
+ }
+ val stripped: List[String] = stringContext.parts.toList match {
+ case head :: tail => head.stripMargin :: (tail map stripTrailingPart)
+ case Nil => Nil
+ }
+ new StringContext(stripped: _*).raw(args: _*)
+ }
+}
diff --git a/src/reflect/scala/reflect/internal/util/package.scala b/src/reflect/scala/reflect/internal/util/package.scala
index 83c8bf67ba..1ca57b81ed 100644
--- a/src/reflect/scala/reflect/internal/util/package.scala
+++ b/src/reflect/scala/reflect/internal/util/package.scala
@@ -31,4 +31,8 @@ package object util {
}
else shortenName(name)
}
+ /**
+ * Adds the `sm` String interpolator to a [[scala.StringContext]].
+ */
+ implicit class StringContextStripMarginOps(val stringContext: StringContext) extends StripMarginInterpolator
}
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index d264cc06b4..f6ce19e1d7 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -126,11 +126,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
private def ErrorStaticModule(sym: Symbol) = throw new ScalaReflectionException(s"$sym is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
private def ErrorNotMember(sym: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a member of $owner, you provided ${sym.kindString} ${sym.fullName}")
private def ErrorNotField(sym: Symbol) = throw new ScalaReflectionException(s"expected a field or an accessor method symbol, you provided $sym")
- private def ErrorNonExistentField(sym: Symbol) = throw new ScalaReflectionException(s"""
- |Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method
- |note that private parameters of class constructors don't get mapped onto fields and/or accessors,
- |unless they are used outside of their declaring constructors.
- """.trim.stripMargin)
+ private def ErrorNonExistentField(sym: Symbol) = throw new ScalaReflectionException(
+ sm"""Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method
+ |note that private parameters of class constructors don't get mapped onto fields and/or accessors,
+ |unless they are used outside of their declaring constructors.""")
private def ErrorSetImmutableField(sym: Symbol) = throw new ScalaReflectionException(s"cannot set an immutable field ${sym.name}")
private def ErrorNotConstructor(sym: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a constructor of $owner, you provided $sym")
private def ErrorFree(member: Symbol, freeType: Symbol) = throw new ScalaReflectionException(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a weak type ${freeType.name}")
@@ -414,7 +413,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
case sym if sym.owner.isPrimitiveValueClass => invokePrimitiveMethod
case sym if sym == Predef_classOf => fail("Predef.classOf is a compile-time function")
case sym if sym.isTermMacro => fail(s"${symbol.fullName} is a macro, i.e. a compile-time function")
- case _ => assert(false, this)
+ case _ => abort(s"unsupported symbol $symbol when invoking $this")
}
}
}
@@ -466,7 +465,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
staticSingletonInstance(classLoader, symbol.fullName)
else
if (outer == null) staticSingletonInstance(classToJava(symbol.moduleClass.asClass))
- else innerSingletonInstance(outer, symbol.name)
+ else innerSingletonInstance(outer, symbol.name.toString)
}
override def toString = s"module mirror for ${symbol.fullName} (bound to $outer)"
}
@@ -535,8 +534,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val result = anns find (_.annotationType == annotClass)
if (result.isEmpty && (anns exists (_.annotationType.getName == name)))
throw new ClassNotFoundException(
- s"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)})
- |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""".stripMargin)
+ sm"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)})
+ |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""")
result
}
def loadBytes[T: ClassTag](name: String): Option[T] =
@@ -935,8 +934,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
javaTypeToValueClass(jclazz) orElse lookupClass
assert (cls.isType,
- s"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"}
- | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""".stripMargin)
+ sm"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"}
+ | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""")
cls.asClass
}
diff --git a/test/attic/files/cli/test1/Main.check.scalac b/test/attic/files/cli/test1/Main.check.scalac
index 8465810d0b..5561cc1ead 100644
--- a/test/attic/files/cli/test1/Main.check.scalac
+++ b/test/attic/files/cli/test1/Main.check.scalac
@@ -1,7 +1,7 @@
scalac error: bad option: '-dd'
scalac -help gives more information
Usage: scalac <options | source files>
-where possible options include:
+where possible options include:
-doc Generate documentation
-g:<g> Generate debugging info (none,source,line,vars,notc)
-nowarn Generate no warnings
@@ -15,10 +15,8 @@ where possible options include:
-encoding <encoding> Specify character encoding used by source files
-windowtitle <windowtitle> Specify window title of generated HTML documentation
-documenttitle <documenttitle> Specify document title of generated HTML documentation
- -target:<target> Specify which backend to use (jvm-1.5,msil)
+ -target:<target> Specify which backend to use (jvm-1.5)
-migrate Assist in migrating from Scala version 1.0
- -o <file> Name of the output assembly (only relevant with -target:msil)
- -r <path> List of assemblies referenced by the program (only relevant with -target:msil)
-debug Output debugging messages
-deprecation enable detailed deprecation warnings
-unchecked enable detailed unchecked warnings
diff --git a/test/attic/files/cli/test2/Main.check.scalac b/test/attic/files/cli/test2/Main.check.scalac
index 8465810d0b..5561cc1ead 100644
--- a/test/attic/files/cli/test2/Main.check.scalac
+++ b/test/attic/files/cli/test2/Main.check.scalac
@@ -1,7 +1,7 @@
scalac error: bad option: '-dd'
scalac -help gives more information
Usage: scalac <options | source files>
-where possible options include:
+where possible options include:
-doc Generate documentation
-g:<g> Generate debugging info (none,source,line,vars,notc)
-nowarn Generate no warnings
@@ -15,10 +15,8 @@ where possible options include:
-encoding <encoding> Specify character encoding used by source files
-windowtitle <windowtitle> Specify window title of generated HTML documentation
-documenttitle <documenttitle> Specify document title of generated HTML documentation
- -target:<target> Specify which backend to use (jvm-1.5,msil)
+ -target:<target> Specify which backend to use (jvm-1.5)
-migrate Assist in migrating from Scala version 1.0
- -o <file> Name of the output assembly (only relevant with -target:msil)
- -r <path> List of assemblies referenced by the program (only relevant with -target:msil)
-debug Output debugging messages
-deprecation enable detailed deprecation warnings
-unchecked enable detailed unchecked warnings
diff --git a/test/attic/files/cli/test3/Main.check.scalac b/test/attic/files/cli/test3/Main.check.scalac
index 8465810d0b..5561cc1ead 100644
--- a/test/attic/files/cli/test3/Main.check.scalac
+++ b/test/attic/files/cli/test3/Main.check.scalac
@@ -1,7 +1,7 @@
scalac error: bad option: '-dd'
scalac -help gives more information
Usage: scalac <options | source files>
-where possible options include:
+where possible options include:
-doc Generate documentation
-g:<g> Generate debugging info (none,source,line,vars,notc)
-nowarn Generate no warnings
@@ -15,10 +15,8 @@ where possible options include:
-encoding <encoding> Specify character encoding used by source files
-windowtitle <windowtitle> Specify window title of generated HTML documentation
-documenttitle <documenttitle> Specify document title of generated HTML documentation
- -target:<target> Specify which backend to use (jvm-1.5,msil)
+ -target:<target> Specify which backend to use (jvm-1.5)
-migrate Assist in migrating from Scala version 1.0
- -o <file> Name of the output assembly (only relevant with -target:msil)
- -r <path> List of assemblies referenced by the program (only relevant with -target:msil)
-debug Output debugging messages
-deprecation enable detailed deprecation warnings
-unchecked enable detailed unchecked warnings
diff --git a/test/disabled/presentation/akka.flags b/test/disabled/presentation/akka.flags
index 56d026a62d..9bf2878f62 100644
--- a/test/disabled/presentation/akka.flags
+++ b/test/disabled/presentation/akka.flags
@@ -12,7 +12,7 @@
# running partest from. Run it from the root scala checkout for these files to resolve correctly
# (by default when running 'ant test', or 'test/partest'). Paths use Unix separators, the test
# framework translates them to the platform dependent representation.
-# -bootclasspath lib/scala-compiler.jar:lib/scala-library.jar:lib/fjbg.jar
+# -bootclasspath lib/scala-compiler.jar:lib/scala-library.jar
# the following line would test using the quick compiler
-# -bootclasspath build/quick/classes/compiler:build/quick/classes/library:lib/fjbg.jar
+# -bootclasspath build/quick/classes/compiler:build/quick/classes/library
diff --git a/test/disabled/presentation/simple-tests.opts b/test/disabled/presentation/simple-tests.opts
index 8529bbf1a0..d651316984 100644
--- a/test/disabled/presentation/simple-tests.opts
+++ b/test/disabled/presentation/simple-tests.opts
@@ -12,7 +12,7 @@
# running partest from. Run it from the root scala checkout for these files to resolve correctly
# (by default when running 'ant test', or 'test/partest'). Paths use Unix separators, the test
# framework translates them to the platform dependent representation.
--bootclasspath lib/scala-compiler.jar:lib/scala-library.jar:lib/fjbg.jar
+-bootclasspath lib/scala-compiler.jar:lib/scala-library.jar
# the following line would test using the quick compiler
-# -bootclasspath build/quick/classes/compiler:build/quick/classes/library:lib/fjbg.jar
+# -bootclasspath build/quick/classes/compiler:build/quick/classes/library
diff --git a/test/files/ant/imported.xml b/test/files/ant/imported.xml
index 5a4dfc319b..182c80aadf 100644
--- a/test/files/ant/imported.xml
+++ b/test/files/ant/imported.xml
@@ -56,7 +56,6 @@ INITIALISATION
<property name="scala.dir" value="${quick.dir}"/>
<property name="scala-library.lib" value="${scala.dir}/classes/library/"/>
<property name="scala-compiler.lib" value="${scala.dir}/classes/compiler/"/>
- <property name="fjbg.lib" value="${project.dir}/lib/fjbg.jar"/>
</target>
<target name="pack.init" if="pack.binary">
@@ -67,7 +66,6 @@ INITIALISATION
<property name="scala.dir" value="${pack.dir}"/>
<property name="scala-library.lib" value="${scala.dir}/lib/scala-library.jar"/>
<property name="scala-compiler.lib" value="${scala.dir}/lib/scala-compiler.jar"/>
- <property name="fjbg.lib" value=""/>
</target>
<target name="latest.init" if="latest.binary">
@@ -78,7 +76,6 @@ INITIALISATION
<property name="scala.dir" value="${latest.dir}"/>
<property name="scala-library.lib" value="${scala.dir}/lib/scala-library.jar"/>
<property name="scala-compiler.lib" value="${scala.dir}/lib/scala-compiler.jar"/>
- <property name="fjbg.lib" value=""/>
</target>
<target name="installed.init" if="installed.binary">
@@ -89,7 +86,6 @@ INITIALISATION
<property name="scala.dir" value="${installed.dir}"/>
<property name="scala-library.lib" value="${scala.dir}/lib/scala-library.jar"/>
<property name="scala-compiler.lib" value="${scala.dir}/lib/scala-compiler.jar"/>
- <property name="fjbg.lib" value=""/>
</target>
<target name="init" depends="quick.init, pack.init, latest.init, installed.init">
@@ -98,7 +94,6 @@ INITIALISATION
<path id="scala.classpath">
<pathelement location="${scala-library.lib}"/>
<pathelement location="${scala-compiler.lib}"/>
- <pathelement location="${fjbg.lib}"/> <!-- only present for 'quick' -->
</path>
<fail message="Scala library '${scala-library.lib}' or '${scala-compiler.lib}' is missing/broken">
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
index 34b64938b4..f2c47aad77 100644
--- a/test/files/jvm/serialization.scala
+++ b/test/files/jvm/serialization.scala
@@ -604,6 +604,7 @@ object Test {
Test7
Test8
Test9_parallel
+ Test10_util
}
}
@@ -669,3 +670,17 @@ object Test9_parallel {
throw e
}
}
+
+//############################################################################
+// Test classes in package scala.util
+
+object Test10_util {
+ import scala.util.Random
+ def rep[A](n: Int)(f: => A) { if (n > 0) { f; rep(n-1)(f) } }
+
+ try {
+ val random = new Random(345)
+ val random2: Random = read(write(random))
+ rep(5) { assert(random.nextInt == random2.nextInt) }
+ }
+}
diff --git a/test/files/neg/anyval-anyref-parent.check b/test/files/neg/anyval-anyref-parent.check
index fe20e5de81..8c2aa36583 100644
--- a/test/files/neg/anyval-anyref-parent.check
+++ b/test/files/neg/anyval-anyref-parent.check
@@ -3,7 +3,7 @@ trait Foo2 extends AnyVal // fail
^
anyval-anyref-parent.scala:5: error: Any does not have a constructor
class Bar1 extends Any // fail
- ^
+ ^
anyval-anyref-parent.scala:6: error: value class needs to have exactly one public val parameter
class Bar2(x: Int) extends AnyVal // fail
^
diff --git a/test/files/neg/case-collision.check b/test/files/neg/case-collision.check
new file mode 100644
index 0000000000..22cf105a4f
--- /dev/null
+++ b/test/files/neg/case-collision.check
@@ -0,0 +1,12 @@
+case-collision.scala:5: warning: Class foo.BIPPY differs only in case from foo.Bippy. Such classes will overwrite one another on case-insensitive filesystems.
+class BIPPY
+ ^
+case-collision.scala:11: warning: Class foo.HyRaX$ differs only in case from foo.Hyrax$. Such classes will overwrite one another on case-insensitive filesystems.
+object HyRaX
+ ^
+case-collision.scala:8: warning: Class foo.DINGO$ differs only in case from foo.Dingo$. Such classes will overwrite one another on case-insensitive filesystems.
+object DINGO
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+three warnings found
+one error found
diff --git a/test/files/neg/case-collision.flags b/test/files/neg/case-collision.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/case-collision.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/case-collision.scala b/test/files/neg/case-collision.scala
new file mode 100644
index 0000000000..241169a77a
--- /dev/null
+++ b/test/files/neg/case-collision.scala
@@ -0,0 +1,11 @@
+package foo
+
+class Bippy
+
+class BIPPY
+
+object Dingo
+object DINGO
+
+case class Hyrax()
+object HyRaX
diff --git a/test/files/neg/cyclics-import.check b/test/files/neg/cyclics-import.check
index ef355fab0a..be09fca374 100644
--- a/test/files/neg/cyclics-import.check
+++ b/test/files/neg/cyclics-import.check
@@ -3,13 +3,4 @@ Note: this is often due in part to a class depending on a definition nested with
If applicable, you may wish to try moving some members into another object.
import User.UserStatus._
^
-cyclics-import.scala:12: error: not found: type Value
- type UserStatus = Value
- ^
-cyclics-import.scala:14: error: not found: value Value
- val Active = Value("1")
- ^
-cyclics-import.scala:15: error: not found: value Value
- val Disabled = Value("2")
- ^
-four errors found
+one error found
diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check
index a61231a27a..9b7ea5556a 100644
--- a/test/files/neg/gadts1.check
+++ b/test/files/neg/gadts1.check
@@ -1,6 +1,6 @@
-gadts1.scala:20: error: class Cell of type Test.Cell does not take type parameters.
+gadts1.scala:20: error: Test.Cell[a] does not take parameters
case Cell[a](x: Int) => c.x = 5
- ^
+ ^
gadts1.scala:20: error: type mismatch;
found : Int(5)
required: a
diff --git a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
index 845a168ff2..7a7293422e 100644
--- a/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
+++ b/test/files/neg/macro-invalidsig-implicit-params/Impls_Macros_1.scala
@@ -5,10 +5,10 @@ object Impls {
def foo_targs[T, U: c.WeakTypeTag](c: Ctx)(implicit x: c.Expr[Int]) = {
import c.{prefix => prefix}
import c.universe._
- val body = Block(
+ val body = Block(List(
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))),
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + implicitly[c.WeakTypeTag[U]].tpe))))),
Literal(Constant(())))
c.Expr[Unit](body)
}
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index f3c45a6aa0..6f9dc7d127 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -100,7 +100,7 @@ Error occurred in an application involving default arguments.
^
names-defaults-neg.scala:86: error: module extending its companion class cannot use default constructor arguments
object C extends C()
- ^
+ ^
names-defaults-neg.scala:90: error: deprecated parameter name x has to be distinct from any other parameter name (deprecated or not).
def deprNam1(x: Int, @deprecatedName('x) y: String) = 0
^
diff --git a/test/files/neg/protected-constructors.check b/test/files/neg/protected-constructors.check
index f137158ed6..e295917050 100644
--- a/test/files/neg/protected-constructors.check
+++ b/test/files/neg/protected-constructors.check
@@ -19,7 +19,4 @@ protected-constructors.scala:15: error: class Foo3 in object Ding cannot be acce
object Ding in package dingus where target is defined
class Bar3 extends Ding.Foo3("abc")
^
-protected-constructors.scala:15: error: too many arguments for constructor Object: ()Object
- class Bar3 extends Ding.Foo3("abc")
- ^
-5 errors found
+four errors found
diff --git a/test/files/neg/serialversionuid-not-const.check b/test/files/neg/serialversionuid-not-const.check
new file mode 100644
index 0000000000..9c383d97ad
--- /dev/null
+++ b/test/files/neg/serialversionuid-not-const.check
@@ -0,0 +1,10 @@
+serialversionuid-not-const.scala:1: error: annotation argument needs to be a constant; found: 13L.toLong
+@SerialVersionUID(13l.toLong) class C1 extends Serializable
+ ^
+serialversionuid-not-const.scala:3: error: annotation argument needs to be a constant; found: 13.asInstanceOf[Long]
+@SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable
+ ^
+serialversionuid-not-const.scala:4: error: annotation argument needs to be a constant; found: Test.bippy
+@SerialVersionUID(Test.bippy) class C4 extends Serializable
+ ^
+three errors found
diff --git a/test/files/neg/serialversionuid-not-const.scala b/test/files/neg/serialversionuid-not-const.scala
new file mode 100644
index 0000000000..f0e3ef4e7e
--- /dev/null
+++ b/test/files/neg/serialversionuid-not-const.scala
@@ -0,0 +1,16 @@
+@SerialVersionUID(13l.toLong) class C1 extends Serializable
+@SerialVersionUID(13l) class C2 extends Serializable
+@SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable
+@SerialVersionUID(Test.bippy) class C4 extends Serializable
+
+object Test {
+ val bippy = 13L
+
+ def show(c: Class[_]) = println(java.io.ObjectStreamClass.lookup(c).getSerialVersionUID)
+ def main(args: Array[String]): Unit = {
+ show(classOf[C1])
+ show(classOf[C2])
+ show(classOf[C3])
+ show(classOf[C4])
+ }
+}
diff --git a/test/files/neg/t1672b.check b/test/files/neg/t1672b.check
new file mode 100644
index 0000000000..60ccf77174
--- /dev/null
+++ b/test/files/neg/t1672b.check
@@ -0,0 +1,16 @@
+t1672b.scala:3: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position
+ def bar : Nothing = {
+ ^
+t1672b.scala:14: error: could not optimize @tailrec annotated method baz: it contains a recursive call not in tail position
+ def baz : Nothing = {
+ ^
+t1672b.scala:29: error: could not optimize @tailrec annotated method boz: it contains a recursive call not in tail position
+ case _: Throwable => boz; ???
+ ^
+t1672b.scala:34: error: could not optimize @tailrec annotated method bez: it contains a recursive call not in tail position
+ def bez : Nothing = {
+ ^
+t1672b.scala:46: error: could not optimize @tailrec annotated method bar: it contains a recursive call not in tail position
+ else 1 + (try {
+ ^
+5 errors found
diff --git a/test/files/neg/t1672b.scala b/test/files/neg/t1672b.scala
new file mode 100644
index 0000000000..0ccdd03633
--- /dev/null
+++ b/test/files/neg/t1672b.scala
@@ -0,0 +1,52 @@
+object Test {
+ @annotation.tailrec
+ def bar : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar
+ } finally {
+ bar
+ }
+ }
+
+ @annotation.tailrec
+ def baz : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => baz
+ } finally {
+ ???
+ }
+ }
+
+ @annotation.tailrec
+ def boz : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => boz; ???
+ }
+ }
+
+ @annotation.tailrec
+ def bez : Nothing = {
+ try {
+ bez
+ } finally {
+ ???
+ }
+ }
+
+ // the `liftedTree` local method will prevent a tail call here.
+ @annotation.tailrec
+ def bar(i : Int) : Int = {
+ if (i == 0) 0
+ else 1 + (try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar(i - 1)
+ })
+ }
+}
diff --git a/test/files/neg/t2148.check b/test/files/neg/t2148.check
index 5113b48e51..27b5dce507 100644
--- a/test/files/neg/t2148.check
+++ b/test/files/neg/t2148.check
@@ -1,4 +1,4 @@
-t2148.scala:9: error: type A is not a stable prefix
+t2148.scala:9: error: A is not a legal prefix for a constructor
val b = new A with A#A1
^
one error found
diff --git a/test/files/neg/t409.check b/test/files/neg/t409.check
index 433d64d25d..0edc0d03cd 100644
--- a/test/files/neg/t409.check
+++ b/test/files/neg/t409.check
@@ -1,4 +1,4 @@
-t409.scala:6: error: traits or objects may not have parameters
+t409.scala:6: error: class Case1 needs to be a trait to be mixed in
class Toto extends Expr with Case1(12);
- ^
+ ^
one error found
diff --git a/test/files/neg/t5529.check b/test/files/neg/t5529.check
index 5d2175fa79..da3f84e1ec 100644
--- a/test/files/neg/t5529.check
+++ b/test/files/neg/t5529.check
@@ -4,7 +4,4 @@ t5529.scala:12: error: File is already defined as class File
t5529.scala:10: error: class type required but test.Test.File found
sealed class Dir extends File { }
^
-t5529.scala:10: error: test.Test.File does not have a constructor
- sealed class Dir extends File { }
- ^
-three errors found
+two errors found
diff --git a/test/files/neg/t5696.check b/test/files/neg/t5696.check
index 72b7781fc4..e0fb61b839 100644
--- a/test/files/neg/t5696.check
+++ b/test/files/neg/t5696.check
@@ -15,5 +15,5 @@ t5696.scala:38: error: too many argument lists for constructor invocation
^
t5696.scala:46: error: too many argument lists for constructor invocation
object x extends G(1)(2) {}
- ^
+ ^
6 errors found
diff --git a/test/files/neg/t5753.check b/test/files/neg/t5753.check
new file mode 100644
index 0000000000..76602de17d
--- /dev/null
+++ b/test/files/neg/t5753.check
@@ -0,0 +1,4 @@
+Test_2.scala:9: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
+ println(foo(42))
+ ^
+one error found
diff --git a/test/files/neg/t5753.flags b/test/files/neg/t5753.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/neg/t5753.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/neg/t5753/Impls$class.class b/test/files/neg/t5753/Impls$class.class
new file mode 100644
index 0000000000..476329174e
--- /dev/null
+++ b/test/files/neg/t5753/Impls$class.class
Binary files differ
diff --git a/test/files/neg/t5753/Impls.class b/test/files/neg/t5753/Impls.class
new file mode 100644
index 0000000000..dfcf89ed44
--- /dev/null
+++ b/test/files/neg/t5753/Impls.class
Binary files differ
diff --git a/test/files/neg/t5753/Impls_Macros_1.scala b/test/files/neg/t5753/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1d9c26458c
--- /dev/null
+++ b/test/files/neg/t5753/Impls_Macros_1.scala
@@ -0,0 +1,6 @@
+import scala.reflect.macros.{Context => Ctx}
+
+trait Impls {
+def impl(c: Ctx)(x: c.Expr[Any]) = x
+}
+
diff --git a/test/files/neg/t5753/Test_2.scala b/test/files/neg/t5753/Test_2.scala
new file mode 100644
index 0000000000..2369b18e76
--- /dev/null
+++ b/test/files/neg/t5753/Test_2.scala
@@ -0,0 +1,11 @@
+import scala.reflect.macros.{Context => Ctx}
+
+object Macros extends Impls {
+ def foo(x: Any) = macro impl
+}
+
+object Test extends App {
+ import Macros._
+ println(foo(42))
+}
+
diff --git a/test/files/neg/t6535.check b/test/files/neg/t6535.check
new file mode 100644
index 0000000000..1225ea70db
--- /dev/null
+++ b/test/files/neg/t6535.check
@@ -0,0 +1,6 @@
+t6535.scala:2: error: encountered unrecoverable cycle resolving import.
+Note: this is often due in part to a class depending on a definition nested within its companion.
+If applicable, you may wish to try moving some members into another object.
+ import Bs.B._
+ ^
+one error found
diff --git a/test/files/neg/t6535.scala b/test/files/neg/t6535.scala
new file mode 100644
index 0000000000..30a750311c
--- /dev/null
+++ b/test/files/neg/t6535.scala
@@ -0,0 +1,15 @@
+object As {
+ import Bs.B._
+
+ object A
+ extends scala.AnyRef // needed for the cycle;
+ // replacing with a locally defined closs doesn't
+ // hit the locked import and hence doesn't cycle.
+}
+
+object Bs {
+ import As.A._
+
+ object B
+ extends scala.AnyRef // scala.Immutable, ...
+}
diff --git a/test/files/neg/t6558.check b/test/files/neg/t6558.check
new file mode 100644
index 0000000000..1b39ef9986
--- /dev/null
+++ b/test/files/neg/t6558.check
@@ -0,0 +1,10 @@
+t6558.scala:19: error: not found: type classs
+ @classs
+ ^
+t6558.scala:22: error: not found: type typeparam
+ class D[@typeparam T]
+ ^
+t6558.scala:25: error: not found: type valueparam
+ @valueparam x: Any
+ ^
+three errors found
diff --git a/test/files/neg/t6558.scala b/test/files/neg/t6558.scala
new file mode 100644
index 0000000000..bdc441698f
--- /dev/null
+++ b/test/files/neg/t6558.scala
@@ -0,0 +1,27 @@
+class AnnotNotFound {
+ def foo(a: Any) = ()
+
+ foo {
+ // Not yet issued in the context of this file, see SI-6758
+ // This error is issued in t6558b.scala
+ @inargument
+ def foo = 0
+ foo
+ }
+
+ () => {
+ // As per above
+ @infunction
+ def foo = 0
+ ()
+ }
+
+ @classs
+ class C
+
+ class D[@typeparam T]
+
+ class E(
+ @valueparam x: Any
+ )
+}
diff --git a/test/files/neg/t6558b.check b/test/files/neg/t6558b.check
new file mode 100644
index 0000000000..cfa384fc08
--- /dev/null
+++ b/test/files/neg/t6558b.check
@@ -0,0 +1,7 @@
+t6558b.scala:5: error: not found: type inargument
+ @inargument
+ ^
+t6558b.scala:11: error: not found: type infunction
+ @infunction
+ ^
+two errors found
diff --git a/test/files/neg/t6558b.scala b/test/files/neg/t6558b.scala
new file mode 100644
index 0000000000..2aa06f69cf
--- /dev/null
+++ b/test/files/neg/t6558b.scala
@@ -0,0 +1,15 @@
+class AnnotNotFound {
+ def foo(a: Any) = ()
+
+ foo {
+ @inargument
+ def foo = 0
+ foo
+ }
+
+ () => {
+ @infunction
+ def foo = 0
+ ()
+ }
+}
diff --git a/test/files/neg/t6667.check b/test/files/neg/t6667.check
new file mode 100644
index 0000000000..43313fa4fe
--- /dev/null
+++ b/test/files/neg/t6667.check
@@ -0,0 +1,13 @@
+t6667.scala:8: error: ambiguous implicit values:
+ both value inScope1 in object Test of type => C
+ and value inScope2 in object Test of type => C
+ match expected type C
+ implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search.
+ ^
+t6667.scala:9: error: ambiguous implicit values:
+ both value inScope1 in object Test of type => C
+ and value inScope2 in object Test of type => C
+ match expected type C
+ implicitly[C] // ambiguity reported, rather than falling back to C.companion
+ ^
+two errors found
diff --git a/test/files/neg/t6667.scala b/test/files/neg/t6667.scala
new file mode 100644
index 0000000000..fb857ebd33
--- /dev/null
+++ b/test/files/neg/t6667.scala
@@ -0,0 +1,10 @@
+class C
+object C {
+ implicit def companion = new C
+}
+
+object Test {
+ implicit val inScope1, inScope2 = new C
+ implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search.
+ implicitly[C] // ambiguity reported, rather than falling back to C.companion
+}
diff --git a/test/files/neg/t6667b.check b/test/files/neg/t6667b.check
new file mode 100644
index 0000000000..99cea9a47c
--- /dev/null
+++ b/test/files/neg/t6667b.check
@@ -0,0 +1,13 @@
+t6667b.scala:16: error: ambiguous implicit values:
+ both value a in object Test of type => Test.Box
+ and value b of type Test.Box
+ match expected type Test.Box
+ new Test()
+ ^
+t6667b.scala:19: error: ambiguous implicit values:
+ both value a in object Test of type => Test.Box
+ and value b of type Test.Box
+ match expected type Test.Box
+ new Test()
+ ^
+two errors found
diff --git a/test/files/neg/t6667b.scala b/test/files/neg/t6667b.scala
new file mode 100644
index 0000000000..4e64e1af17
--- /dev/null
+++ b/test/files/neg/t6667b.scala
@@ -0,0 +1,25 @@
+object Test {
+ abstract class Box {
+ val value: Int
+ }
+
+ implicit val a: Box = new Box {
+ val value= 1
+ }
+
+ def main(args: Array[String]) {
+ implicit val b: Box= new Box {
+ val value= 2
+ }
+
+ new Object {
+ new Test()
+ }
+ // compare with:
+ new Test()
+ }
+}
+
+class Test()(implicit x: Test.Box) {
+ println(x.value)
+}
diff --git a/test/files/neg/t667.check b/test/files/neg/t667.check
index d4367bc87b..e68c6dea00 100644
--- a/test/files/neg/t667.check
+++ b/test/files/neg/t667.check
@@ -1,4 +1,4 @@
-t667.scala:8: error: class Ni inherits itself
+t667.scala:8: error: illegal cyclic reference involving class Ni
class Ni extends super.Ni with Ni;
- ^
+ ^
one error found
diff --git a/test/files/neg/t877.check b/test/files/neg/t877.check
index 5f25bd439c..c3d4ab6584 100644
--- a/test/files/neg/t877.check
+++ b/test/files/neg/t877.check
@@ -1,7 +1,7 @@
t877.scala:3: error: Invalid literal number
trait Foo extends A(22A, Bug!) {}
^
-t877.scala:3: error: parents of traits may not have parameters
+t877.scala:3: error: ')' expected but eof found.
trait Foo extends A(22A, Bug!) {}
- ^
+ ^
two errors found
diff --git a/test/files/pos/t1672.scala b/test/files/pos/t1672.scala
new file mode 100644
index 0000000000..5ee6bb1759
--- /dev/null
+++ b/test/files/pos/t1672.scala
@@ -0,0 +1,10 @@
+object Test {
+ @annotation.tailrec
+ def bar : Nothing = {
+ try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar
+ }
+ }
+}
diff --git a/test/files/pos/t5726.scala b/test/files/pos/t5726.scala
new file mode 100644
index 0000000000..b28ebd8674
--- /dev/null
+++ b/test/files/pos/t5726.scala
@@ -0,0 +1,17 @@
+import scala.language.dynamics
+
+class DynamicTest extends Dynamic {
+ def selectDynamic(name: String) = s"value of $name"
+ def updateDynamic(name: String)(value: Any) {
+ println(s"You have just updated property '$name' with value: $value")
+ }
+}
+
+object MyApp extends App {
+ def testing() {
+ val test = new DynamicTest
+ test.firstName = "John"
+ }
+
+ testing()
+}
diff --git a/test/files/pos/t5858.scala b/test/files/pos/t5858.scala
new file mode 100644
index 0000000000..f2b0f58d76
--- /dev/null
+++ b/test/files/pos/t5858.scala
@@ -0,0 +1,3 @@
+object Test {
+ new xml.Elem(null, null, xml.Null, xml.TopScope, Nil: _*) // was ambiguous
+}
diff --git a/test/files/pos/t5877.scala b/test/files/pos/t5877.scala
new file mode 100644
index 0000000000..c7827df99f
--- /dev/null
+++ b/test/files/pos/t5877.scala
@@ -0,0 +1,14 @@
+package foo {
+ class Foo
+
+ object Test {
+ new Foo().huzzah
+ }
+}
+
+package object foo {
+ // Crasher: No synthetics for method PimpedFoo2: synthetics contains
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
diff --git a/test/files/pos/t5877b.scala b/test/files/pos/t5877b.scala
new file mode 100644
index 0000000000..6b8cbd473e
--- /dev/null
+++ b/test/files/pos/t5877b.scala
@@ -0,0 +1,13 @@
+package foo
+
+class Foo
+
+object Test {
+ new Foo().huzzah
+}
+
+object `package` {
+ implicit class PimpedFoo2(value: Foo) {
+ def huzzah = ""
+ }
+}
diff --git a/test/files/pos/t6547.flags b/test/files/pos/t6547.flags
new file mode 100644
index 0000000000..c9b68d70dc
--- /dev/null
+++ b/test/files/pos/t6547.flags
@@ -0,0 +1 @@
+-optimise
diff --git a/test/files/pos/t6547.scala b/test/files/pos/t6547.scala
new file mode 100644
index 0000000000..53bd798219
--- /dev/null
+++ b/test/files/pos/t6547.scala
@@ -0,0 +1,6 @@
+trait ConfigurableDefault[@specialized V] {
+ def fillArray(arr: Array[V], v: V) = (arr: Any) match {
+ case x: Array[Int] => null
+ case x: Array[Long] => v.asInstanceOf[Long]
+ }
+}
diff --git a/test/files/pos/t6551.scala b/test/files/pos/t6551.scala
index fb68663809..8bb396a19f 100644
--- a/test/files/pos/t6551.scala
+++ b/test/files/pos/t6551.scala
@@ -1,4 +1,4 @@
-import language.dynamics
+import scala.language.dynamics
object Test {
def main(args: Array[String]) {
diff --git a/test/files/pos/t6595.flags b/test/files/pos/t6595.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/pos/t6595.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/pos/t6595.scala b/test/files/pos/t6595.scala
new file mode 100644
index 0000000000..437c0bcf05
--- /dev/null
+++ b/test/files/pos/t6595.scala
@@ -0,0 +1,18 @@
+import scala.annotation.switch
+
+class Foo extends {
+ final val b0 = 5
+} with AnyRef {
+ final val b1 = 10
+
+ // Using the @switch annotation as a means of testing that the
+ // type inferred for b0 is Int(5) and not Int. Only in the former
+ // case can a switch be generated.
+ def f(p: Int) = (p: @switch) match {
+ case `b0` => 1
+ case `b1` => 2
+ case 15 => 3
+ case 20 => 4
+ case _ => 5
+ }
+}
diff --git a/test/files/pos/t6712.scala b/test/files/pos/t6712.scala
new file mode 100644
index 0000000000..3c96eb14fb
--- /dev/null
+++ b/test/files/pos/t6712.scala
@@ -0,0 +1,5 @@
+class H {
+ object O
+
+ def foo() { object O }
+}
diff --git a/test/files/pos/t6722.scala b/test/files/pos/t6722.scala
new file mode 100644
index 0000000000..576746c915
--- /dev/null
+++ b/test/files/pos/t6722.scala
@@ -0,0 +1,11 @@
+import scala.language.dynamics
+
+class Dyn extends Dynamic {
+ def selectDynamic(s: String): Dyn = new Dyn
+ def get[T]: T = null.asInstanceOf[T]
+}
+
+object Foo {
+ val dyn = new Dyn
+ dyn.foo.bar.baz.get[String]
+}
diff --git a/test/files/run/idempotency-case-classes.check b/test/files/run/idempotency-case-classes.check
new file mode 100644
index 0000000000..d2fb8169cb
--- /dev/null
+++ b/test/files/run/idempotency-case-classes.check
@@ -0,0 +1,52 @@
+C(2,3)
+()
+{
+ case class C extends AnyRef with Product with Serializable {
+ <caseaccessor> <paramaccessor> private[this] val x: Int = _;
+ <stable> <caseaccessor> <accessor> <paramaccessor> def x: Int = C.this.x;
+ <caseaccessor> <paramaccessor> private[this] val y: Int = _;
+ <stable> <caseaccessor> <accessor> <paramaccessor> def y: Int = C.this.y;
+ def <init>(x: Int, y: Int): C = {
+ C.super.<init>();
+ ()
+ };
+ <synthetic> def copy(x: Int = x, y: Int = y): C = new C(x, y);
+ <synthetic> def copy$default$1: Int = C.this.x;
+ <synthetic> def copy$default$2: Int = C.this.y;
+ override <synthetic> def productPrefix: String = "C";
+ <synthetic> def productArity: Int = 2;
+ <synthetic> def productElement(x$1: Int): Any = x$1 match {
+ case 0 => C.this.x
+ case 1 => C.this.y
+ case _ => throw new IndexOutOfBoundsException(x$1.toString())
+ };
+ override <synthetic> def productIterator: Iterator[Any] = runtime.this.ScalaRunTime.typedProductIterator[Any](C.this);
+ <synthetic> def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[C]();
+ override <synthetic> def hashCode(): Int = {
+ <synthetic> var acc: Int = -889275714;
+ acc = Statics.this.mix(acc, x);
+ acc = Statics.this.mix(acc, y);
+ Statics.this.finalizeHash(acc, 2)
+ };
+ override <synthetic> def toString(): String = ScalaRunTime.this._toString(C.this);
+ override <synthetic> def equals(x$1: Any): Boolean = C.this.eq(x$1.asInstanceOf[Object]).||(x$1.isInstanceOf[C].&&({
+ <synthetic> val C$1: C = x$1.asInstanceOf[C];
+ C.this.x.==(C$1.x).&&(C.this.y.==(C$1.y)).&&(C$1.canEqual(C.this))
+ }))
+ };
+ <synthetic> object C extends scala.runtime.AbstractFunction2[Int,Int,C] with Serializable {
+ def <init>(): C.type = {
+ C.super.<init>();
+ ()
+ };
+ final override def toString(): String = "C";
+ case <synthetic> def apply(x: Int, y: Int): C = new C(x, y);
+ case <synthetic> def unapply(x$0: C): Option[(Int, Int)] = if (x$0.==(null))
+ scala.this.None
+ else
+ Some.apply[(Int, Int)](Tuple2.apply[Int, Int](x$0.x, x$0.y));
+ <synthetic> private def readResolve(): Object = C
+ };
+ scala.this.Predef.println(C.apply(2, 3))
+}
+error!
diff --git a/test/files/run/idempotency-case-classes.scala b/test/files/run/idempotency-case-classes.scala
new file mode 100644
index 0000000000..4da8393cb6
--- /dev/null
+++ b/test/files/run/idempotency-case-classes.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val casee = reify {
+ case class C(x: Int, y: Int)
+ println(C(2, 3))
+ }
+ println(casee.eval)
+ val tb = cm.mkToolBox()
+ val tcasee = tb.typeCheck(casee.tree)
+ println(tcasee)
+ val rtcasee = tb.resetAllAttrs(tcasee)
+ try {
+ println(tb.eval(rtcasee))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5467
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-extractors.check b/test/files/run/idempotency-extractors.check
new file mode 100644
index 0000000000..fcd50faa79
--- /dev/null
+++ b/test/files/run/idempotency-extractors.check
@@ -0,0 +1,5 @@
+2
+2 match {
+ case Test.this.Extractor.unapply(<unapply-selector>) <unapply> ((x @ _)) => x
+}
+error!
diff --git a/test/files/run/idempotency-extractors.scala b/test/files/run/idempotency-extractors.scala
new file mode 100644
index 0000000000..fe033295f5
--- /dev/null
+++ b/test/files/run/idempotency-extractors.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ object Extractor { def unapply(x: Int): Option[Int] = Some(x) }
+ val extractor = reify {
+ 2 match { case Extractor(x) => x }
+ }
+ println(extractor.eval)
+ val tb = cm.mkToolBox()
+ val textractor = tb.typeCheck(extractor.tree)
+ println(textractor)
+ val rtextractor = tb.resetAllAttrs(textractor)
+ try {
+ println(tb.eval(rtextractor))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5465
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-labels.check b/test/files/run/idempotency-labels.check
new file mode 100644
index 0000000000..8709efeb43
--- /dev/null
+++ b/test/files/run/idempotency-labels.check
@@ -0,0 +1,15 @@
+2
+{
+ var x: Int = 0;
+ while$1(){
+ if (x.<(2))
+ {
+ x = x.+(1);
+ while$1()
+ }
+ else
+ ()
+ };
+ x
+}
+2
diff --git a/test/files/run/idempotency-labels.scala b/test/files/run/idempotency-labels.scala
new file mode 100644
index 0000000000..82d009751a
--- /dev/null
+++ b/test/files/run/idempotency-labels.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val label = reify {
+ var x = 0
+ while (x < 2) { x += 1 }
+ x
+ }
+ println(label.eval)
+ val tb = cm.mkToolBox()
+ val tlabel = tb.typeCheck(label.tree)
+ println(tlabel)
+ val rtlabel = tb.resetAllAttrs(tlabel)
+ try {
+ println(tb.eval(rtlabel))
+ } catch {
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-lazy-vals.check b/test/files/run/idempotency-lazy-vals.check
new file mode 100644
index 0000000000..4dcbf96184
--- /dev/null
+++ b/test/files/run/idempotency-lazy-vals.check
@@ -0,0 +1,23 @@
+6
+{
+ class C extends AnyRef {
+ def <init>(): C = {
+ C.super.<init>();
+ ()
+ };
+ lazy private[this] val x: Int = _;
+ <stable> <accessor> lazy def x: Int = {
+ C.this.x = 2;
+ C.this.x
+ };
+ lazy private[this] val y: Int = _;
+ implicit <stable> <accessor> lazy def y: Int = {
+ C.this.y = 3;
+ C.this.y
+ }
+ };
+ val c: C = new C();
+ import c._;
+ c.x.*(scala.this.Predef.implicitly[Int](c.y))
+}
+error!
diff --git a/test/files/run/idempotency-lazy-vals.scala b/test/files/run/idempotency-lazy-vals.scala
new file mode 100644
index 0000000000..3531f9ff4b
--- /dev/null
+++ b/test/files/run/idempotency-lazy-vals.scala
@@ -0,0 +1,27 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val lazee = reify {
+ class C {
+ lazy val x = 2
+ implicit lazy val y = 3
+ }
+ val c = new C()
+ import c._
+ x * implicitly[Int]
+ }
+ println(lazee.eval)
+ val tb = cm.mkToolBox()
+ val tlazee = tb.typeCheck(lazee.tree)
+ println(tlazee)
+ val rtlazee = tb.resetAllAttrs(tlazee)
+ try {
+ println(tb.eval(rtlazee))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5466
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-partial-functions.check b/test/files/run/idempotency-partial-functions.check
new file mode 100644
index 0000000000..5c8a411655
--- /dev/null
+++ b/test/files/run/idempotency-partial-functions.check
@@ -0,0 +1,2 @@
+error!!
+error!
diff --git a/test/files/run/idempotency-partial-functions.scala b/test/files/run/idempotency-partial-functions.scala
new file mode 100644
index 0000000000..dd5f1167f1
--- /dev/null
+++ b/test/files/run/idempotency-partial-functions.scala
@@ -0,0 +1,25 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val partials = reify {
+ List((false,true)) collect { case (x,true) => x }
+ }
+ try {
+ println(partials.eval)
+ } catch {
+ case _: ToolBoxError => println("error!!")
+ }
+ try {
+ val tb = cm.mkToolBox()
+ val tpartials = tb.typeCheck(partials.tree)
+ println(tpartials)
+ val rtpartials = tb.resetAllAttrs(tpartials)
+ println(tb.eval(rtpartials))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-6187
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/idempotency-this.check b/test/files/run/idempotency-this.check
new file mode 100644
index 0000000000..08738c4565
--- /dev/null
+++ b/test/files/run/idempotency-this.check
@@ -0,0 +1,4 @@
+List()
+immutable.this.List.apply[String]("")
+Apply(TypeApply(Select(Select(This(newTypeName("immutable")), scala.collection.immutable.List), newTermName("apply")), List(TypeTree().setOriginal(Ident(newTypeName("String"))))), List(Literal(Constant(""))))
+error!
diff --git a/test/files/run/idempotency-this.scala b/test/files/run/idempotency-this.scala
new file mode 100644
index 0000000000..5cd4226326
--- /dev/null
+++ b/test/files/run/idempotency-this.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.{ToolBox, ToolBoxError}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val thiss = reify {
+ List[String]("")
+ }
+ println(thiss.eval)
+ val tb = cm.mkToolBox()
+ val tthiss = tb.typeCheck(thiss.tree)
+ println(tthiss)
+ println(showRaw(tthiss))
+ val rtthiss = tb.resetAllAttrs(tthiss)
+ try {
+ println(tb.eval(rtthiss))
+ } catch {
+ // this is the current behaviour, rather than the desired behavior; see SI-5705
+ case _: ToolBoxError => println("error!")
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-abort-fresh/Test_2.scala b/test/files/run/macro-abort-fresh/Test_2.scala
index 15c498efb0..0b9986e9f6 100644
--- a/test/files/run/macro-abort-fresh/Test_2.scala
+++ b/test/files/run/macro-abort-fresh/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-class/Impls_1.scala b/test/files/run/macro-declared-in-class-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class-object/Impls_1.scala b/test/files/run/macro-declared-in-class-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-class/Impls_1.scala b/test/files/run/macro-declared-in-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
index d506de4252..837b306976 100644
--- a/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
+++ b/test/files/run/macro-declared-in-implicit-class/Impls_Macros_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt")))))
+ val body = Block(List(printPrefix), Apply(Ident(definitions.SomeModule), List(Select(Select(prefix.tree, newTermName("x")), newTermName("toInt")))))
c.Expr[Option[Int]](body)
}
}
diff --git a/test/files/run/macro-declared-in-method/Impls_1.scala b/test/files/run/macro-declared-in-method/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-method/Impls_1.scala
+++ b/test/files/run/macro-declared-in-method/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-class/Impls_1.scala b/test/files/run/macro-declared-in-object-class/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object-class/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object-class/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object-object/Impls_1.scala b/test/files/run/macro-declared-in-object-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-object/Impls_1.scala b/test/files/run/macro-declared-in-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-package-object/Impls_1.scala b/test/files/run/macro-declared-in-package-object/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-package-object/Impls_1.scala
+++ b/test/files/run/macro-declared-in-package-object/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-refinement/Impls_1.scala b/test/files/run/macro-declared-in-refinement/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-refinement/Impls_1.scala
+++ b/test/files/run/macro-declared-in-refinement/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-declared-in-trait/Impls_1.scala b/test/files/run/macro-declared-in-trait/Impls_1.scala
index 1f8f3cbd5a..6f06f6d3f0 100644
--- a/test/files/run/macro-declared-in-trait/Impls_1.scala
+++ b/test/files/run/macro-declared-in-trait/Impls_1.scala
@@ -5,7 +5,7 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val printPrefix = Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("prefix = " + prefix))))
- val body = Block(printPrefix, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
+ val body = Block(List(printPrefix), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("it works")))))
c.Expr[Unit](body)
}
} \ No newline at end of file
diff --git a/test/files/run/macro-def-infer-return-type-b/Test_2.scala b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
index ef2920a432..ea0fd4bbff 100644
--- a/test/files/run/macro-def-infer-return-type-b/Test_2.scala
+++ b/test/files/run/macro-def-infer-return-type-b/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-expand-implicit-argument/Macros_1.scala b/test/files/run/macro-expand-implicit-argument/Macros_1.scala
index b1665256cd..d9fd5b8cb0 100644
--- a/test/files/run/macro-expand-implicit-argument/Macros_1.scala
+++ b/test/files/run/macro-expand-implicit-argument/Macros_1.scala
@@ -43,16 +43,16 @@ object Macros {
val n = as.length
val arr = newTermName("arr")
- val create = Apply(Select(ct.tree, "newArray"), List(const(n)))
+ val create = Apply(Select(ct.tree, newTermName("newArray")), List(const(n)))
val arrtpe = TypeTree(implicitly[c.WeakTypeTag[Array[A]]].tpe)
val valdef = ValDef(Modifiers(), arr, arrtpe, create)
val updates = (0 until n).map {
- i => Apply(Select(Ident(arr), "update"), List(const(i), as(i).tree))
+ i => Apply(Select(Ident(arr), newTermName("update")), List(const(i), as(i).tree))
}
- val exprs = Seq(valdef) ++ updates ++ Seq(Ident(arr))
- val block = Block(exprs:_*)
+ val exprs = (Seq(valdef) ++ updates ++ Seq(Ident(arr))).toList
+ val block = Block(exprs.init, exprs.last)
c.Expr[Array[A]](block)
}
diff --git a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
index 16d2c1e6ac..c832826d64 100644
--- a/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
+++ b/test/files/run/macro-expand-varargs-explicit-over-nonvarargs-bad/Macros_Test_2.scala
@@ -6,7 +6,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Typed(Apply(Ident(definitions.ListModule), List(Literal(Constant(1)), Literal(Constant(2)))), Ident(tpnme.WILDCARD_STAR))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
index db77b1923a..7c40045c0f 100644
--- a/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
+++ b/test/files/run/macro-impl-default-params/Impls_Macros_1.scala
@@ -6,11 +6,11 @@ object Impls {
import c.{prefix => prefix}
import c.universe._
val U = implicitly[c.WeakTypeTag[U]]
- val body = Block(
+ val body = Block(List(
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo_targs...")))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix is: " + prefix.staticType)))),
Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("type of prefix tree is: " + prefix.tree.tpe)))),
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe)))),
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("U is: " + U.tpe))))),
Literal(Constant(())))
c.Expr[Unit](body)
}
diff --git a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
index 537f1db8c6..56c23f5faf 100644
--- a/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
+++ b/test/files/run/macro-impl-rename-context/Impls_Macros_1.scala
@@ -3,8 +3,8 @@ import scala.reflect.macros.{Context => Ctx}
object Impls {
def foo(unconventionalName: Ctx)(x: unconventionalName.Expr[Int]) = {
import unconventionalName.universe._
- val body = Block(
- Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo...")))),
+ val body = Block(List(
+ Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Literal(Constant("invoking foo..."))))),
Literal(Constant(())))
unconventionalName.Expr[Unit](body)
}
diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
index 15c498efb0..0b9986e9f6 100644
--- a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
+++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
index 405ae7024f..fb0d55208c 100644
--- a/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
+++ b/test/files/run/macro-invalidret-nontypeable/Impls_Macros_1.scala
@@ -3,7 +3,7 @@ import scala.reflect.macros.{Context => Ctx}
object Impls {
def foo(c: Ctx) = {
import c.universe._
- val body = Ident("IDoNotExist")
+ val body = Ident(newTermName("IDoNotExist"))
c.Expr[Int](body)
}
}
diff --git a/test/files/run/macro-invalidret-nontypeable/Test_2.scala b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
index 15c498efb0..0daee49a08 100644
--- a/test/files/run/macro-invalidret-nontypeable/Test_2.scala
+++ b/test/files/run/macro-invalidret-nontypeable/Test_2.scala
@@ -1,8 +1,8 @@
-object Test extends App {
+ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
} \ No newline at end of file
diff --git a/test/files/run/macro-invalidusage-badret/Test_2.scala b/test/files/run/macro-invalidusage-badret/Test_2.scala
index f3a76f3fff..5cb0be5ddd 100644
--- a/test/files/run/macro-invalidusage-badret/Test_2.scala
+++ b/test/files/run/macro-invalidusage-badret/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Typed(Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String")))
+ val tree = Typed(Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42)))), Ident(newTypeName("String")))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
index c91fd7d380..e453d0b70c 100644
--- a/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
+++ b/test/files/run/macro-invalidusage-partialapplication-with-tparams/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Select(Ident("Macros"), newTermName("foo"))
+ val tree = Select(Ident(newTermName("Macros")), newTermName("foo"))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
index cbfee725e2..dc48c127f4 100644
--- a/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
+++ b/test/files/run/macro-invalidusage-partialapplication/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(40))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(40))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
index 373c6a6fca..2e64c01e35 100644
--- a/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
+++ b/test/files/run/macro-reflective-ma-normal-mdmi/Test_2.scala
@@ -2,6 +2,6 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
println(cm.mkToolBox().eval(tree))
}
diff --git a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
index adecfcff17..70560009b1 100644
--- a/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
+++ b/test/files/run/macro-reflective-mamd-normal-mi/Macros_Test_2.scala
@@ -11,10 +11,10 @@ object Test extends App {
val macrobody = Select(Ident(newTermName("Impls")), newTermName("foo"))
val macroparam = ValDef(NoMods, newTermName("x"), TypeTree(definitions.IntClass.toType), EmptyTree)
val macrodef = DefDef(Modifiers(MACRO), newTermName("foo"), Nil, List(List(macroparam)), TypeTree(), macrobody)
- val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())))
+ val modulector = DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(()))))
val module = ModuleDef(NoMods, newTermName("Macros"), Template(Nil, emptyValDef, List(modulector, macrodef)))
- val macroapp = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
- val tree = Block(macrodef, module, macroapp)
+ val macroapp = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Block(List(macrodef, module), macroapp)
val toolbox = cm.mkToolBox(options = "-language:experimental.macros")
println(toolbox.eval(tree))
}
diff --git a/test/files/run/macro-reify-freevars/Test_2.scala b/test/files/run/macro-reify-freevars/Test_2.scala
index e24758cfb4..7af9d89bdb 100644
--- a/test/files/run/macro-reify-freevars/Test_2.scala
+++ b/test/files/run/macro-reify-freevars/Test_2.scala
@@ -2,8 +2,8 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val q = New(AppliedTypeTree(Select(Select(Select(Ident("scala"), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident("Int"))))
- val x = ValDef(NoMods, newTermName("x"), Ident("Int"), EmptyTree)
+ val q = New(AppliedTypeTree(Select(Select(Select(Ident(newTermName("scala")), newTermName("collection")), newTermName("slick")), newTypeName("Queryable")), List(Ident(newTermName("Int")))))
+ val x = ValDef(NoMods, newTermName("x"), Ident(newTermName("Int")), EmptyTree)
val fn = Function(List(x), Apply(Select(Ident(newTermName("x")), newTermName("$plus")), List(Literal(Constant("5")))))
val tree = Apply(Select(q, newTermName("map")), List(fn))
try cm.mkToolBox().eval(tree)
diff --git a/test/files/run/macro-reify-splice-outside-reify/Test_2.scala b/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
index 8f96ea199d..54bd03fcd2 100644
--- a/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
+++ b/test/files/run/macro-reify-splice-outside-reify/Test_2.scala
@@ -2,7 +2,7 @@ object Test extends App {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
- val tree = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant(42))))
+ val tree = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant(42))))
try println(cm.mkToolBox().eval(tree))
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/macro-reify-tagless-a/Test_2.scala b/test/files/run/macro-reify-tagless-a/Test_2.scala
index 1bb3945ece..584c4bdf5b 100644
--- a/test/files/run/macro-reify-tagless-a/Test_2.scala
+++ b/test/files/run/macro-reify-tagless-a/Test_2.scala
@@ -6,9 +6,9 @@ object Test extends App {
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
- val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val rhs = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant("hello world"))))
val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
- val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
+ val tree = Block(List(list), Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
try cm.mkToolBox().eval(tree)
catch { case ex: Throwable => println(ex.getMessage) }
}
diff --git a/test/files/run/reify_renamed_term_basic.check b/test/files/run/reify_renamed_term_basic.check
new file mode 100644
index 0000000000..e78f94fffd
--- /dev/null
+++ b/test/files/run/reify_renamed_term_basic.check
@@ -0,0 +1 @@
+((),(),())
diff --git a/test/files/run/reify_renamed_term_basic.scala b/test/files/run/reify_renamed_term_basic.scala
new file mode 100644
index 0000000000..cd76def395
--- /dev/null
+++ b/test/files/run/reify_renamed_term_basic.scala
@@ -0,0 +1,20 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object A {
+ object B {
+ val c = ()
+ }
+}
+
+object Test extends App {
+ import A.{B => X}
+ import A.B.{c => y}
+ import X.{c => z}
+
+ val expr = reify (
+ X.c, y, z
+ )
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_local_to_reifee.check b/test/files/run/reify_renamed_term_local_to_reifee.check
new file mode 100644
index 0000000000..e78f94fffd
--- /dev/null
+++ b/test/files/run/reify_renamed_term_local_to_reifee.check
@@ -0,0 +1 @@
+((),(),())
diff --git a/test/files/run/reify_renamed_term_local_to_reifee.scala b/test/files/run/reify_renamed_term_local_to_reifee.scala
new file mode 100644
index 0000000000..1860316a5b
--- /dev/null
+++ b/test/files/run/reify_renamed_term_local_to_reifee.scala
@@ -0,0 +1,20 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object A {
+ object B {
+ val c = ()
+ }
+}
+
+object Test extends App {
+ val expr = reify {
+ import A.{B => X}
+ import A.B.{c => y}
+ import X.{c => z}
+
+ (X.c, y, z)
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_overloaded_method.check b/test/files/run/reify_renamed_term_overloaded_method.check
new file mode 100644
index 0000000000..48082f72f0
--- /dev/null
+++ b/test/files/run/reify_renamed_term_overloaded_method.check
@@ -0,0 +1 @@
+12
diff --git a/test/files/run/reify_renamed_term_overloaded_method.scala b/test/files/run/reify_renamed_term_overloaded_method.scala
new file mode 100644
index 0000000000..3ef442d203
--- /dev/null
+++ b/test/files/run/reify_renamed_term_overloaded_method.scala
@@ -0,0 +1,17 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ def show(i: Int) = i.toString
+ def show(s: String) = s
+}
+
+object Test extends App {
+ import O.{show => s}
+
+ val expr = reify {
+ s("1") + s(2)
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_term_si5841.check b/test/files/run/reify_renamed_term_si5841.check
new file mode 100644
index 0000000000..6031277b76
--- /dev/null
+++ b/test/files/run/reify_renamed_term_si5841.check
@@ -0,0 +1 @@
+class scala.reflect.runtime.JavaUniverse
diff --git a/test/files/run/reify_renamed_term_si5841.scala b/test/files/run/reify_renamed_term_si5841.scala
new file mode 100644
index 0000000000..ef18d650bf
--- /dev/null
+++ b/test/files/run/reify_renamed_term_si5841.scala
@@ -0,0 +1,7 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ println(reify{ru}.eval.getClass)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_basic.check b/test/files/run/reify_renamed_type_basic.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_basic.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_basic.scala b/test/files/run/reify_renamed_type_basic.scala
new file mode 100644
index 0000000000..23729e5c54
--- /dev/null
+++ b/test/files/run/reify_renamed_type_basic.scala
@@ -0,0 +1,16 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ type A = Unit
+}
+
+object Test extends App {
+ import O.{A => X}
+
+ def expr = reify {
+ val a: X = ()
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_local_to_reifee.check b/test/files/run/reify_renamed_type_local_to_reifee.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_local_to_reifee.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_local_to_reifee.scala b/test/files/run/reify_renamed_type_local_to_reifee.scala
new file mode 100644
index 0000000000..ed1bad239e
--- /dev/null
+++ b/test/files/run/reify_renamed_type_local_to_reifee.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+object O {
+ type A = Unit
+}
+
+object Test extends App {
+ val expr = reify {
+ import O.{A => X}
+
+ val a: X = ()
+
+ object P {
+ type B = Unit
+ }
+
+ import P.{B => Y}
+
+ val b: Y = ()
+ }
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/reify_renamed_type_spliceable.check b/test/files/run/reify_renamed_type_spliceable.check
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/files/run/reify_renamed_type_spliceable.check
@@ -0,0 +1 @@
+()
diff --git a/test/files/run/reify_renamed_type_spliceable.scala b/test/files/run/reify_renamed_type_spliceable.scala
new file mode 100644
index 0000000000..9c2cff5199
--- /dev/null
+++ b/test/files/run/reify_renamed_type_spliceable.scala
@@ -0,0 +1,21 @@
+import scala.reflect.runtime.universe._
+import scala.tools.reflect.Eval
+
+abstract class C {
+ type T >: Null
+}
+
+object Test extends App {
+ def foo(c: C) = {
+ import c.{T => U}
+ reify {
+ val x: U = null
+ }
+ }
+
+ val expr = foo(new C {
+ type T = AnyRef
+ })
+
+ println(expr.eval)
+} \ No newline at end of file
diff --git a/test/files/run/showraw_aliases.check b/test/files/run/showraw_aliases.check
index 1838bf9bec..aebd354031 100644
--- a/test/files/run/showraw_aliases.check
+++ b/test/files/run/showraw_aliases.check
@@ -1,2 +1,2 @@
-Block(List(Import(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), List(ImportSelector(newTermName("universe"), 52, newTermName("ru"), 64)))), Select(Select(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), scala.reflect.runtime.package), [newTermName("universe") aka newTermName("ru")]))
-Block(List(Import(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), List(ImportSelector(newTermName("universe"), 52, newTermName("ru"), 64)))), Select(Select(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), scala.reflect.runtime.package#<id>), [newTermName("universe")#<id> aka newTermName("ru")]))
+Block(List(Import(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), List(ImportSelector(newTermName("universe"), <offset>, newTermName("ru"), <offset>)))), Select(Select(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), scala.reflect.runtime.package), [newTermName("universe") aka newTermName("ru")]))
+Block(List(Import(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), List(ImportSelector(newTermName("universe"), <offset>, newTermName("ru"), <offset>)))), Select(Select(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), scala.reflect.runtime.package#<id>), [newTermName("universe")#<id> aka newTermName("ru")]))
diff --git a/test/files/run/showraw_aliases.scala b/test/files/run/showraw_aliases.scala
index 3a68ca37b2..65b4fcb1cd 100644
--- a/test/files/run/showraw_aliases.scala
+++ b/test/files/run/showraw_aliases.scala
@@ -9,7 +9,9 @@ object Test extends App {
""")
val ttree = tb.typeCheck(tree)
- def stabilize(s: String) = """#\d+""".r.replaceAllIn(s, "#<id>")
- println(showRaw(ttree))
+ def stabilizeIds(s: String) = """#\d+""".r.replaceAllIn(s, "#<id>")
+ def stabilizePositions(s: String) = """\d+""".r.replaceAllIn(s, "<offset>")
+ def stabilize(s: String) = stabilizePositions(stabilizeIds(s))
+ println(stabilize(showRaw(ttree)))
println(stabilize(showRaw(ttree, printIds = true)))
} \ No newline at end of file
diff --git a/test/files/run/sm-interpolator.scala b/test/files/run/sm-interpolator.scala
new file mode 100644
index 0000000000..7f7b9f061a
--- /dev/null
+++ b/test/files/run/sm-interpolator.scala
@@ -0,0 +1,41 @@
+object Test extends App {
+ import scala.reflect.internal.util.StringContextStripMarginOps
+ def check(actual: Any, expected: Any) = if (actual != expected) sys.error(s"expected: [$expected], actual: [$actual])")
+
+ val bar = "|\n ||"
+
+ check(
+ sm"""|ab
+ |de
+ |${bar} | ${1}""",
+ "ab \nde\n|\n || | 1")
+
+ check(
+ sm"|",
+ "")
+
+ check(
+ sm"${0}",
+ "0")
+
+ check(
+ sm"${0}",
+ "0")
+
+ check(
+ sm"""${0}|${1}
+ |""",
+ "0|1\n")
+
+ check(
+ sm""" ||""",
+ "|")
+
+ check(
+ sm""" ${" "} ||""",
+ " ||")
+
+ check(
+ sm"\n",
+ raw"\n".stripMargin)
+}
diff --git a/test/files/run/t0091.check b/test/files/run/t0091.check
index 7ed6ff82de..fd3c81a4d7 100644
--- a/test/files/run/t0091.check
+++ b/test/files/run/t0091.check
@@ -1 +1,2 @@
5
+5
diff --git a/test/files/run/t0091.scala b/test/files/run/t0091.scala
index eaddde0dbf..45235eb77b 100644
--- a/test/files/run/t0091.scala
+++ b/test/files/run/t0091.scala
@@ -4,10 +4,13 @@ object C extends B {
object m extends A { def x = 5 }
}
object Test {
- // The type annotation here is necessary, otherwise
- // the compiler would reference C$m$ directly.
- def o : B = C
- def main(argv : Array[String]) : Unit = {
- println(o.m.x)
- }
+ // The type annotation here is necessary, otherwise
+ // the compiler would reference C$m$ directly.
+ def o1 : B = C
+ def o2 = C
+
+ def main(argv : Array[String]) : Unit = {
+ println(o1.m.x)
+ println(o2.m.x)
+ }
}
diff --git a/test/files/run/t1672.scala b/test/files/run/t1672.scala
new file mode 100644
index 0000000000..ee025b9031
--- /dev/null
+++ b/test/files/run/t1672.scala
@@ -0,0 +1,28 @@
+object Test {
+ @annotation.tailrec
+ def bar(i : Int) : Int = {
+ if (i == 0) 0
+ else try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable => bar(i - 1)
+ }
+ }
+
+ @annotation.tailrec
+ def nestedTry1(i : Int) : Int = {
+ if (i == 0) 0
+ else try {
+ throw new RuntimeException
+ } catch {
+ case _: Throwable =>
+ try { ??? } catch { case _: Throwable => nestedTry1(i - 1) }
+ }
+ }
+
+ def main(args: Array[String]) {
+ assert(bar(2) == 0)
+
+ assert(nestedTry1(2) == 0)
+ }
+}
diff --git a/test/files/run/t5064.check b/test/files/run/t5064.check
index 077006abd9..61ccfd16e7 100644
--- a/test/files/run/t5064.check
+++ b/test/files/run/t5064.check
@@ -1,6 +1,6 @@
-[12] T5064.super.<init>()
-[12] T5064.super.<init>
-[12] this
+[53] T5064.super.<init>()
+[53] T5064.super.<init>
+[53] this
[16:23] immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1}))
[16:20] immutable.this.List.apply
<16:20> immutable.this.List
diff --git a/test/files/run/t5374.check b/test/files/run/t5374.check
index 6be88d77ec..c1cd843080 100644
--- a/test/files/run/t5374.check
+++ b/test/files/run/t5374.check
@@ -2,5 +2,4 @@ ListBuffer(1, 2, 3, 1)
ListBuffer(1, 2, 3, 1)
ListBuffer()
List(1, 2, 3, 4, 5)
-List(1, 2, 3)
-ok \ No newline at end of file
+ok
diff --git a/test/files/run/t5374.scala b/test/files/run/t5374.scala
index 9b1671e795..f6a913e35c 100644
--- a/test/files/run/t5374.scala
+++ b/test/files/run/t5374.scala
@@ -7,15 +7,15 @@ import java.io._
object Test {
-
+
def main(args: Array[String]) {
ticketExample()
emptyListBuffer()
list()
- legacyList()
+ // legacyList()
objectWithMultipleLists()
}
-
+
def inAndOut[T <: AnyRef](obj: T): T = {
val baos = new ByteArrayOutputStream
val oos = new ObjectOutputStream(baos)
@@ -24,53 +24,53 @@ object Test {
val ois = new ObjectInputStream(bais)
ois.readObject.asInstanceOf[T]
}
-
+
def ticketExample() {
val lb = inAndOut(ListBuffer(1, 2, 3))
val lb2 = ListBuffer[Int]() ++= lb
-
+
lb2 ++= List(1)
lb ++= List(1)
println(lb)
println(lb2)
}
-
+
def emptyListBuffer() {
val lb = inAndOut(ListBuffer[Int]())
-
+
println(lb)
}
-
+
def list() {
val l = inAndOut(List(1, 2, 3, 4, 5))
-
+
println(l)
}
-
+
// this byte array corresponds to what List(1, 2, 3) used to be serialized to prior to this fix
val listBytes = Array[Byte](-84, -19, 0, 5, 115, 114, 0, 39, 115, 99, 97, 108, 97, 46, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 46, 105, 109, 109, 117, 116, 97, 98, 108, 101, 46, 36, 99, 111, 108, 111, 110, 36, 99, 111, 108, 111, 110, -118, 92, 99, 91, -10, -40, -7, 109, 3, 0, 2, 76, 0, 43, 115, 99, 97, 108, 97, 36, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 36, 105, 109, 109, 117, 116, 97, 98, 108, 101, 36, 36, 99, 111, 108, 111, 110, 36, 99, 111, 108, 111, 110, 36, 36, 104, 100, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 76, 0, 2, 116, 108, 116, 0, 33, 76, 115, 99, 97, 108, 97, 47, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 47, 105, 109, 109, 117, 116, 97, 98, 108, 101, 47, 76, 105, 115, 116, 59, 120, 112, 115, 114, 0, 17, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 18, -30, -96, -92, -9, -127, -121, 56, 2, 0, 1, 73, 0, 5, 118, 97, 108, 117, 101, 120, 114, 0, 16, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 78, 117, 109, 98, 101, 114, -122, -84, -107, 29, 11, -108, -32, -117, 2, 0, 0, 120, 112, 0, 0, 0, 1, 115, 113, 0, 126, 0, 4, 0, 0, 0, 2, 115, 113, 0, 126, 0, 4, 0, 0, 0, 3, 115, 114, 0, 44, 115, 99, 97, 108, 97, 46, 99, 111, 108, 108, 101, 99, 116, 105, 111, 110, 46, 105, 109, 109, 117, 116, 97, 98, 108, 101, 46, 76, 105, 115, 116, 83, 101, 114, 105, 97, 108, 105, 122, 101, 69, 110, 100, 36, -118, 92, 99, 91, -9, 83, 11, 109, 2, 0, 0, 120, 112, 120)
-
- def legacyList() {
- val bais = new ByteArrayInputStream(listBytes)
- val ois = new ObjectInputStream(bais)
- val l = ois.readObject()
-
- println(l)
- }
-
+
+ // def legacyList() {
+ // val bais = new ByteArrayInputStream(listBytes)
+ // val ois = new ObjectInputStream(bais)
+ // val l = ois.readObject()
+
+ // println(l)
+ // }
+
class Foo extends Serializable {
val head = List(1, 2, 3)
val last = head.tail.tail
def structuralSharing: Boolean = head.tail.tail eq last
-
+
assert(structuralSharing)
}
-
+
def objectWithMultipleLists() {
val foo = inAndOut(new Foo)
-
+
if (foo.structuralSharing) println("ok")
else println("no structural sharing")
}
-
+
}
diff --git a/test/files/run/t5603.check b/test/files/run/t5603.check
index 5127d3c1c7..3b2eb55313 100644
--- a/test/files/run/t5603.check
+++ b/test/files/run/t5603.check
@@ -12,7 +12,7 @@
[95:101]<paramaccessor> private[this] val i: [98:101]Int = _;
<119:139>def <init>([95]i: [98]Int) = <119:139>{
<119:139>val nameElse = <134:139>"Bob";
- [94][94][94]super.<init>();
+ [NoPosition][NoPosition][NoPosition]super.<init>();
[94]()
};
[168:184]val name = [179:184]"avc";
@@ -20,7 +20,7 @@
};
[215:241]object Test extends [227:241][235:238]App {
[227]def <init>() = [227]{
- [227][227][227]super.<init>();
+ [NoPosition][NoPosition][NoPosition]super.<init>();
[227]()
};
[NoPosition]<empty>
diff --git a/test/files/run/t5733.check b/test/files/run/t5733.check
new file mode 100644
index 0000000000..e697046a94
--- /dev/null
+++ b/test/files/run/t5733.check
@@ -0,0 +1,2 @@
+Running ABTest asserts
+Done
diff --git a/test/files/run/t5733.scala b/test/files/run/t5733.scala
new file mode 100644
index 0000000000..360264e4ed
--- /dev/null
+++ b/test/files/run/t5733.scala
@@ -0,0 +1,53 @@
+import scala.language.dynamics
+
+object A extends Dynamic {
+ var a = "a"
+
+ def selectDynamic(method:String): String = a
+
+ def updateDynamic(method:String)(v:String) { a = v }
+}
+
+class B extends Dynamic {
+ var b = "b"
+
+ def selectDynamic(method:String): String = b
+
+ def updateDynamic(method:String)(v:String) { b = v }
+}
+
+object Test extends App {
+ assert( A.foo == "a" )
+ assert( A.bar == "a" )
+ A.aaa = "aaa"
+ assert( A.bar == "aaa" )
+
+ val b = new B
+ assert( b.foo == "b" )
+ assert( b.bar == "b" )
+ b.bbb = "bbb"
+ assert( b.bar == "bbb" )
+
+ {
+ println("Running ABTest asserts")
+ A.a = "a"
+ (new ABTest).test()
+ }
+
+ println("Done")
+}
+
+class ABTest {
+ def test() {
+ assert( A.foo == "a" )
+ assert( A.bar == "a" )
+ A.aaa = "aaa"
+ assert( A.bar == "aaa" )
+
+ val b = new B
+ assert( b.foo == "b" )
+ assert( b.bar == "b" )
+ b.bbb = "bbb"
+ assert( b.bar == "bbb" )
+ }
+}
diff --git a/test/files/run/t5753_1.check b/test/files/run/t5753_1.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/t5753_1.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/t5753_1.flags b/test/files/run/t5753_1.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/t5753_1.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/t5753_1/Impls_Macros_1.scala b/test/files/run/t5753_1/Impls_Macros_1.scala
new file mode 100644
index 0000000000..1664301f5f
--- /dev/null
+++ b/test/files/run/t5753_1/Impls_Macros_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Impls {
+ def impl(c: Context)(x: c.Expr[Any]) = x
+}
+
+object Macros extends Impls {
+ def foo(x: Any) = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/t5753_1/Test_2.scala b/test/files/run/t5753_1/Test_2.scala
new file mode 100644
index 0000000000..a2777638bc
--- /dev/null
+++ b/test/files/run/t5753_1/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/t5753_2.check b/test/files/run/t5753_2.check
new file mode 100644
index 0000000000..f70d7bba4a
--- /dev/null
+++ b/test/files/run/t5753_2.check
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/test/files/run/t5753_2.flags b/test/files/run/t5753_2.flags
new file mode 100644
index 0000000000..cd66464f2f
--- /dev/null
+++ b/test/files/run/t5753_2.flags
@@ -0,0 +1 @@
+-language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/t5753_2/Impls_Macros_1.scala b/test/files/run/t5753_2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..e23c0b938b
--- /dev/null
+++ b/test/files/run/t5753_2/Impls_Macros_1.scala
@@ -0,0 +1,10 @@
+import scala.reflect.macros.{Context => Ctx}
+
+trait Macro_T {
+ def foo[T](c: Ctx)(s: c.Expr[T]) = s
+}
+
+object Macros {
+ def foo[T](s: T) = macro Impls.foo[T]
+ object Impls extends Macro_T
+}
diff --git a/test/files/run/t5753_2/Test_2.scala b/test/files/run/t5753_2/Test_2.scala
new file mode 100644
index 0000000000..a2777638bc
--- /dev/null
+++ b/test/files/run/t5753_2/Test_2.scala
@@ -0,0 +1,4 @@
+object Test extends App {
+ import Macros._
+ println(foo(42))
+} \ No newline at end of file
diff --git a/test/files/run/t5789.check b/test/files/run/t5789.check
new file mode 100644
index 0000000000..ea8d4966b1
--- /dev/null
+++ b/test/files/run/t5789.check
@@ -0,0 +1,14 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> val n = 2
+n: Int = 2
+
+scala> () => n
+res0: () => Int = <function0>
+
+scala>
+
+scala>
diff --git a/test/files/run/t5789.scala b/test/files/run/t5789.scala
new file mode 100644
index 0000000000..461f6a4aae
--- /dev/null
+++ b/test/files/run/t5789.scala
@@ -0,0 +1,14 @@
+
+import scala.tools.nsc._
+import interpreter.ILoop
+import scala.tools.partest.ReplTest
+
+
+object Test extends ReplTest {
+ override def extraSettings = "-Yinline"
+ def code = """
+ val n = 2
+ () => n
+ """
+}
+
diff --git a/test/files/run/t5894.scala b/test/files/run/t5894.scala
new file mode 100644
index 0000000000..abeec32365
--- /dev/null
+++ b/test/files/run/t5894.scala
@@ -0,0 +1,17 @@
+import language.experimental.macros
+
+class Test
+
+object Test {
+ def foo = macro fooImpl
+ def fooImpl(c: reflect.macros.Context) = c.literalUnit
+
+ def main(args: Array[String]) {
+ try {
+ val method = classOf[Test].getMethod("foo")
+ sys.error("Static forwarder generated for macro: " + method)
+ } catch {
+ case _: NoSuchMethodException => // okay
+ }
+ }
+}
diff --git a/test/files/run/t6320.check b/test/files/run/t6320.check
new file mode 100644
index 0000000000..e56bacd223
--- /dev/null
+++ b/test/files/run/t6320.check
@@ -0,0 +1,17 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> import scala.language.dynamics
+import scala.language.dynamics
+
+scala> class Dyn(m: Map[String, Any]) extends Dynamic { def selectDynamic[T](s: String): T = m(s).asInstanceOf[T] }
+defined class Dyn
+
+scala> new Dyn(Map("foo" -> 10)).foo[Int]
+res0: Int = 10
+
+scala>
+
+scala>
diff --git a/test/files/run/t6320.scala b/test/files/run/t6320.scala
new file mode 100644
index 0000000000..26085a3d7d
--- /dev/null
+++ b/test/files/run/t6320.scala
@@ -0,0 +1,9 @@
+import scala.tools.partest.ReplTest
+
+object Test extends ReplTest {
+ def code = """
+import scala.language.dynamics
+class Dyn(m: Map[String, Any]) extends Dynamic { def selectDynamic[T](s: String): T = m(s).asInstanceOf[T] }
+new Dyn(Map("foo" -> 10)).foo[Int]
+ """
+}
diff --git a/test/files/run/t6549.check b/test/files/run/t6549.check
new file mode 100644
index 0000000000..bc78aac741
--- /dev/null
+++ b/test/files/run/t6549.check
@@ -0,0 +1,32 @@
+Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala>
+
+scala> case class `X"`(var xxx: Any)
+defined class X$u0022
+
+scala> val m = Map(("": Any) -> `X"`("\""), ('s: Any) -> `X"`("\""))
+m: scala.collection.immutable.Map[Any,X"] = Map("" -> X"("), 's -> X"("))
+
+scala> m("")
+res0: X" = X"(")
+
+scala> m("").xxx
+res1: Any = "
+
+scala> m("").xxx = 0
+m("").xxx: Any = 0
+
+scala> m("").xxx = "\""
+m("").xxx: Any = "
+
+scala> m('s).xxx = 's
+m(scala.Symbol("s")).xxx: Any = 's
+
+scala> val `"` = 0
+": Int = 0
+
+scala>
+
+scala>
diff --git a/test/files/run/t6549.scala b/test/files/run/t6549.scala
new file mode 100644
index 0000000000..7335661dc7
--- /dev/null
+++ b/test/files/run/t6549.scala
@@ -0,0 +1,22 @@
+import scala.tools.partest.ReplTest
+
+// Check that the fragments of code generated in
+// in the REPL correctly escape values added to
+// literal strings.
+//
+// Before, we saw:
+// scala> m("").x = 77
+// <console>:10: error: ')' expected but string literal found.
+// + "m("").x: Int = " + `$ires8` + "\n"
+object Test extends ReplTest {
+ def code = """
+ |case class `X"`(var xxx: Any)
+ |val m = Map(("": Any) -> `X"`("\""), ('s: Any) -> `X"`("\""))
+ |m("")
+ |m("").xxx
+ |m("").xxx = 0
+ |m("").xxx = "\""
+ |m('s).xxx = 's
+ |val `"` = 0
+ """.stripMargin
+}
diff --git a/test/files/run/t6614.check b/test/files/run/t6614.check
new file mode 100644
index 0000000000..2e80ebda8b
--- /dev/null
+++ b/test/files/run/t6614.check
@@ -0,0 +1,11 @@
+(ArrayStack(),true)
+(ArrayStack(0),true)
+(ArrayStack(0, 1),true)
+(ArrayStack(0, 1, 2),true)
+(ArrayStack(0, 1, 2, 3),true)
+(ArrayStack(0, 1, 2, 3, 4),true)
+(ArrayStack(0, 1, 2, 3, 4, 5),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7, 8),true)
+(ArrayStack(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),true)
diff --git a/test/files/run/t6614.scala b/test/files/run/t6614.scala
new file mode 100644
index 0000000000..3ad9f36fc4
--- /dev/null
+++ b/test/files/run/t6614.scala
@@ -0,0 +1,8 @@
+object Test extends App {
+ import scala.collection.mutable.ArrayStack
+
+ println((for (i <- 0 to 10) yield {
+ val in = ArrayStack.tabulate(i)(_.toString)
+ (in, (in filter (_ => true)) == in)
+ }).mkString("\n"))
+}
diff --git a/test/files/run/t6631.scala b/test/files/run/t6631.scala
new file mode 100644
index 0000000000..e472b83d50
--- /dev/null
+++ b/test/files/run/t6631.scala
@@ -0,0 +1,18 @@
+import reflect.ClassTag
+
+object Test extends App {
+ def intercept[T <: Throwable : ClassTag](act: => Any) = try {
+ act
+ } catch {
+ case x: Throwable =>
+ val cls = implicitly[ClassTag[T]].runtimeClass
+ assert(cls.isInstance(x), (x.getClass, x, cls).toString)
+ }
+ assert(s"""\f\r\n\t""" == "\f\r\n\t")
+
+ import StringContext.InvalidEscapeException
+ intercept[InvalidEscapeException](s"""\""")
+ intercept[InvalidEscapeException](s"""\x""")
+ intercept[InvalidEscapeException](s"\")
+
+}
diff --git a/test/files/run/t6677.scala b/test/files/run/t6677.scala
new file mode 100644
index 0000000000..e6eaf6a498
--- /dev/null
+++ b/test/files/run/t6677.scala
@@ -0,0 +1,28 @@
+
+class Test {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+ def error {
+ new cm.universe.Traverser // java.lang.VerifyError: (class: Test, method: error signature: ()V) Incompatible object argument for function call
+
+ }
+
+ def okay1 {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+
+ new cm.universe.Traverser
+ }
+
+ def okay2 {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+ val u: reflect.runtime.universe.type = cm.universe
+ new u.Traverser
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ new Test().error
+ new Test().okay1
+ new Test().okay2
+ }
+}
diff --git a/test/files/run/t6677b.scala b/test/files/run/t6677b.scala
new file mode 100644
index 0000000000..e4fe5e3722
--- /dev/null
+++ b/test/files/run/t6677b.scala
@@ -0,0 +1,33 @@
+trait U {
+ trait U1 {
+ class X
+ }
+ type U11 <: U1
+ val u : U11 = null.asInstanceOf[U11]
+}
+trait A extends U
+
+trait B extends U {
+ def foo = ""
+ class U11 extends U1 { class X extends super.X { foo } } // refer to foo to add $outer pointer
+ override val u = new U11
+}
+class C {
+ val ab: A with B = new A with B // `B with A` works.
+
+ def foo {
+ // fails
+ new ab.u.X
+
+ // works:
+ val u = ab.u
+ new u.X
+ }
+}
+object Test {
+ def main(args: Array[String]) {
+ // java.lang.NoSuchMethodError: A.u()LB$U11;
+ // at C.foo(t6677b.scala:23)
+ new C().foo
+ }
+}
diff --git a/test/files/run/t6687.scala b/test/files/run/t6687.scala
new file mode 100644
index 0000000000..ee44e5f0d2
--- /dev/null
+++ b/test/files/run/t6687.scala
@@ -0,0 +1,10 @@
+import scala.reflect.runtime.universe._
+
+class A { lazy val x = 1 }
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val vars = typeOf[A].members.toList filter (x => x.isTerm && x.asTerm.isVar)
+ assert(vars.isEmpty, vars)
+ }
+}
diff --git a/test/files/run/t6690.scala b/test/files/run/t6690.scala
new file mode 100644
index 0000000000..43ede967a0
--- /dev/null
+++ b/test/files/run/t6690.scala
@@ -0,0 +1,62 @@
+import scala.collection.mutable
+
+object Test extends App {
+ def last0(ml: mutable.MutableList[Int]) =
+ ml.asInstanceOf[{def last0: mutable.LinkedList[Int]}].last0
+
+ def first0(ml: mutable.MutableList[Int]) =
+ ml.asInstanceOf[{def first0: mutable.LinkedList[Int]}].first0
+
+ val f = mutable.Queue[Int]()
+ def check(desc: String) {
+ assert(f.length == 0, s"$desc: non empty: $f")
+ assert(last0(f).isEmpty, s"$desc: last0 leak: ${last0(f)}")
+ assert(first0(f).isEmpty, s"$desc: first0 leak: ${last0(f)}")
+ }
+
+ f.enqueue(1)
+ f.dequeue()
+ check("dequeue 1")
+
+ f.enqueue(1)
+ f.enqueue(2)
+ f.dequeue()
+ assert(last0(f).toList == List(2), last0(f))
+ f.dequeue()
+ check("dequeue 2")
+
+ f.enqueue(1)
+ f.dequeueAll(_ => false)
+ f.dequeueAll(_ => true)
+ check("dequeueAll")
+
+ f.enqueue(1)
+ f.dequeueFirst(_ => true)
+ check("dequeueFirst")
+
+ {
+ f.enqueue(1)
+ val tail = f.tail
+ assert(last0(tail).isEmpty, last0(tail))
+ assert(first0(tail).isEmpty, first0(tail))
+ }
+
+ {
+ val ml = mutable.MutableList[Int]()
+ 1 +=: ml
+ val tail = ml.tail
+ assert(last0(tail).isEmpty, last0(tail))
+ assert(first0(tail).isEmpty, first0(tail))
+ }
+
+ {
+ val ml = mutable.MutableList[Int]()
+ 1 +=: ml
+ ml += 2
+ val tail = ml.tail
+ assert(last0(tail).toList == List(2), last0(tail))
+ assert(first0(tail) == last0(tail).toList, first0(tail))
+ assert(last0(tail.tail).toList == Nil, last0(tail.tail).toList)
+ assert(first0(tail.tail) == Nil, first0(tail.tail))
+ }
+}
diff --git a/test/files/run/t6706.scala b/test/files/run/t6706.scala
new file mode 100644
index 0000000000..905494ca8d
--- /dev/null
+++ b/test/files/run/t6706.scala
@@ -0,0 +1,14 @@
+object Test {
+ var name = "foo" + 1
+ var s1 = Symbol(name)
+ s1 = null
+ System.gc
+ val s2 = Symbol("foo1")
+ name = null
+ System.gc
+ val s3 = Symbol("foo1")
+
+ def main(args: Array[String]): Unit = {
+ assert(s2 eq s3, ((s2, System.identityHashCode(s2), s3, System.identityHashCode(s3))))
+ }
+}
diff --git a/test/files/run/t6731.check b/test/files/run/t6731.check
new file mode 100644
index 0000000000..a5d59bd378
--- /dev/null
+++ b/test/files/run/t6731.check
@@ -0,0 +1,40 @@
+Mono$.bar()
+Mono$.bar
+Mono$.bar()
+Mono$.bar
+Mono$.bar
+Mono$.baz
+Mono$.bar(bippy=1, boppy=2)
+Mono$.baz
+Poly.bar[Nothing]
+Poly.bar[Int]
+Poly.bar[Nothing]()
+Poly.bar[Int]()
+Poly.bar[Int](1, 2, 3)
+Poly.bar[Nothing]
+Poly.bar[Int]
+Poly.bar[Nothing]()
+Poly.bar[Int]()
+Poly.bar[Int](1, 2, 3)
+Updating.bar
+Updating.bar = b
+Nest1$Nest2$Nest3$.bippy(1, 2, 3)
+Nest1$Nest2$Nest3$.bippy
+Named.bippy(a=1, b=2)
+Named.boppy(c=3, d=4)
+Named.apply()
+Named.apply()
+Named.apply(e=5, f=6)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(b, q0)
+Named2.bippy(1)(q0, c)
+Named2.bippy(1)(c, b)
+Named2.bippy(1)(b, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(2)(b, c)
+Named2.bippy(1)(q0, c)
+Named2.bippy(5)(b, c)
+Named2.dingus(100)(b, dong)
+Named2.bippy(1)(q0, q1)
+Named2.hello(100)(!!, !!)
diff --git a/test/files/run/t6731.scala b/test/files/run/t6731.scala
new file mode 100644
index 0000000000..89d212e91e
--- /dev/null
+++ b/test/files/run/t6731.scala
@@ -0,0 +1,143 @@
+import scala.language.dynamics
+import scala.reflect.{ ClassTag, classTag }
+
+object Util {
+ def show[T](x: T): T = { println(x) ; x }
+ def mkArgs(xs: Any*) = xs map { case ((k, v)) => k + "=" + v ; case x => "" + x } mkString ("(", ", ", ")")
+}
+import Util._
+
+abstract class MonoDynamic extends Dynamic {
+ def selectDynamic(name: String): String = show(this + "." + name)
+ def applyDynamic(name: String)(args: Any*): String = show(this + "." + name + mkArgs(args: _*))
+ def applyDynamicNamed(name: String)(args: (String, Any)*): String = show(this + "." + name + mkArgs(args: _*))
+
+ override def toString = this.getClass.getName split '.' last
+}
+
+object Mono extends MonoDynamic {
+ def f(s: String): String = s
+
+ def f1 = this.bar()
+ def f2 = this.bar
+ def f3 = f(this.bar())
+ def f4 = f(this.bar)
+ def f5 = f(f(f(f(f(f(this.bar)))))) + f(f(f(f(f(f(this.baz))))))
+ def f6 = f(f(f(f(f(f(this.bar(bippy = 1, boppy = 2))))))) + f(f(f(f(f(f(this.baz))))))
+}
+
+object Poly extends Dynamic {
+ def selectDynamic[T: ClassTag](name: String): String = show(s"$this.$name[${classTag[T]}]")
+ def applyDynamic[T: ClassTag](name: String)(args: Any*): String = show(args.mkString(s"$this.$name[${classTag[T]}](", ", ", ")"))
+
+ def f(s: String): String = s
+
+ def f1 = this.bar
+ def f2 = this.bar[Int]
+ def f3 = this.bar()
+ def f4 = this.bar[Int]()
+ def f5 = this.bar[Int](1, 2, 3)
+
+ def f6 = f(f(this.bar))
+ def f7 = f(f(this.bar[Int]))
+ def f8 = f(f(this.bar()))
+ def f9 = f(f(this.bar[Int]()))
+ def f10 = f(f(this.bar[Int](1, 2, 3)))
+
+ override def toString = "Poly"
+}
+
+object Updating extends Dynamic {
+ def selectDynamic(name: String): String = show(s"$this.$name")
+ def updateDynamic(name: String)(value: Any): String = show(s"$this.$name = $value")
+
+ def f1 = this.bar
+ def f2 = this.bar = "b"
+
+ override def toString = "Updating"
+}
+
+object Nest1 extends Dynamic {
+ def applyDynamic(name: String)(args: Any*): Nest2.type = Nest2
+
+ object Nest2 extends Dynamic {
+ def applyDynamicNamed(name: String)(args: (String, Any)*): Nest3.type = Nest3
+
+ object Nest3 extends MonoDynamic {
+
+ }
+ }
+
+ def f1 = Nest1.bip().bop(foo = "bar").bippy(1, 2, 3)
+ def f2 = Nest1.bip("abc").bop(foo = 5).bippy
+}
+
+object Named extends Dynamic {
+ def applyDynamic(name: String)(args: Any*): Named.type = {
+ show(this + "." + name + mkArgs(args: _*))
+ this
+ }
+ def applyDynamicNamed(name: String)(args: (String, Any)*): Named.type = {
+ show(this + "." + name + mkArgs(args: _*))
+ this
+ }
+
+ def f1 = this.bippy(a = 1, b = 2).boppy(c = 3, d = 4)()()(e = 5, f = 6)
+ override def toString = "Named"
+}
+
+object Named2 extends Dynamic {
+ def applyDynamic(name: String)(a: Any)(b: Any = "b", c: Any = "c"): Named2.type = {
+ show(this + "." + name + mkArgs(a) + mkArgs(b, c))
+ this
+ }
+ def applyDynamicNamed(name: String)(a: (String, Any))(b: (String, Any), c: (String, Any)): Named2.type = {
+ show(this + "." + name + mkArgs(a) + mkArgs(b, c))
+ this
+ }
+
+ def f1 = this.bippy(1)(b = "q0")
+ def f2 = this.bippy(1)("q0")
+ def f3 = this.bippy(1)(c = "q0")
+ def f4 = this.bippy(1)("q0")
+ def f5 = this.bippy(1)(c = "b", b = "c")
+ def f6 = this.bippy(1)("b", "c")
+ def f7 = this.bippy(1)(b = "q0").bippy(2)()
+ def f8 = this.bippy(1)("q0").bippy(5)(c = "c").dingus(100)(c = "dong")
+ def f9 = this.bippy(1)(b = "q0", c = "q1").hello(100)("!!", "!!")
+
+ override def toString = "Named2"
+}
+
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ {
+ import Mono._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6
+ }
+ {
+ import Poly._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6 ; f7 ; f8 ; f9 ; f10
+ }
+ {
+ import Updating._
+ f1 ; f2
+ }
+ {
+ import Nest1._
+ f1 ; f2
+ }
+ {
+ import Named._
+ f1
+ }
+ {
+ import Named2._
+ f1 ; f2 ; f3 ; f4 ; f5
+ f6 ; f7 ; f8 ; f9
+ }
+ }
+}
diff --git a/test/files/run/t6745-2.scala b/test/files/run/t6745-2.scala
new file mode 100644
index 0000000000..31ecd42bd1
--- /dev/null
+++ b/test/files/run/t6745-2.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc._
+import scala.tools.partest.CompilerTest
+import scala.collection.{ mutable, immutable, generic }
+
+object Test extends CompilerTest {
+ import global._
+ import rootMirror._
+ import definitions._
+ import global.analyzer.{Context, ImportInfo}
+
+ override def code = """
+package context {
+}
+ """
+
+ def check(source: String, unit: global.CompilationUnit) = {
+ val context: Context = global.analyzer.rootContext(unit)
+ val importInfo: ImportInfo = context.imports.head // Predef._
+ val importedSym = importInfo.importedSymbol(nme.CONSTRUCTOR)
+ assert(importedSym == NoSymbol, importedSym) // was "constructor Predef"
+ }
+}
diff --git a/test/files/run/toolbox_typecheck_implicitsdisabled.scala b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
index f11f0192f3..8a3d433142 100644
--- a/test/files/run/toolbox_typecheck_implicitsdisabled.scala
+++ b/test/files/run/toolbox_typecheck_implicitsdisabled.scala
@@ -6,16 +6,16 @@ import scala.tools.reflect.ToolBox
object Test extends App {
val toolbox = cm.mkToolBox()
- val tree1 = Block(
- Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ val tree1 = Block(List(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1)))),
Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
)
val ttree1 = toolbox.typeCheck(tree1, withImplicitViewsDisabled = false)
println(ttree1)
try {
- val tree2 = Block(
- Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1))),
+ val tree2 = Block(List(
+ Import(Select(Ident(newTermName("scala")), newTermName("Predef")), List(ImportSelector(nme.WILDCARD, -1, null, -1)))),
Apply(Select(Literal(Constant(1)), newTermName("$minus$greater")), List(Literal(Constant(2))))
)
val ttree2 = toolbox.typeCheck(tree2, withImplicitViewsDisabled = true)
diff --git a/test/pending/jvm/cf-attributes.scala b/test/pending/jvm/cf-attributes.scala
index 9e0e9d95de..f4964b63b1 100644
--- a/test/pending/jvm/cf-attributes.scala
+++ b/test/pending/jvm/cf-attributes.scala
@@ -52,14 +52,14 @@ object anonymousFunctions {
}
object anonymousClasses {
- //InnerClass:
+ //InnerClass:
// public abstract #_= #_ of #_; //Foo=class anonymousClasses$Foo of class anonymousClasses$
// public abstract #_= #_ of #_; //Foo$class=class anonymousClasses$Foo$class of class anonymousClasses$
trait Foo {
def foo() { println("foo"); }
override def toString = getClass.getName
}
- //InnerClass:
+ //InnerClass:
// public final #_; //class anonymousClasses$$anon$1 of class anonymousClasses$
val x = new Foo() {
override def foo() { println("foo (overriden)"); }
@@ -88,16 +88,16 @@ trait Test1 {
trait Test2 {
@throws(classOf[Exception])
- def printInnerClasses(cls: Class[_]) {
- import java.io._, ch.epfl.lamp.fjbg._
- val fjbgContext = new FJBGContext(49, 0)
- val outDir = System.getProperty("partest.output", "cf-attributes.obj")
- val fileName = outDir+File.separator+cls.getName+".class"
- val in = new DataInputStream(new FileInputStream(fileName))
- val jclass = fjbgContext.JClass(in)
- println(jclass.getInnerClasses)
- in.close()
- }
+ // def printInnerClasses(cls: Class[_]) {
+ // import java.io._, ch.epfl.lamp.fjbg._
+ // val fjbgContext = new FJBGContext(49, 0)
+ // val outDir = System.getProperty("partest.output", "cf-attributes.obj")
+ // val fileName = outDir+File.separator+cls.getName+".class"
+ // val in = new DataInputStream(new FileInputStream(fileName))
+ // val jclass = fjbgContext.JClass(in)
+ // println(jclass.getInnerClasses)
+ // in.close()
+ // }
def printClass(name: String) {
try { printClass(Class.forName(name)) }
catch { case e: Exception => println(e) }
@@ -105,7 +105,7 @@ trait Test2 {
def printClass(cls: Class[_]) {
println("\n[[ "+cls.getName+" ]]");
try { printInnerClasses(cls) }
- catch { case e: Exception => println(e) }
+ catch { case e: Exception => println(e) }
}
}
diff --git a/test/pending/run/macro-reify-tagless-b/Test_2.scala b/test/pending/run/macro-reify-tagless-b/Test_2.scala
index ebd35ffe47..10487b1515 100644
--- a/test/pending/run/macro-reify-tagless-b/Test_2.scala
+++ b/test/pending/run/macro-reify-tagless-b/Test_2.scala
@@ -6,7 +6,7 @@ object Test extends App {
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox
val tpt = AppliedTypeTree(Ident(definitions.ListClass), List(Ident(definitions.StringClass)))
- val rhs = Apply(Select(Ident("Macros"), newTermName("foo")), List(Literal(Constant("hello world"))))
+ val rhs = Apply(Select(Ident(newTermName("Macros")), newTermName("foo")), List(Literal(Constant("hello world"))))
val list = ValDef(NoMods, newTermName("list"), tpt, rhs)
val tree = Block(list, Apply(Select(Ident(definitions.PredefModule), newTermName("println")), List(Ident(list.name))))
println(cm.mkToolBox().eval(tree))
diff --git a/test/postreview.py b/test/postreview.py
deleted file mode 100644
index 2e2518f7ee..0000000000
--- a/test/postreview.py
+++ /dev/null
@@ -1,2540 +0,0 @@
-#!/usr/bin/env python
-import cookielib
-import difflib
-import getpass
-import marshal
-import mimetools
-import ntpath
-import os
-import re
-import socket
-import stat
-import subprocess
-import sys
-import tempfile
-import urllib
-import urllib2
-from optparse import OptionParser
-from tempfile import mkstemp
-from urlparse import urljoin, urlparse
-
-try:
- from hashlib import md5
-except ImportError:
- # Support Python versions before 2.5.
- from md5 import md5
-
-try:
- import json
-except ImportError:
- import simplejson as json
-
-# This specific import is necessary to handle the paths for
-# cygwin enabled machines.
-if (sys.platform.startswith('win')
- or sys.platform.startswith('cygwin')):
- import ntpath as cpath
-else:
- import posixpath as cpath
-
-###
-# Default configuration -- user-settable variables follow.
-###
-
-# The following settings usually aren't needed, but if your Review
-# Board crew has specific preferences and doesn't want to express
-# them with command line switches, set them here and you're done.
-# In particular, setting the REVIEWBOARD_URL variable will allow
-# you to make it easy for people to submit reviews regardless of
-# their SCM setup.
-#
-# Note that in order for this script to work with a reviewboard site
-# that uses local paths to access a repository, the 'Mirror path'
-# in the repository setup page must be set to the remote URL of the
-# repository.
-
-#
-# Reviewboard URL.
-#
-# Set this if you wish to hard-code a default server to always use.
-# It's generally recommended to set this using your SCM repository
-# (for those that support it -- currently only SVN, Git, and Perforce).
-#
-# For example, on SVN:
-# $ svn propset reviewboard:url http://reviewboard.example.com .
-#
-# Or with Git:
-# $ git config reviewboard.url http://reviewboard.example.com
-#
-# On Perforce servers version 2008.1 and above:
-# $ p4 counter reviewboard.url http://reviewboard.example.com
-#
-# Older Perforce servers only allow numerical counters, so embedding
-# the url in the counter name is also supported:
-# $ p4 counter reviewboard.url.http:\|\|reviewboard.example.com 1
-#
-# Note that slashes are not allowed in Perforce counter names, so replace them
-# with pipe characters (they are a safe substitute as they are not used
-# unencoded in URLs). You may need to escape them when issuing the p4 counter
-# command as above.
-#
-# If this is not possible or desired, setting the value here will let
-# you get started quickly.
-#
-# For all other repositories, a .reviewboardrc file present at the top of
-# the checkout will also work. For example:
-#
-# $ cat .reviewboardrc
-# REVIEWBOARD_URL = "http://reviewboard.example.com"
-#
-REVIEWBOARD_URL = None
-
-# Default submission arguments. These are all optional; run this
-# script with --help for descriptions of each argument.
-TARGET_GROUPS = None
-TARGET_PEOPLE = None
-SUBMIT_AS = None
-PUBLISH = False
-OPEN_BROWSER = False
-
-# Debugging. For development...
-DEBUG = False
-
-###
-# End user-settable variables.
-###
-
-
-VERSION = "0.8"
-
-user_config = None
-tempfiles = []
-options = None
-
-
-class APIError(Exception):
- pass
-
-
-class RepositoryInfo:
- """
- A representation of a source code repository.
- """
- def __init__(self, path=None, base_path=None, supports_changesets=False,
- supports_parent_diffs=False):
- self.path = path
- self.base_path = base_path
- self.supports_changesets = supports_changesets
- self.supports_parent_diffs = supports_parent_diffs
- debug("repository info: %s" % self)
-
- def __str__(self):
- return "Path: %s, Base path: %s, Supports changesets: %s" % \
- (self.path, self.base_path, self.supports_changesets)
-
- def set_base_path(self, base_path):
- if not base_path.startswith('/'):
- base_path = '/' + base_path
- debug("changing repository info base_path from %s to %s" % \
- (self.base_path, base_path))
- self.base_path = base_path
-
- def find_server_repository_info(self, server):
- """
- Try to find the repository from the list of repositories on the server.
- For Subversion, this could be a repository with a different URL. For
- all other clients, this is a noop.
- """
- return self
-
-
-class SvnRepositoryInfo(RepositoryInfo):
- """
- A representation of a SVN source code repository. This version knows how to
- find a matching repository on the server even if the URLs differ.
- """
- def __init__(self, path, base_path, uuid, supports_parent_diffs=False):
- RepositoryInfo.__init__(self, path, base_path,
- supports_parent_diffs=supports_parent_diffs)
- self.uuid = uuid
-
- def find_server_repository_info(self, server):
- """
- The point of this function is to find a repository on the server that
- matches self, even if the paths aren't the same. (For example, if self
- uses an 'http' path, but the server uses a 'file' path for the same
- repository.) It does this by comparing repository UUIDs. If the
- repositories use the same path, you'll get back self, otherwise you'll
- get a different SvnRepositoryInfo object (with a different path).
- """
- repositories = server.get_repositories()
-
- for repository in repositories:
- if repository['tool'] != 'Subversion':
- continue
-
- info = self._get_repository_info(server, repository)
-
- if not info or self.uuid != info['uuid']:
- continue
-
- repos_base_path = info['url'][len(info['root_url']):]
- relpath = self._get_relative_path(self.base_path, repos_base_path)
- if relpath:
- return SvnRepositoryInfo(info['url'], relpath, self.uuid)
-
- # We didn't find a matching repository on the server. We'll just return
- # self and hope for the best.
- return self
-
- def _get_repository_info(self, server, repository):
- try:
- return server.get_repository_info(repository['id'])
- except APIError, e:
- # If the server couldn't fetch the repository info, it will return
- # code 210. Ignore those.
- # Other more serious errors should still be raised, though.
- rsp = e.args[0]
- if rsp['err']['code'] == 210:
- return None
-
- raise e
-
- def _get_relative_path(self, path, root):
- pathdirs = self._split_on_slash(path)
- rootdirs = self._split_on_slash(root)
-
- # root is empty, so anything relative to that is itself
- if len(rootdirs) == 0:
- return path
-
- # If one of the directories doesn't match, then path is not relative
- # to root.
- if rootdirs != pathdirs:
- return None
-
- # All the directories matched, so the relative path is whatever
- # directories are left over. The base_path can't be empty, though, so
- # if the paths are the same, return '/'
- if len(pathdirs) == len(rootdirs):
- return '/'
- else:
- return '/'.join(pathdirs[len(rootdirs):])
-
- def _split_on_slash(self, path):
- # Split on slashes, but ignore multiple slashes and throw away any
- # trailing slashes.
- split = re.split('/*', path)
- if split[-1] == '':
- split = split[0:-1]
- return split
-
-
-class ReviewBoardHTTPPasswordMgr(urllib2.HTTPPasswordMgr):
- """
- Adds HTTP authentication support for URLs.
-
- Python 2.4's password manager has a bug in http authentication when the
- target server uses a non-standard port. This works around that bug on
- Python 2.4 installs. This also allows post-review to prompt for passwords
- in a consistent way.
-
- See: http://bugs.python.org/issue974757
- """
- def __init__(self, reviewboard_url):
- self.passwd = {}
- self.rb_url = reviewboard_url
- self.rb_user = None
- self.rb_pass = None
-
- def find_user_password(self, realm, uri):
- if uri.startswith(self.rb_url):
- if self.rb_user is None or self.rb_pass is None:
- print "==> HTTP Authentication Required"
- print 'Enter username and password for "%s" at %s' % \
- (realm, urlparse(uri)[1])
- self.rb_user = raw_input('Username: ')
- self.rb_pass = getpass.getpass('Password: ')
-
- return self.rb_user, self.rb_pass
- else:
- # If this is an auth request for some other domain (since HTTP
- # handlers are global), fall back to standard password management.
- return urllib2.HTTPPasswordMgr.find_user_password(self, realm, uri)
-
-
-class ReviewBoardServer(object):
- """
- An instance of a Review Board server.
- """
- def __init__(self, url, info, cookie_file):
- self.url = url
- if self.url[-1] != '/':
- self.url += '/'
- self._info = info
- self._server_info = None
- self.cookie_file = cookie_file
- self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file)
-
- # Set up the HTTP libraries to support all of the features we need.
- cookie_handler = urllib2.HTTPCookieProcessor(self.cookie_jar)
- password_mgr = ReviewBoardHTTPPasswordMgr(self.url)
- auth_handler = urllib2.HTTPBasicAuthHandler(password_mgr)
-
- opener = urllib2.build_opener(cookie_handler, auth_handler)
- opener.addheaders = [('User-agent', 'post-review/' + VERSION)]
- urllib2.install_opener(opener)
-
- def login(self, force=False):
- """
- Logs in to a Review Board server, prompting the user for login
- information if needed.
- """
- if not force and self.has_valid_cookie():
- return
-
- print "==> Review Board Login Required"
- print "Enter username and password for Review Board at %s" % self.url
- if options.username:
- username = options.username
- elif options.submit_as:
- username = options.submit_as
- else:
- username = raw_input('Username: ')
-
- if not options.password:
- password = getpass.getpass('Password: ')
- else:
- password = options.password
-
- debug('Logging in with username "%s"' % username)
- try:
- self.api_post('api/json/accounts/login/', {
- 'username': username,
- 'password': password,
- })
- except APIError, e:
- rsp, = e.args
-
- die("Unable to log in: %s (%s)" % (rsp["err"]["msg"],
- rsp["err"]["code"]))
-
- debug("Logged in.")
-
- def has_valid_cookie(self):
- """
- Load the user's cookie file and see if they have a valid
- 'rbsessionid' cookie for the current Review Board server. Returns
- true if so and false otherwise.
- """
- try:
- parsed_url = urlparse(self.url)
- host = parsed_url[1]
- path = parsed_url[2] or '/'
-
- # Cookie files don't store port numbers, unfortunately, so
- # get rid of the port number if it's present.
- host = host.split(":")[0]
-
- debug("Looking for '%s %s' cookie in %s" % \
- (host, path, self.cookie_file))
- self.cookie_jar.load(self.cookie_file, ignore_expires=True)
-
- try:
- cookie = self.cookie_jar._cookies[host][path]['rbsessionid']
-
- if not cookie.is_expired():
- debug("Loaded valid cookie -- no login required")
- return True
-
- debug("Cookie file loaded, but cookie has expired")
- except KeyError:
- debug("Cookie file loaded, but no cookie for this server")
- except IOError, error:
- debug("Couldn't load cookie file: %s" % error)
-
- return False
-
- def new_review_request(self, changenum, submit_as=None):
- """
- Creates a review request on a Review Board server, updating an
- existing one if the changeset number already exists.
-
- If submit_as is provided, the specified user name will be recorded as
- the submitter of the review request (given that the logged in user has
- the appropriate permissions).
- """
- try:
- debug("Attempting to create review request for %s" % changenum)
- data = { 'repository_path': self.info.path }
-
- if changenum:
- data['changenum'] = changenum
-
- if submit_as:
- debug("Submitting the review request as %s" % submit_as)
- data['submit_as'] = submit_as
-
- rsp = self.api_post('api/json/reviewrequests/new/', data)
- except APIError, e:
- rsp, = e.args
-
- if not options.diff_only:
- if rsp['err']['code'] == 204: # Change number in use
- debug("Review request already exists. Updating it...")
- rsp = self.api_post(
- 'api/json/reviewrequests/%s/update_from_changenum/' %
- rsp['review_request']['id'])
- else:
- raise e
-
- debug("Review request created")
- return rsp['review_request']
-
- def set_review_request_field(self, review_request, field, value):
- """
- Sets a field in a review request to the specified value.
- """
- rid = review_request['id']
-
- debug("Attempting to set field '%s' to '%s' for review request '%s'" %
- (field, value, rid))
-
- self.api_post('api/json/reviewrequests/%s/draft/set/' % rid, {
- field: value,
- })
-
- def get_review_request(self, rid):
- """
- Returns the review request with the specified ID.
- """
- rsp = self.api_get('api/json/reviewrequests/%s/' % rid)
- return rsp['review_request']
-
- def get_repositories(self):
- """
- Returns the list of repositories on this server.
- """
- rsp = self.api_get('/api/json/repositories/')
- return rsp['repositories']
-
- def get_repository_info(self, rid):
- """
- Returns detailed information about a specific repository.
- """
- rsp = self.api_get('/api/json/repositories/%s/info/' % rid)
- return rsp['info']
-
- def save_draft(self, review_request):
- """
- Saves a draft of a review request.
- """
- self.api_post("api/json/reviewrequests/%s/draft/save/" %
- review_request['id'])
- debug("Review request draft saved")
-
- def upload_diff(self, review_request, diff_content, parent_diff_content):
- """
- Uploads a diff to a Review Board server.
- """
- debug("Uploading diff, size: %d" % len(diff_content))
-
- if parent_diff_content:
- debug("Uploading parent diff, size: %d" % len(parent_diff_content))
-
- fields = {}
- files = {}
-
- if self.info.base_path:
- fields['basedir'] = self.info.base_path
-
- files['path'] = {
- 'filename': 'diff',
- 'content': diff_content
- }
-
- if parent_diff_content:
- files['parent_diff_path'] = {
- 'filename': 'parent_diff',
- 'content': parent_diff_content
- }
-
- self.api_post('api/json/reviewrequests/%s/diff/new/' %
- review_request['id'], fields, files)
-
- def publish(self, review_request):
- """
- Publishes a review request.
- """
- debug("Publishing")
- self.api_post('api/json/reviewrequests/%s/publish/' %
- review_request['id'])
-
- def _get_server_info(self):
- if not self._server_info:
- self._server_info = self._info.find_server_repository_info(self)
-
- return self._server_info
-
- info = property(_get_server_info)
-
- def process_json(self, data):
- """
- Loads in a JSON file and returns the data if successful. On failure,
- APIError is raised.
- """
- rsp = json.loads(data)
-
- if rsp['stat'] == 'fail':
- raise APIError, rsp
-
- return rsp
-
- def http_get(self, path):
- """
- Performs an HTTP GET on the specified path, storing any cookies that
- were set.
- """
- debug('HTTP GETting %s' % path)
-
- url = self._make_url(path)
-
- try:
- rsp = urllib2.urlopen(url).read()
- self.cookie_jar.save(self.cookie_file)
- return rsp
- except urllib2.HTTPError, e:
- print "Unable to access %s (%s). The host path may be invalid" % \
- (url, e.code)
- try:
- debug(e.read())
- except AttributeError:
- pass
- die()
-
- def _make_url(self, path):
- """Given a path on the server returns a full http:// style url"""
- app = urlparse(self.url)[2]
- if path[0] == '/':
- url = urljoin(self.url, app[:-1] + path)
- else:
- url = urljoin(self.url, app + path)
-
- if not url.startswith('http'):
- url = 'http://%s' % url
- return url
-
- def api_get(self, path):
- """
- Performs an API call using HTTP GET at the specified path.
- """
- return self.process_json(self.http_get(path))
-
- def http_post(self, path, fields, files=None):
- """
- Performs an HTTP POST on the specified path, storing any cookies that
- were set.
- """
- if fields:
- debug_fields = fields.copy()
- else:
- debug_fields = {}
-
- if 'password' in debug_fields:
- debug_fields["password"] = "**************"
- url = self._make_url(path)
- debug('HTTP POSTing to %s: %s' % (url, debug_fields))
-
- content_type, body = self._encode_multipart_formdata(fields, files)
- headers = {
- 'Content-Type': content_type,
- 'Content-Length': str(len(body))
- }
-
- try:
- r = urllib2.Request(url, body, headers)
- data = urllib2.urlopen(r).read()
- self.cookie_jar.save(self.cookie_file)
- return data
- except urllib2.URLError, e:
- try:
- debug(e.read())
- except AttributeError:
- pass
-
- die("Unable to access %s. The host path may be invalid\n%s" % \
- (url, e))
- except urllib2.HTTPError, e:
- die("Unable to access %s (%s). The host path may be invalid\n%s" % \
- (url, e.code, e.read()))
-
- def api_post(self, path, fields=None, files=None):
- """
- Performs an API call using HTTP POST at the specified path.
- """
- return self.process_json(self.http_post(path, fields, files))
-
- def _encode_multipart_formdata(self, fields, files):
- """
- Encodes data for use in an HTTP POST.
- """
- BOUNDARY = mimetools.choose_boundary()
- content = ""
-
- fields = fields or {}
- files = files or {}
-
- for key in fields:
- content += "--" + BOUNDARY + "\r\n"
- content += "Content-Disposition: form-data; name=\"%s\"\r\n" % key
- content += "\r\n"
- content += fields[key] + "\r\n"
-
- for key in files:
- filename = files[key]['filename']
- value = files[key]['content']
- content += "--" + BOUNDARY + "\r\n"
- content += "Content-Disposition: form-data; name=\"%s\"; " % key
- content += "filename=\"%s\"\r\n" % filename
- content += "\r\n"
- content += value + "\r\n"
-
- content += "--" + BOUNDARY + "--\r\n"
- content += "\r\n"
-
- content_type = "multipart/form-data; boundary=%s" % BOUNDARY
-
- return content_type, content
-
-
-class SCMClient(object):
- """
- A base representation of an SCM tool for fetching repository information
- and generating diffs.
- """
- def get_repository_info(self):
- return None
-
- def scan_for_server(self, repository_info):
- """
- Scans the current directory on up to find a .reviewboard file
- containing the server path.
- """
- server_url = self._get_server_from_config(user_config, repository_info)
- if server_url:
- return server_url
-
- for path in walk_parents(os.getcwd()):
- filename = os.path.join(path, ".reviewboardrc")
- if os.path.exists(filename):
- config = load_config_file(filename)
- server_url = self._get_server_from_config(config,
- repository_info)
- if server_url:
- return server_url
-
- return None
-
- def diff(self, args):
- """
- Returns the generated diff and optional parent diff for this
- repository.
-
- The returned tuple is (diff_string, parent_diff_string)
- """
- return (None, None)
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- """
- Returns the generated diff between revisions in the repository.
- """
- return None
-
- def _get_server_from_config(self, config, repository_info):
- if 'REVIEWBOARD_URL' in config:
- return config['REVIEWBOARD_URL']
- elif 'TREES' in config:
- trees = config['TREES']
- if not isinstance(trees, dict):
- die("Warning: 'TREES' in config file is not a dict!")
-
- if repository_info.path in trees and \
- 'REVIEWBOARD_URL' in trees[repository_info.path]:
- return trees[repository_info.path]['REVIEWBOARD_URL']
-
- return None
-
-
-class CVSClient(SCMClient):
- """
- A wrapper around the cvs tool that fetches repository
- information and generates compatible diffs.
- """
- def get_repository_info(self):
- if not check_install("cvs"):
- return None
-
- cvsroot_path = os.path.join("CVS", "Root")
-
- if not os.path.exists(cvsroot_path):
- return None
-
- fp = open(cvsroot_path, "r")
- repository_path = fp.read().strip()
- fp.close()
-
- i = repository_path.find("@")
- if i != -1:
- repository_path = repository_path[i + 1:]
-
- i = repository_path.find(":")
- if i != -1:
- host = repository_path[:i]
- try:
- canon = socket.getfqdn(host)
- repository_path = repository_path.replace('%s:' % host,
- '%s:' % canon)
- except socket.error, msg:
- debug("failed to get fqdn for %s, msg=%s" % (host, msg))
-
- return RepositoryInfo(path=repository_path)
-
- def diff(self, files):
- """
- Performs a diff across all modified files in a CVS repository.
-
- CVS repositories do not support branches of branches in a way that
- makes parent diffs possible, so we never return a parent diff
- (the second value in the tuple).
- """
- return (self.do_diff(files), None)
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- """
- Performs a diff between 2 revisions of a CVS repository.
- """
- revs = []
-
- for rev in revision_range.split(":"):
- revs += ["-r", rev]
-
- return self.do_diff(revs)
-
- def do_diff(self, params):
- """
- Performs the actual diff operation through cvs diff, handling
- fake errors generated by CVS.
- """
- # Diff returns "1" if differences were found.
- return execute(["cvs", "diff", "-uN"] + params,
- extra_ignore_errors=(1,))
-
-
-class ClearCaseClient(SCMClient):
- """
- A wrapper around the clearcase tool that fetches repository
- information and generates compatible diffs.
- This client assumes that cygwin is installed on windows.
- """
- ccroot_path = "/view/reviewboard.diffview/vobs/"
- viewinfo = ""
- viewtype = "snapshot"
-
- def get_filename_hash(self, fname):
- # Hash the filename string so its easy to find the file later on.
- return md5(fname).hexdigest()
-
- def get_repository_info(self):
- if not check_install('cleartool help'):
- return None
-
- # We must be running this from inside a view.
- # Otherwise it doesn't make sense.
- self.viewinfo = execute(["cleartool", "pwv", "-short"])
- if self.viewinfo.startswith('\*\* NONE'):
- return None
-
- # Returning the hardcoded clearcase root path to match the server
- # respository path.
- # There is no reason to have a dynamic path unless you have
- # multiple clearcase repositories. This should be implemented.
- return RepositoryInfo(path=self.ccroot_path,
- base_path=self.ccroot_path,
- supports_parent_diffs=False)
-
- def get_previous_version(self, files):
- file = []
- curdir = os.getcwd()
-
- # Cygwin case must transform a linux-like path to windows like path
- # including drive letter.
- if 'cygdrive' in curdir:
- where = curdir.index('cygdrive') + 9
- drive_letter = curdir[where:where+1]
- curdir = drive_letter + ":\\" + curdir[where+2:len(curdir)]
-
- for key in files:
- # Sometimes there is a quote in the filename. It must be removed.
- key = key.replace('\'', '')
- elem_path = cpath.normpath(os.path.join(curdir, key))
-
- # Removing anything before the last /vobs
- # because it may be repeated.
- elem_path_idx = elem_path.rfind("/vobs")
- if elem_path_idx != -1:
- elem_path = elem_path[elem_path_idx:len(elem_path)].strip("\"")
-
- # Call cleartool to get this version and the previous version
- # of the element.
- curr_version, pre_version = execute(
- ["cleartool", "desc", "-pre", elem_path])
- curr_version = cpath.normpath(curr_version)
- pre_version = pre_version.split(':')[1].strip()
-
- # If a specific version was given, remove it from the path
- # to avoid version duplication
- if "@@" in elem_path:
- elem_path = elem_path[:elem_path.rfind("@@")]
- file.append(elem_path + "@@" + pre_version)
- file.append(curr_version)
-
- # Determnine if the view type is snapshot or dynamic.
- if os.path.exists(file[0]):
- self.viewtype = "dynamic"
-
- return file
-
- def get_extended_namespace(self, files):
- """
- Parses the file path to get the extended namespace
- """
- versions = self.get_previous_version(files)
-
- evfiles = []
- hlist = []
-
- for vkey in versions:
- # Verify if it is a checkedout file.
- if "CHECKEDOUT" in vkey:
- # For checkedout files just add it to the file list
- # since it cannot be accessed outside the view.
- splversions = vkey[:vkey.rfind("@@")]
- evfiles.append(splversions)
- else:
- # For checkedin files.
- ext_path = []
- ver = []
- fname = "" # fname holds the file name without the version.
- (bpath, fpath) = cpath.splitdrive(vkey)
- if bpath :
- # Windows.
- # The version (if specified like file.c@@/main/1)
- # should be kept as a single string
- # so split the path and concat the file name
- # and version in the last position of the list.
- ver = fpath.split("@@")
- splversions = fpath[:vkey.rfind("@@")].split("\\")
- fname = splversions.pop()
- splversions.append(fname + ver[1])
- else :
- # Linux.
- bpath = vkey[:vkey.rfind("vobs")+4]
- fpath = vkey[vkey.rfind("vobs")+5:]
- ver = fpath.split("@@")
- splversions = ver[0][:vkey.rfind("@@")].split("/")
- fname = splversions.pop()
- splversions.append(fname + ver[1])
-
- filename = splversions.pop()
- bpath = cpath.normpath(bpath + "/")
- elem_path = bpath
-
- for key in splversions:
- # For each element (directory) in the path,
- # get its version from clearcase.
- elem_path = cpath.join(elem_path, key)
-
- # This is the version to be appended to the extended
- # path list.
- this_version = execute(
- ["cleartool", "desc", "-fmt", "%Vn",
- cpath.normpath(elem_path)])
- if this_version:
- ext_path.append(key + "/@@" + this_version + "/")
- else:
- ext_path.append(key + "/")
-
- # This must be done in case we haven't specified
- # the version on the command line.
- ext_path.append(cpath.normpath(fname + "/@@" +
- vkey[vkey.rfind("@@")+2:len(vkey)]))
- epstr = cpath.join(bpath, cpath.normpath(''.join(ext_path)))
- evfiles.append(epstr)
-
- """
- In windows, there is a problem with long names(> 254).
- In this case, we hash the string and copy the unextended
- filename to a temp file whose name is the hash.
- This way we can get the file later on for diff.
- The same problem applies to snapshot views where the
- extended name isn't available.
- The previous file must be copied from the CC server
- to a local dir.
- """
- if cpath.exists(epstr) :
- pass
- else:
- if len(epstr) > 254 or self.viewtype == "snapshot":
- name = self.get_filename_hash(epstr)
- # Check if this hash is already in the list
- try:
- i = hlist.index(name)
- die("ERROR: duplicate value %s : %s" %
- (name, epstr))
- except ValueError:
- hlist.append(name)
-
- normkey = cpath.normpath(vkey)
- td = tempfile.gettempdir()
- # Cygwin case must transform a linux-like path to
- # windows like path including drive letter
- if 'cygdrive' in td:
- where = td.index('cygdrive') + 9
- drive_letter = td[where:where+1] + ":"
- td = cpath.join(drive_letter, td[where+1:])
- tf = cpath.normpath(cpath.join(td, name))
- if cpath.exists(tf):
- debug("WARNING: FILE EXISTS")
- os.unlink(tf)
- execute(["cleartool", "get", "-to", tf, normkey])
- else:
- die("ERROR: FILE NOT FOUND : %s" % epstr)
-
- return evfiles
-
- def get_files_from_label(self, label):
- voblist=[]
- # Get the list of vobs for the current view
- allvoblist = execute(["cleartool", "lsvob", "-short"]).split()
- # For each vob, find if the label is present
- for vob in allvoblist:
- try:
- execute(["cleartool", "describe", "-local",
- "lbtype:%s@%s" % (label, vob)]).split()
- voblist.append(vob)
- except:
- pass
-
- filelist=[]
- # For each vob containing the label, get the file list
- for vob in voblist:
- try:
- res = execute(["cleartool", "find", vob, "-all", "-version",
- "lbtype(%s)" % label, "-print"])
- filelist.extend(res.split())
- except :
- pass
-
- # Return only the unique itens
- return set(filelist)
-
- def diff(self, files):
- """
- Performs a diff of the specified file and its previous version.
- """
- # We must be running this from inside a view.
- # Otherwise it doesn't make sense.
- return self.do_diff(self.get_extended_namespace(files))
-
- def diff_label(self, label):
- """
- Get the files that are attached to a label and diff them
- TODO
- """
- return self.diff(self.get_files_from_label(label))
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- """
- Performs a diff between 2 revisions of a CC repository.
- """
- rev_str = ''
-
- for rev in revision_range.split(":"):
- rev_str += "-r %s " % rev
-
- return self.do_diff(rev_str)
-
- def do_diff(self, params):
- # Diff returns "1" if differences were found.
- # Add the view name and view type to the description
- if options.description:
- options.description = ("VIEW: " + self.viewinfo +
- "VIEWTYPE: " + self.viewtype + "\n" + options.description)
- else:
- options.description = (self.viewinfo +
- "VIEWTYPE: " + self.viewtype + "\n")
-
- o = []
- Feol = False
- while len(params) > 0:
- # Read both original and modified files.
- onam = params.pop(0)
- mnam = params.pop(0)
- file_data = []
- do_rem = False
- # If the filename length is greater than 254 char for windows,
- # we copied the file to a temp file
- # because the open will not work for path greater than 254.
- # This is valid for the original and
- # modified files if the name size is > 254.
- for filenam in (onam, mnam) :
- if cpath.exists(filenam) and self.viewtype == "dynamic":
- do_rem = False
- fn = filenam
- elif len(filenam) > 254 or self.viewtype == "snapshot":
- fn = self.get_filename_hash(filenam)
- fn = cpath.join(tempfile.gettempdir(), fn)
- do_rem = True
- fd = open(cpath.normpath(fn))
- fdata = fd.readlines()
- fd.close()
- file_data.append(fdata)
- # If the file was temp, it should be removed.
- if do_rem:
- os.remove(filenam)
-
- modi = file_data.pop()
- orig = file_data.pop()
-
- # For snapshot views, the local directories must be removed because
- # they will break the diff on the server. Just replacing
- # everything before the view name (including the view name) for
- # vobs do the work.
- if (self.viewtype == "snapshot"
- and (sys.platform.startswith('win')
- or sys.platform.startswith('cygwin'))):
- vinfo = self.viewinfo.rstrip("\r\n")
- mnam = "c:\\\\vobs" + mnam[mnam.rfind(vinfo) + len(vinfo):]
- onam = "c:\\\\vobs" + onam[onam.rfind(vinfo) + len(vinfo):]
- # Call the diff lib to generate a diff.
- # The dates are bogus, since they don't natter anyway.
- # The only thing is that two spaces are needed to the server
- # so it can identify the heades correctly.
- diff = difflib.unified_diff(orig, modi, onam, mnam,
- ' 2002-02-21 23:30:39.942229878 -0800',
- ' 2002-02-21 23:30:50.442260588 -0800', lineterm=' \n')
- # Transform the generator output into a string output
- # Use a comprehension instead of a generator,
- # so 2.3.x doesn't fail to interpret.
- diffstr = ''.join([str(l) for l in diff])
- # Workaround for the difflib no new line at end of file
- # problem.
- if not diffstr.endswith('\n'):
- diffstr = diffstr + ("\n\\ No newline at end of file\n")
- o.append(diffstr)
-
- ostr = ''.join(o)
- return (ostr, None) # diff, parent_diff (not supported)
-
-
-class SVNClient(SCMClient):
- """
- A wrapper around the svn Subversion tool that fetches repository
- information and generates compatible diffs.
- """
- def get_repository_info(self):
- if not check_install('svn help'):
- return None
-
- # Get the SVN repository path (either via a working copy or
- # a supplied URI)
- svn_info_params = ["svn", "info"]
- if options.repository_url:
- svn_info_params.append(options.repository_url)
- data = execute(svn_info_params,
- ignore_errors=True)
- m = re.search(r'^Repository Root: (.+)$', data, re.M)
- if not m:
- return None
-
- path = m.group(1)
-
- m = re.search(r'^URL: (.+)$', data, re.M)
- if not m:
- return None
-
- base_path = m.group(1)[len(path):] or "/"
-
- m = re.search(r'^Repository UUID: (.+)$', data, re.M)
- if not m:
- return None
-
- return SvnRepositoryInfo(path, base_path, m.group(1))
-
- def scan_for_server(self, repository_info):
- # Scan first for dot files, since it's faster and will cover the
- # user's $HOME/.reviewboardrc
- server_url = super(SVNClient, self).scan_for_server(repository_info)
- if server_url:
- return server_url
-
- return self.scan_for_server_property(repository_info)
-
- def scan_for_server_property(self, repository_info):
- def get_url_prop(path):
- url = execute(["svn", "propget", "reviewboard:url", path]).strip()
- return url or None
-
- for path in walk_parents(os.getcwd()):
- if not os.path.exists(os.path.join(path, ".svn")):
- break
-
- prop = get_url_prop(path)
- if prop:
- return prop
-
- return get_url_prop(repository_info.path)
-
- def diff(self, files):
- """
- Performs a diff across all modified files in a Subversion repository.
-
- SVN repositories do not support branches of branches in a way that
- makes parent diffs possible, so we never return a parent diff
- (the second value in the tuple).
- """
- return (self.do_diff(["svn", "diff", "--diff-cmd=diff"] + files),
- None)
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- """
- Performs a diff between 2 revisions of a Subversion repository.
- """
- if options.repository_url:
- revisions = revision_range.split(':')
- if len(revisions) < 1:
- return None
- elif len(revisions) == 1:
- revisions.append('HEAD')
-
- # if a new path was supplied at the command line, set it
- if len(args):
- repository_info.set_base_path(args[0])
-
- url = repository_info.path + repository_info.base_path
-
- old_url = url + '@' + revisions[0]
- new_url = url + '@' + revisions[1]
-
- return self.do_diff(["svn", "diff", "--diff-cmd=diff", old_url,
- new_url],
- repository_info)
- # Otherwise, perform the revision range diff using a working copy
- else:
- return self.do_diff(["svn", "diff", "--diff-cmd=diff", "-r",
- revision_range],
- repository_info)
-
- def do_diff(self, cmd, repository_info=None):
- """
- Performs the actual diff operation, handling renames and converting
- paths to absolute.
- """
- diff = execute(cmd, split_lines=True)
- diff = self.handle_renames(diff)
- diff = self.convert_to_absolute_paths(diff, repository_info)
-
- return ''.join(diff)
-
- def handle_renames(self, diff_content):
- """
- The output of svn diff is incorrect when the file in question came
- into being via svn mv/cp. Although the patch for these files are
- relative to its parent, the diff header doesn't reflect this.
- This function fixes the relevant section headers of the patch to
- portray this relationship.
- """
-
- # svn diff against a repository URL on two revisions appears to
- # handle moved files properly, so only adjust the diff file names
- # if they were created using a working copy.
- if options.repository_url:
- return diff_content
-
- result = []
-
- from_line = ""
- for line in diff_content:
- if line.startswith('--- '):
- from_line = line
- continue
-
- # This is where we decide how mangle the previous '--- '
- if line.startswith('+++ '):
- to_file, _ = self.parse_filename_header(line[4:])
- info = self.svn_info(to_file)
- if info.has_key("Copied From URL"):
- url = info["Copied From URL"]
- root = info["Repository Root"]
- from_file = urllib.unquote(url[len(root):])
- result.append(from_line.replace(to_file, from_file))
- else:
- result.append(from_line) #as is, no copy performed
-
- # We only mangle '---' lines. All others get added straight to
- # the output.
- result.append(line)
-
- return result
-
-
- def convert_to_absolute_paths(self, diff_content, repository_info):
- """
- Converts relative paths in a diff output to absolute paths.
- This handles paths that have been svn switched to other parts of the
- repository.
- """
-
- result = []
-
- for line in diff_content:
- front = None
- if line.startswith('+++ ') or line.startswith('--- ') or line.startswith('Index: '):
- front, line = line.split(" ", 1)
-
- if front:
- if line.startswith('/'): #already absolute
- line = front + " " + line
- else:
- # filename and rest of line (usually the revision
- # component)
- file, rest = self.parse_filename_header(line)
-
- # If working with a diff generated outside of a working
- # copy, then file paths are already absolute, so just
- # add initial slash.
- if options.repository_url:
- path = urllib.unquote(
- "%s/%s" % (repository_info.base_path, file))
- else:
- info = self.svn_info(file)
- url = info["URL"]
- root = info["Repository Root"]
- path = urllib.unquote(url[len(root):])
-
- line = front + " " + path + rest
-
- result.append(line)
-
- return result
-
- def svn_info(self, path):
- """Return a dict which is the result of 'svn info' at a given path."""
- svninfo = {}
- for info in execute(["svn", "info", path],
- split_lines=True):
- parts = info.strip().split(": ", 1)
- if len(parts) == 2:
- key, value = parts
- svninfo[key] = value
-
- return svninfo
-
- # Adapted from server code parser.py
- def parse_filename_header(self, s):
- parts = None
- if "\t" in s:
- # There's a \t separating the filename and info. This is the
- # best case scenario, since it allows for filenames with spaces
- # without much work.
- parts = s.split("\t")
-
- # There's spaces being used to separate the filename and info.
- # This is technically wrong, so all we can do is assume that
- # 1) the filename won't have multiple consecutive spaces, and
- # 2) there's at least 2 spaces separating the filename and info.
- if " " in s:
- parts = re.split(r" +", s)
-
- if parts:
- parts[1] = '\t' + parts[1]
- return parts
-
- # strip off ending newline, and return it as the second component
- return [s.split('\n')[0], '\n']
-
-
-class PerforceClient(SCMClient):
- """
- A wrapper around the p4 Perforce tool that fetches repository information
- and generates compatible diffs.
- """
- def get_repository_info(self):
- if not check_install('p4 help'):
- return None
-
- data = execute(["p4", "info"], ignore_errors=True)
-
- m = re.search(r'^Server address: (.+)$', data, re.M)
- if not m:
- return None
-
- repository_path = m.group(1).strip()
-
- try:
- hostname, port = repository_path.split(":")
- info = socket.gethostbyaddr(hostname)
- repository_path = "%s:%s" % (info[0], port)
- except (socket.gaierror, socket.herror):
- pass
-
- return RepositoryInfo(path=repository_path, supports_changesets=True)
-
- def scan_for_server(self, repository_info):
- # Scan first for dot files, since it's faster and will cover the
- # user's $HOME/.reviewboardrc
- server_url = \
- super(PerforceClient, self).scan_for_server(repository_info)
-
- if server_url:
- return server_url
-
- return self.scan_for_server_counter(repository_info)
-
- def scan_for_server_counter(self, repository_info):
- """
- Checks the Perforce counters to see if the Review Board server's url
- is specified. Since Perforce only started supporting non-numeric
- counter values in server version 2008.1, we support both a normal
- counter 'reviewboard.url' with a string value and embedding the url in
- a counter name like 'reviewboard.url.http:||reviewboard.example.com'.
- Note that forward slashes aren't allowed in counter names, so
- pipe ('|') characters should be used. These should be safe because they
- should not be used unencoded in urls.
- """
-
- counters_text = execute(["p4", "counters"])
-
- # Try for a "reviewboard.url" counter first.
- m = re.search(r'^reviewboard.url = (\S+)', counters_text, re.M)
-
- if m:
- return m.group(1)
-
- # Next try for a counter of the form:
- # reviewboard_url.http:||reviewboard.example.com
- m2 = re.search(r'^reviewboard.url\.(\S+)', counters_text, re.M)
-
- if m2:
- return m2.group(1).replace('|', '/')
-
- return None
-
- def get_changenum(self, args):
- if len(args) == 1:
- try:
- return str(int(args[0]))
- except ValueError:
- pass
- return None
-
- def diff(self, args):
- """
- Goes through the hard work of generating a diff on Perforce in order
- to take into account adds/deletes and to provide the necessary
- revision information.
- """
- # set the P4 enviroment:
- if options.p4_client:
- os.environ['P4CLIENT'] = options.p4_client
-
- if options.p4_port:
- os.environ['P4PORT'] = options.p4_port
-
- changenum = self.get_changenum(args)
- if changenum is None:
- return self._path_diff(args)
- else:
- return self._changenum_diff(changenum)
-
-
- def _path_diff(self, args):
- """
- Process a path-style diff. See _changenum_diff for the alternate
- version that handles specific change numbers.
-
- Multiple paths may be specified in `args`. The path styles supported
- are:
-
- //path/to/file
- Upload file as a "new" file.
-
- //path/to/dir/...
- Upload all files as "new" files.
-
- //path/to/file[@#]rev
- Upload file from that rev as a "new" file.
-
- //path/to/file[@#]rev,[@#]rev
- Upload a diff between revs.
-
- //path/to/dir/...[@#]rev,[@#]rev
- Upload a diff of all files between revs in that directory.
- """
- r_revision_range = re.compile(r'^(?P<path>//[^@#]+)' +
- r'(?P<revision1>[#@][^,]+)?' +
- r'(?P<revision2>,[#@][^,]+)?$')
-
- empty_filename = make_tempfile()
- tmp_diff_from_filename = make_tempfile()
- tmp_diff_to_filename = make_tempfile()
-
- diff_lines = []
-
- for path in args:
- m = r_revision_range.match(path)
-
- if not m:
- die('Path %r does not match a valid Perforce path.' % (path,))
- revision1 = m.group('revision1')
- revision2 = m.group('revision2')
- first_rev_path = m.group('path')
-
- if revision1:
- first_rev_path += revision1
- records = self._run_p4(['files', first_rev_path])
-
- # Make a map for convenience.
- files = {}
-
- # Records are:
- # 'rev': '1'
- # 'func': '...'
- # 'time': '1214418871'
- # 'action': 'edit'
- # 'type': 'ktext'
- # 'depotFile': '...'
- # 'change': '123456'
- for record in records:
- if record['action'] != 'delete':
- if revision2:
- files[record['depotFile']] = [record, None]
- else:
- files[record['depotFile']] = [None, record]
-
- if revision2:
- # [1:] to skip the comma.
- second_rev_path = m.group('path') + revision2[1:]
- records = self._run_p4(['files', second_rev_path])
- for record in records:
- if record['action'] != 'delete':
- try:
- m = files[record['depotFile']]
- m[1] = record
- except KeyError:
- files[record['depotFile']] = [None, record]
-
- old_file = new_file = empty_filename
- changetype_short = None
-
- for depot_path, (first_record, second_record) in files.items():
- old_file = new_file = empty_filename
- if first_record is None:
- self._write_file(depot_path + '#' + second_record['rev'],
- tmp_diff_to_filename)
- new_file = tmp_diff_to_filename
- changetype_short = 'A'
- base_revision = 0
- elif second_record is None:
- self._write_file(depot_path + '#' + first_record['rev'],
- tmp_diff_from_filename)
- old_file = tmp_diff_from_filename
- changetype_short = 'D'
- base_revision = int(first_record['rev'])
- else:
- self._write_file(depot_path + '#' + first_record['rev'],
- tmp_diff_from_filename)
- self._write_file(depot_path + '#' + second_record['rev'],
- tmp_diff_to_filename)
- new_file = tmp_diff_to_filename
- old_file = tmp_diff_from_filename
- changetype_short = 'M'
- base_revision = int(first_record['rev'])
-
- dl = self._do_diff(old_file, new_file, depot_path,
- base_revision, changetype_short,
- ignore_unmodified=True)
- diff_lines += dl
-
- os.unlink(empty_filename)
- os.unlink(tmp_diff_from_filename)
- os.unlink(tmp_diff_to_filename)
- return (''.join(diff_lines), None)
-
- def _run_p4(self, command):
- """Execute a perforce command using the python marshal API.
-
- - command: A list of strings of the command to execute.
-
- The return type depends on the command being run.
- """
- command = ['p4', '-G'] + command
- p = subprocess.Popen(command, stdout=subprocess.PIPE)
- result = []
- has_error = False
-
- while 1:
- try:
- data = marshal.load(p.stdout)
- except EOFError:
- break
- else:
- result.append(data)
- if data.get('code', None) == 'error':
- has_error = True
-
- rc = p.wait()
-
- if rc or has_error:
- for record in result:
- if 'data' in record:
- print record['data']
- die('Failed to execute command: %s\n' % (command,))
-
- return result
-
- def _changenum_diff(self, changenum):
- """
- Process a diff for a particular change number. This handles both
- pending and submitted changelists.
-
- See _path_diff for the alternate version that does diffs of depot
- paths.
- """
- # TODO: It might be a good idea to enhance PerforceDiffParser to
- # understand that newFile could include a revision tag for post-submit
- # reviewing.
- cl_is_pending = False
-
- debug("Generating diff for changenum %s" % changenum)
-
- description = execute(["p4", "describe", "-s", changenum],
- split_lines=True)
-
- if '*pending*' in description[0]:
- cl_is_pending = True
-
- # Get the file list
- for line_num, line in enumerate(description):
- if 'Affected files ...' in line:
- break
- else:
- # Got to the end of all the description lines and didn't find
- # what we were looking for.
- die("Couldn't find any affected files for this change.")
-
- description = description[line_num+2:]
-
- diff_lines = []
-
- empty_filename = make_tempfile()
- tmp_diff_from_filename = make_tempfile()
- tmp_diff_to_filename = make_tempfile()
-
- for line in description:
- line = line.strip()
- if not line:
- continue
-
- m = re.search(r'\.\.\. ([^#]+)#(\d+) (add|edit|delete|integrate|branch)', line)
- if not m:
- die("Unsupported line from p4 opened: %s" % line)
-
- depot_path = m.group(1)
- base_revision = int(m.group(2))
- if not cl_is_pending:
- # If the changelist is pending our base revision is the one that's
- # currently in the depot. If we're not pending the base revision is
- # actually the revision prior to this one
- base_revision -= 1
-
- changetype = m.group(3)
-
- debug('Processing %s of %s' % (changetype, depot_path))
-
- old_file = new_file = empty_filename
- old_depot_path = new_depot_path = None
- changetype_short = None
-
- if changetype == 'edit' or changetype == 'integrate':
- # A big assumption
- new_revision = base_revision + 1
-
- # We have an old file, get p4 to take this old version from the
- # depot and put it into a plain old temp file for us
- old_depot_path = "%s#%s" % (depot_path, base_revision)
- self._write_file(old_depot_path, tmp_diff_from_filename)
- old_file = tmp_diff_from_filename
-
- # Also print out the new file into a tmpfile
- if cl_is_pending:
- new_file = self._depot_to_local(depot_path)
- else:
- new_depot_path = "%s#%s" %(depot_path, new_revision)
- self._write_file(new_depot_path, tmp_diff_to_filename)
- new_file = tmp_diff_to_filename
-
- changetype_short = "M"
-
- elif changetype == 'add' or changetype == 'branch':
- # We have a new file, get p4 to put this new file into a pretty
- # temp file for us. No old file to worry about here.
- if cl_is_pending:
- new_file = self._depot_to_local(depot_path)
- else:
- self._write_file(depot_path, tmp_diff_to_filename)
- new_file = tmp_diff_to_filename
- changetype_short = "A"
-
- elif changetype == 'delete':
- # We've deleted a file, get p4 to put the deleted file into a temp
- # file for us. The new file remains the empty file.
- old_depot_path = "%s#%s" % (depot_path, base_revision)
- self._write_file(old_depot_path, tmp_diff_from_filename)
- old_file = tmp_diff_from_filename
- changetype_short = "D"
- else:
- die("Unknown change type '%s' for %s" % (changetype, depot_path))
-
- dl = self._do_diff(old_file, new_file, depot_path, base_revision, changetype_short)
- diff_lines += dl
-
- os.unlink(empty_filename)
- os.unlink(tmp_diff_from_filename)
- os.unlink(tmp_diff_to_filename)
- return (''.join(diff_lines), None)
-
- def _do_diff(self, old_file, new_file, depot_path, base_revision,
- changetype_short, ignore_unmodified=False):
- """
- Do the work of producing a diff for Perforce.
-
- old_file - The absolute path to the "old" file.
- new_file - The absolute path to the "new" file.
- depot_path - The depot path in Perforce for this file.
- base_revision - The base perforce revision number of the old file as
- an integer.
- changetype_short - The change type as a single character string.
- ignore_unmodified - If True, will return an empty list if the file
- is not changed.
-
- Returns a list of strings of diff lines.
- """
- if hasattr(os, 'uname') and os.uname()[0] == 'SunOS':
- diff_cmd = ["gdiff", "-urNp", old_file, new_file]
- else:
- diff_cmd = ["diff", "-urNp", old_file, new_file]
- # Diff returns "1" if differences were found.
- dl = execute(diff_cmd, extra_ignore_errors=(1,2),
- translate_newlines=False)
-
- # If the input file has ^M characters at end of line, lets ignore them.
- dl = dl.replace('\r\r\n', '\r\n')
- dl = dl.splitlines(True)
-
- cwd = os.getcwd()
- if depot_path.startswith(cwd):
- local_path = depot_path[len(cwd) + 1:]
- else:
- local_path = depot_path
-
- # Special handling for the output of the diff tool on binary files:
- # diff outputs "Files a and b differ"
- # and the code below expects the output to start with
- # "Binary files "
- if len(dl) == 1 and \
- dl[0] == ('Files %s and %s differ'% (old_file, new_file)):
- dl = ['Binary files %s and %s differ'% (old_file, new_file)]
-
- if dl == [] or dl[0].startswith("Binary files "):
- if dl == []:
- if ignore_unmodified:
- return []
- else:
- print "Warning: %s in your changeset is unmodified" % \
- local_path
-
- dl.insert(0, "==== %s#%s ==%s== %s ====\n" % \
- (depot_path, base_revision, changetype_short, local_path))
- dl.append('\n')
- else:
- m = re.search(r'(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)', dl[1])
- if m:
- timestamp = m.group(1)
- else:
- # Thu Sep 3 11:24:48 2007
- m = re.search(r'(\w+)\s+(\w+)\s+(\d+)\s+(\d\d:\d\d:\d\d)\s+(\d\d\d\d)', dl[1])
- if not m:
- die("Unable to parse diff header: %s" % dl[1])
-
- month_map = {
- "Jan": "01",
- "Feb": "02",
- "Mar": "03",
- "Apr": "04",
- "May": "05",
- "Jun": "06",
- "Jul": "07",
- "Aug": "08",
- "Sep": "09",
- "Oct": "10",
- "Nov": "11",
- "Dec": "12",
- }
- month = month_map[m.group(2)]
- day = m.group(3)
- timestamp = m.group(4)
- year = m.group(5)
-
- timestamp = "%s-%s-%s %s" % (year, month, day, timestamp)
-
- dl[0] = "--- %s\t%s#%s\n" % (local_path, depot_path, base_revision)
- dl[1] = "+++ %s\t%s\n" % (local_path, timestamp)
-
- return dl
-
- def _write_file(self, depot_path, tmpfile):
- """
- Grabs a file from Perforce and writes it to a temp file. p4 print sets
- the file readonly and that causes a later call to unlink fail. So we
- make the file read/write.
- """
- debug('Writing "%s" to "%s"' % (depot_path, tmpfile))
- execute(["p4", "print", "-o", tmpfile, "-q", depot_path])
- os.chmod(tmpfile, stat.S_IREAD | stat.S_IWRITE)
-
- def _depot_to_local(self, depot_path):
- """
- Given a path in the depot return the path on the local filesystem to
- the same file. If there are multiple results, take only the last
- result from the where command.
- """
- where_output = self._run_p4(['where', depot_path])
- return where_output[-1]['path']
-
-
-class MercurialClient(SCMClient):
- """
- A wrapper around the hg Mercurial tool that fetches repository
- information and generates compatible diffs.
- """
- def get_repository_info(self):
- if not check_install('hg --help'):
- return None
-
- data = execute(["hg", "root"], ignore_errors=True)
- if data.startswith('abort:'):
- # hg aborted => no mercurial repository here.
- return None
-
- # Elsewhere, hg root output give us the repository path.
-
- # We save data here to use it as a fallback. See below
- local_data = data.strip()
-
- svn = execute(["hg", "svn", "info", ], ignore_errors=True)
-
- if (not svn.startswith('abort:') and
- not svn.startswith("hg: unknown command")):
- self.type = 'svn'
- m = re.search(r'^Repository Root: (.+)$', svn, re.M)
-
- if not m:
- return None
-
- path = m.group(1)
- m2 = re.match(r'^(svn\+ssh|http|https)://([-a-zA-Z0-9.]*@)(.*)$',
- path)
- if m2:
- path = '%s://%s' % (m2.group(1), m2.group(3))
-
- m = re.search(r'^URL: (.+)$', svn, re.M)
-
- if not m:
- return None
-
- base_path = m.group(1)[len(path):] or "/"
- return RepositoryInfo(path=path,
- base_path=base_path,
- supports_parent_diffs=True)
-
- self.type = 'hg'
-
- # We are going to search .hg/hgrc for the default path.
- file_name = os.path.join(local_data,'.hg', 'hgrc')
-
- if not os.path.exists(file_name):
- return RepositoryInfo(path=local_data, base_path='/',
- supports_parent_diffs=True)
-
- f = open(file_name)
- data = f.read()
- f.close()
-
- m = re.search(r'^default\s+=\s+(.+)$', data, re.M)
-
- if not m:
- # Return the local path, if no default value is found.
- return RepositoryInfo(path=local_data, base_path='/',
- supports_parent_diffs=True)
-
- path = m.group(1).strip()
-
- return RepositoryInfo(path=path, base_path='',
- supports_parent_diffs=True)
-
- def diff(self, files):
- """
- Performs a diff across all modified files in a Mercurial repository.
- """
- # We don't support parent diffs with Mercurial yet, so we always
- # return None for the parent diff.
- if self.type == 'svn':
- parent = execute(['hg', 'parent', '--svn', '--template',
- '{node}\n']).strip()
-
- if options.parent_branch:
- parent = options.parent_branch
-
- if options.guess_summary and not options.summary:
- options.summary = execute(['hg', 'log', '-r.', '--template',
- r'{desc|firstline}\n'])
-
- if options.guess_description and not options.description:
- numrevs = len(execute(['hg', 'log', '-r.:%s' % parent,
- '--follow', '--template',
- r'{rev}\n']).strip().split('\n'))
- options.description = execute(['hg', 'log', '-r.:%s' % parent,
- '--follow', '--template',
- r'{desc}\n\n', '--limit',
- str(numrevs-1)]).strip()
-
- return (execute(["hg", "diff", "--svn", '-r%s:.' % parent]), None)
-
- return (execute(["hg", "diff"] + files), None)
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- """
- Performs a diff between 2 revisions of a Mercurial repository.
- """
- if self.type != 'hg':
- raise NotImplementedError
-
- r1, r2 = revision_range.split(':')
- return execute(["hg", "diff", "-r", r1, "-r", r2])
-
-
-class GitClient(SCMClient):
- """
- A wrapper around git that fetches repository information and generates
- compatible diffs. This will attempt to generate a diff suitable for the
- remote repository, whether git, SVN or Perforce.
- """
- def get_repository_info(self):
- if not check_install('git --help'):
- return None
-
- git_dir = execute(["git", "rev-parse", "--git-dir"],
- ignore_errors=True).strip()
-
- if git_dir.startswith("fatal:") or not os.path.isdir(git_dir):
- return None
-
- # post-review in directories other than the top level of
- # of a work-tree would result in broken diffs on the server
- os.chdir(os.path.dirname(os.path.abspath(git_dir)))
-
- # We know we have something we can work with. Let's find out
- # what it is. We'll try SVN first.
- data = execute(["git", "svn", "info"], ignore_errors=True)
-
- m = re.search(r'^Repository Root: (.+)$', data, re.M)
- if m:
- path = m.group(1)
- m = re.search(r'^URL: (.+)$', data, re.M)
-
- if m:
- base_path = m.group(1)[len(path):] or "/"
- m = re.search(r'^Repository UUID: (.+)$', data, re.M)
-
- if m:
- uuid = m.group(1)
- self.type = "svn"
-
- return SvnRepositoryInfo(path=path, base_path=base_path,
- uuid=uuid,
- supports_parent_diffs=True)
- else:
- # Versions of git-svn before 1.5.4 don't (appear to) support
- # 'git svn info'. If we fail because of an older git install,
- # here, figure out what version of git is installed and give
- # the user a hint about what to do next.
- version = execute(["git", "svn", "--version"], ignore_errors=True)
- version_parts = re.search('version (\d+)\.(\d+)\.(\d+)',
- version)
- svn_remote = execute(["git", "config", "--get",
- "svn-remote.svn.url"], ignore_errors=True)
-
- if (version_parts and
- not self.is_valid_version((int(version_parts.group(1)),
- int(version_parts.group(2)),
- int(version_parts.group(3))),
- (1, 5, 4)) and
- svn_remote):
- die("Your installation of git-svn must be upgraded to " + \
- "version 1.5.4 or later")
-
- # Okay, maybe Perforce.
- # TODO
-
- # Nope, it's git then.
- origin = execute(["git", "remote", "show", "origin"])
- m = re.search(r'URL: (.+)', origin)
- if m:
- url = m.group(1).rstrip('/')
- if url:
- self.type = "git"
- return RepositoryInfo(path=url, base_path='',
- supports_parent_diffs=True)
-
- return None
-
- def is_valid_version(self, actual, expected):
- """
- Takes two tuples, both in the form:
- (major_version, minor_version, micro_version)
- Returns true if the actual version is greater than or equal to
- the expected version, and false otherwise.
- """
- return (actual[0] > expected[0]) or \
- (actual[0] == expected[0] and actual[1] > expected[1]) or \
- (actual[0] == expected[0] and actual[1] == expected[1] and \
- actual[2] >= expected[2])
-
- def scan_for_server(self, repository_info):
- # Scan first for dot files, since it's faster and will cover the
- # user's $HOME/.reviewboardrc
- server_url = super(GitClient, self).scan_for_server(repository_info)
-
- if server_url:
- return server_url
-
- # TODO: Maybe support a server per remote later? Is that useful?
- url = execute(["git", "config", "--get", "reviewboard.url"],
- ignore_errors=True).strip()
- if url:
- return url
-
- if self.type == "svn":
- # Try using the reviewboard:url property on the SVN repo, if it
- # exists.
- prop = SVNClient().scan_for_server_property(repository_info)
-
- if prop:
- return prop
-
- return None
-
- def diff(self, args):
- """
- Performs a diff across all modified files in the branch, taking into
- account a parent branch.
- """
- parent_branch = options.parent_branch or "master"
-
- diff_lines = self.make_diff(parent_branch)
-
- if parent_branch != "master":
- parent_diff_lines = self.make_diff("master", parent_branch)
- else:
- parent_diff_lines = None
-
- if options.guess_summary and not options.summary:
- options.summary = execute(["git", "log", "--pretty=format:%s",
- "HEAD^.."], ignore_errors=True).strip()
-
- if options.guess_description and not options.description:
- options.description = execute(
- ["git", "log", "--pretty=format:%s%n%n%b", parent_branch + ".."],
- ignore_errors=True).strip()
-
- return (diff_lines, parent_diff_lines)
-
- def make_diff(self, parent_branch, source_branch=""):
- """
- Performs a diff on a particular branch range.
- """
- if self.type == "svn":
- diff_lines = execute(["git", "diff", "--no-color", "--no-prefix",
- "-r", "-u", "%s..%s" % (parent_branch,
- source_branch)],
- split_lines=True)
- return self.make_svn_diff(parent_branch, diff_lines)
- elif self.type == "git":
- return execute(["git", "diff", "--no-color", "--full-index",
- parent_branch])
-
- return None
-
- def make_svn_diff(self, parent_branch, diff_lines):
- """
- Formats the output of git diff such that it's in a form that
- svn diff would generate. This is needed so the SVNTool in Review
- Board can properly parse this diff.
- """
- rev = execute(["git", "svn", "find-rev", "master"]).strip()
-
- if not rev:
- return None
-
- diff_data = ""
- filename = ""
- revision = ""
- newfile = False
-
- for line in diff_lines:
- if line.startswith("diff "):
- # Grab the filename and then filter this out.
- # This will be in the format of:
- #
- # diff --git a/path/to/file b/path/to/file
- info = line.split(" ")
- diff_data += "Index: %s\n" % info[2]
- diff_data += "=" * 67
- diff_data += "\n"
- elif line.startswith("index "):
- # Filter this out.
- pass
- elif line.strip() == "--- /dev/null":
- # New file
- newfile = True
- elif line.startswith("--- "):
- newfile = False
- diff_data += "--- %s\t(revision %s)\n" % \
- (line[4:].strip(), rev)
- elif line.startswith("+++ "):
- filename = line[4:].strip()
- if newfile:
- diff_data += "--- %s\t(revision 0)\n" % filename
- diff_data += "+++ %s\t(revision 0)\n" % filename
- else:
- # We already printed the "--- " line.
- diff_data += "+++ %s\t(working copy)\n" % filename
- else:
- diff_data += line
-
- return diff_data
-
- def diff_between_revisions(self, revision_range, args, repository_info):
- pass
-
-
-SCMCLIENTS = (
- SVNClient(),
- CVSClient(),
- GitClient(),
- MercurialClient(),
- PerforceClient(),
- ClearCaseClient(),
-)
-
-def debug(s):
- """
- Prints debugging information if post-review was run with --debug
- """
- if DEBUG or options and options.debug:
- print ">>> %s" % s
-
-
-def make_tempfile():
- """
- Creates a temporary file and returns the path. The path is stored
- in an array for later cleanup.
- """
- fd, tmpfile = mkstemp()
- os.close(fd)
- tempfiles.append(tmpfile)
- return tmpfile
-
-
-def check_install(command):
- """
- Try executing an external command and return a boolean indicating whether
- that command is installed or not. The 'command' argument should be
- something that executes quickly, without hitting the network (for
- instance, 'svn help' or 'git --version').
- """
- try:
- p = subprocess.Popen(command.split(' '),
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- return True
- except OSError:
- return False
-
-
-def execute(command, env=None, split_lines=False, ignore_errors=False,
- extra_ignore_errors=(), translate_newlines=True):
- """
- Utility function to execute a command and return the output.
- """
- if isinstance(command, list):
- debug(subprocess.list2cmdline(command))
- else:
- debug(command)
-
- if env:
- env.update(os.environ)
- else:
- env = os.environ.copy()
-
- env['LC_ALL'] = 'en_US.UTF-8'
- env['LANGUAGE'] = 'en_US.UTF-8'
-
- if sys.platform.startswith('win'):
- p = subprocess.Popen(command,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- shell=False,
- universal_newlines=translate_newlines,
- env=env)
- else:
- p = subprocess.Popen(command,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- shell=False,
- close_fds=True,
- universal_newlines=translate_newlines,
- env=env)
- if split_lines:
- data = p.stdout.readlines()
- else:
- data = p.stdout.read()
- rc = p.wait()
- if rc and not ignore_errors and rc not in extra_ignore_errors:
- die('Failed to execute command: %s\n%s' % (command, data))
-
- return data
-
-
-def die(msg=None):
- """
- Cleanly exits the program with an error message. Erases all remaining
- temporary files.
- """
- for tmpfile in tempfiles:
- try:
- os.unlink(tmpfile)
- except:
- pass
-
- if msg:
- print msg
-
- sys.exit(1)
-
-
-def walk_parents(path):
- """
- Walks up the tree to the root directory.
- """
- while os.path.splitdrive(path)[1] != os.sep:
- yield path
- path = os.path.dirname(path)
-
-
-def load_config_file(filename):
- """
- Loads data from a config file.
- """
- config = {
- 'TREES': {},
- }
-
- if os.path.exists(filename):
- try:
- execfile(filename, config)
- except:
- pass
-
- return config
-
-
-def tempt_fate(server, tool, changenum, diff_content=None,
- parent_diff_content=None, submit_as=None, retries=3):
- """
- Attempts to create a review request on a Review Board server and upload
- a diff. On success, the review request path is displayed.
- """
- try:
- save_draft = False
-
- if options.rid:
- review_request = server.get_review_request(options.rid)
- else:
- review_request = server.new_review_request(changenum, submit_as)
-
- if options.target_groups:
- server.set_review_request_field(review_request, 'target_groups',
- options.target_groups)
- save_draft = True
-
- if options.target_people:
- server.set_review_request_field(review_request, 'target_people',
- options.target_people)
- save_draft = True
-
- if options.summary:
- server.set_review_request_field(review_request, 'summary',
- options.summary)
- save_draft = True
-
- if options.branch:
- server.set_review_request_field(review_request, 'branch',
- options.branch)
- save_draft = True
-
- if options.bugs_closed:
- server.set_review_request_field(review_request, 'bugs_closed',
- options.bugs_closed)
- save_draft = True
-
- if options.description:
- server.set_review_request_field(review_request, 'description',
- options.description)
- save_draft = True
-
- if options.testing_done:
- server.set_review_request_field(review_request, 'testing_done',
- options.testing_done)
- save_draft = True
-
- if save_draft:
- server.save_draft(review_request)
- except APIError, e:
- rsp, = e.args
- if rsp['err']['code'] == 103: # Not logged in
- retries = retries - 1
-
- # We had an odd issue where the server ended up a couple of
- # years in the future. Login succeeds but the cookie date was
- # "odd" so use of the cookie appeared to fail and eventually
- # ended up at max recursion depth :-(. Check for a maximum
- # number of retries.
- if retries >= 0:
- server.login(force=True)
- tempt_fate(server, tool, changenum, diff_content,
- parent_diff_content, submit_as, retries=retries)
- return
-
- if options.rid:
- die("Error getting review request %s: %s (code %s)" % \
- (options.rid, rsp['err']['msg'], rsp['err']['code']))
- else:
- die("Error creating review request: %s (code %s)" % \
- (rsp['err']['msg'], rsp['err']['code']))
-
-
- if not server.info.supports_changesets or not options.change_only:
- try:
- server.upload_diff(review_request, diff_content,
- parent_diff_content)
- except APIError, e:
- rsp, = e.args
- print "Error uploading diff: %s (%s)" % (rsp['err']['msg'],
- rsp['err']['code'])
- debug(rsp)
- die("Your review request still exists, but the diff is not " +
- "attached.")
-
- if options.publish:
- server.publish(review_request)
-
- request_url = 'r/' + str(review_request['id'])
- review_url = urljoin(server.url, request_url)
-
- if not review_url.startswith('http'):
- review_url = 'http://%s' % review_url
-
- print "Review request #%s posted." % (review_request['id'],)
- print
- print review_url
-
- return review_url
-
-
-def parse_options(args):
- parser = OptionParser(usage="%prog [-pond] [-r review_id] [changenum]",
- version="%prog " + VERSION)
-
- parser.add_option("-p", "--publish",
- dest="publish", action="store_true", default=PUBLISH,
- help="publish the review request immediately after "
- "submitting")
- parser.add_option("-r", "--review-request-id",
- dest="rid", metavar="ID", default=None,
- help="existing review request ID to update")
- parser.add_option("-o", "--open",
- dest="open_browser", action="store_true",
- default=OPEN_BROWSER,
- help="open a web browser to the review request page")
- parser.add_option("-n", "--output-diff",
- dest="output_diff_only", action="store_true",
- default=False,
- help="outputs a diff to the console and exits. "
- "Does not post")
- parser.add_option("--server",
- dest="server", default=REVIEWBOARD_URL,
- metavar="SERVER",
- help="specify a different Review Board server "
- "to use")
- parser.add_option("--diff-only",
- dest="diff_only", action="store_true", default=False,
- help="uploads a new diff, but does not update "
- "info from changelist")
- parser.add_option("--target-groups",
- dest="target_groups", default=TARGET_GROUPS,
- help="names of the groups who will perform "
- "the review")
- parser.add_option("--target-people",
- dest="target_people", default=TARGET_PEOPLE,
- help="names of the people who will perform "
- "the review")
- parser.add_option("--summary",
- dest="summary", default=None,
- help="summary of the review ")
- parser.add_option("--description",
- dest="description", default=None,
- help="description of the review ")
- parser.add_option("--description-file",
- dest="description_file", default=None,
- help="text file containing a description of the review")
- parser.add_option("--guess-summary",
- dest="guess_summary", action="store_true",
- default=False,
- help="guess summary from the latest commit (git/"
- "hgsubversion only)")
- parser.add_option("--guess-description",
- dest="guess_description", action="store_true",
- default=False,
- help="guess description based on commits on this branch "
- "(git/hgsubversion only)")
- parser.add_option("--testing-done",
- dest="testing_done", default=None,
- help="details of testing done ")
- parser.add_option("--testing-done-file",
- dest="testing_file", default=None,
- help="text file containing details of testing done ")
- parser.add_option("--branch",
- dest="branch", default=None,
- help="affected branch ")
- parser.add_option("--bugs-closed",
- dest="bugs_closed", default=None,
- help="list of bugs closed ")
- parser.add_option("--revision-range",
- dest="revision_range", default=None,
- help="generate the diff for review based on given "
- "revision range")
- parser.add_option("--label",
- dest="label", default=None,
- help="label (ClearCase Only) ")
- parser.add_option("--submit-as",
- dest="submit_as", default=SUBMIT_AS, metavar="USERNAME",
- help="user name to be recorded as the author of the "
- "review request, instead of the logged in user")
- parser.add_option("--username",
- dest="username", default=None, metavar="USERNAME",
- help="user name to be supplied to the reviewboard server")
- parser.add_option("--password",
- dest="password", default=None, metavar="PASSWORD",
- help="password to be supplied to the reviewboard server")
- parser.add_option("--change-only",
- dest="change_only", action="store_true",
- default=False,
- help="updates info from changelist, but does "
- "not upload a new diff (only available if your "
- "repository supports changesets)")
- parser.add_option("--parent",
- dest="parent_branch", default=None,
- metavar="PARENT_BRANCH",
- help="the parent branch this diff should be against "
- "(only available if your repository supports "
- "parent diffs)")
- parser.add_option("--p4-client",
- dest="p4_client", default=None,
- help="the Perforce client name that the review is in")
- parser.add_option("--p4-port",
- dest="p4_port", default=None,
- help="the Perforce servers IP address that the review is on")
- parser.add_option("--repository-url",
- dest="repository_url", default=None,
- help="the url for a repository for creating a diff "
- "outside of a working copy (currently only supported "
- "by Subversion). Requires --revision-range")
- parser.add_option("-d", "--debug",
- action="store_true", dest="debug", default=DEBUG,
- help="display debug output")
-
- (globals()["options"], args) = parser.parse_args(args)
-
- if options.description and options.description_file:
- sys.stderr.write("The --description and --description-file options "
- "are mutually exclusive.\n")
- sys.exit(1)
-
- if options.description_file:
- if os.path.exists(options.description_file):
- fp = open(options.description_file, "r")
- options.description = fp.read()
- fp.close()
- else:
- sys.stderr.write("The description file %s does not exist.\n" %
- options.description_file)
- sys.exit(1)
-
- if options.testing_done and options.testing_file:
- sys.stderr.write("The --testing-done and --testing-done-file options "
- "are mutually exclusive.\n")
- sys.exit(1)
-
- if options.testing_file:
- if os.path.exists(options.testing_file):
- fp = open(options.testing_file, "r")
- options.testing_done = fp.read()
- fp.close()
- else:
- sys.stderr.write("The testing file %s does not exist.\n" %
- options.testing_file)
- sys.exit(1)
-
- if options.repository_url and not options.revision_range:
- sys.stderr.write("The --repository-url option requires the "
- "--revision-range option.\n")
- sys.exit(1)
-
- return args
-
-def determine_client():
-
- repository_info = None
- tool = None
-
- # Try to find the SCM Client we're going to be working with.
- for tool in SCMCLIENTS:
- repository_info = tool.get_repository_info()
-
- if repository_info:
- break
-
- if not repository_info:
- if options.repository_url:
- print "No supported repository could be access at the supplied url."
- else:
- print "The current directory does not contain a checkout from a"
- print "supported source code repository."
- sys.exit(1)
-
- # Verify that options specific to an SCM Client have not been mis-used.
- if options.change_only and not repository_info.supports_changesets:
- sys.stderr.write("The --change-only option is not valid for the "
- "current SCM client.\n")
- sys.exit(1)
-
- if options.parent_branch and not repository_info.supports_parent_diffs:
- sys.stderr.write("The --parent option is not valid for the "
- "current SCM client.\n")
- sys.exit(1)
-
- if ((options.p4_client or options.p4_port) and \
- not isinstance(tool, PerforceClient)):
- sys.stderr.write("The --p4-client and --p4-port options are not valid "
- "for the current SCM client.\n")
- sys.exit(1)
-
- return (repository_info, tool)
-
-def main():
- if 'USERPROFILE' in os.environ:
- homepath = os.path.join(os.environ["USERPROFILE"], "Local Settings",
- "Application Data")
- elif 'HOME' in os.environ:
- homepath = os.environ["HOME"]
- else:
- homepath = ''
-
- # Load the config and cookie files
- globals()['user_config'] = \
- load_config_file(os.path.join(homepath, ".reviewboardrc"))
- cookie_file = os.path.join(homepath, ".post-review-cookies.txt")
-
- args = parse_options(sys.argv[1:])
-
- repository_info, tool = determine_client()
-
- # Try to find a valid Review Board server to use.
- if options.server:
- server_url = options.server
- else:
- server_url = tool.scan_for_server(repository_info)
-
- if not server_url:
- print "Unable to find a Review Board server for this source code tree."
- sys.exit(1)
-
- server = ReviewBoardServer(server_url, repository_info, cookie_file)
-
- if repository_info.supports_changesets:
- changenum = tool.get_changenum(args)
- else:
- changenum = None
-
- if options.revision_range:
- diff = tool.diff_between_revisions(options.revision_range, args,
- repository_info)
- parent_diff = None
- elif options.label and isinstance(tool, ClearCaseClient):
- diff, parent_diff = tool.diff_label(options.label)
- else:
- diff, parent_diff = tool.diff(args)
-
- if options.output_diff_only:
- print diff
- sys.exit(0)
-
- # Let's begin.
- server.login()
-
- review_url = tempt_fate(server, tool, changenum, diff_content=diff,
- parent_diff_content=parent_diff,
- submit_as=options.submit_as)
-
- # Load the review up in the browser if requested to:
- if options.open_browser:
- try:
- import webbrowser
- if 'open_new_tab' in dir(webbrowser):
- # open_new_tab is only in python 2.5+
- webbrowser.open_new_tab(review_url)
- elif 'open_new' in dir(webbrowser):
- webbrowser.open_new(review_url)
- else:
- os.system( 'start %s' % review_url )
- except:
- print 'Error opening review URL: %s' % review_url
-
-
-if __name__ == "__main__":
- main()
diff --git a/test/review b/test/review
deleted file mode 100755
index e1ccb9c0af..0000000000
--- a/test/review
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-
-if [ -z $1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "-help" ] || [ "$1" = "-?" ]; then
- echo "Usage: `basename $0` [rev] [args]\n"
- echo " [rev] : either the revision number without leading 'r' (post-commit),"
- echo " or '-loc' to create a review from current local changes (pre-commit)\n"
- echo " [args] : optional arguments:"
- echo " -r ID existing review request ID to update\n"
- exit 1
-fi
-
-POSTREVIEW=`dirname $0`/postreview.py
-
-if [ "$1" = "-loc" ]; then
- echo "creating review request from local changes..."
- REVARG=""
- LOG=""
- SUMMARY="local changes"
- REPO=""
-else
- REV=$1
- PREV=`expr $REV - 1`
- if [ $? -ne 0 ]; then
- echo "argument revision not a number: $REV"
- exit 1
- fi
-
- echo "creating review request for changeset $REV..."
-
- LOG="`svn log http://lampsvn.epfl.ch/svn-repos/scala -c $REV`"
- if [ $? -ne 0 ]; then
- echo "could not get svn log for revision $REV"
- exit 1
- fi
-
- REVARG="--revision-range=$PREV:$REV"
- SUMMARY="r$REV"
- REPO="--repository-url=http://lampsvn.epfl.ch/svn-repos/scala"
-fi
-
-
-shift # remove parameter $1 (revision)
-
-python $POSTREVIEW --server="https://chara2.epfl.ch" $REVARG --summary="$SUMMARY" --description="$LOG" $REPO -o $@
diff --git a/test/scaladoc/run/t4922.check b/test/scaladoc/run/t4922.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/t4922.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/t4922.scala b/test/scaladoc/run/t4922.scala
new file mode 100644
index 0000000000..bce87ac980
--- /dev/null
+++ b/test/scaladoc/run/t4922.scala
@@ -0,0 +1,32 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ // Test code
+ override def code = """
+ // This the default values should be displayed
+
+ object Test {
+ def f (a: Any = "".isEmpty) = ()
+ def g[A](b: A = null) = ()
+ }
+ """
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ val Test = rootPackage._object("Test")
+ val f = Test._method("f")
+ val g = Test._method("g")
+
+ def assertEqual(s1: String, s2: String) = assert(s1 == s2, s1 + " == " + s2)
+
+ assertEqual(f.valueParams(0)(0).defaultValue.get.expression, "\"\".isEmpty")
+ assertEqual(g.valueParams(0)(0).defaultValue.get.expression, "null")
+ }
+} \ No newline at end of file
diff --git a/tools/buildcp b/tools/buildcp
index 766ab81f90..3ae70e10a3 100755
--- a/tools/buildcp
+++ b/tools/buildcp
@@ -8,4 +8,4 @@ lib=$($dir/abspath $dir/../lib)
build=$($dir/abspath $dir/../build)
cp=$($dir/cpof $build/$1/classes):$build/asm/classes
-echo $cp:$lib/fjbg.jar:$lib/msil.jar:$lib/forkjoin.jar:$lib/jline.jar:$lib/extra/'*'
+echo $cp:$lib/forkjoin.jar:$lib/jline.jar:$lib/extra/'*'
diff --git a/tools/strapcp b/tools/strapcp
index 6a46b4e1c8..6a4044ae24 100755
--- a/tools/strapcp
+++ b/tools/strapcp
@@ -6,7 +6,6 @@ strap="$dir/../build/strap/classes"
[[ -d $strap ]] || { echo "Error: no directory at $strap"; exit 1; }
cp=$($dir/cpof $strap)
-fjbg=$($dir/abspath $dir/../lib/fjbg.jar)
asm=$($dir/abspath $dir/../build/asm/classes)
-echo $cp:$fjbg:$asm
+echo $cp:$asm