diff --git a/src/IKVM.Java/map.xml b/src/IKVM.Java/map.xml
index 2b7f194e3b..a970136c01 100644
--- a/src/IKVM.Java/map.xml
+++ b/src/IKVM.Java/map.xml
@@ -958,7 +958,7 @@
-
+
@@ -994,7 +994,7 @@
-
+
@@ -1005,7 +1005,7 @@
-
+
@@ -1016,7 +1016,7 @@
-
+
@@ -1025,7 +1025,7 @@
-
+
@@ -1071,7 +1071,7 @@
-
+
@@ -1106,7 +1106,7 @@
-
+
@@ -1144,7 +1144,7 @@
-
+
@@ -1189,7 +1189,7 @@
-
+
@@ -1249,7 +1249,7 @@
-
+
@@ -1290,7 +1290,7 @@
-
+
@@ -1306,7 +1306,7 @@
-
+
@@ -1327,7 +1327,7 @@
-
+
@@ -1335,7 +1335,7 @@
-
+
@@ -1347,21 +1347,21 @@
-
+
-
+
-
+
-
+
@@ -1395,23 +1395,23 @@
-
+
-
+
-
+
-
+
-
+
@@ -1437,12 +1437,12 @@
-
+
-
+
diff --git a/src/IKVM.Runtime/AccessStubConstructorMethodWrapper.cs b/src/IKVM.Runtime/AccessStubConstructorMethodWrapper.cs
index a459f93fcc..a12bdcdb50 100644
--- a/src/IKVM.Runtime/AccessStubConstructorMethodWrapper.cs
+++ b/src/IKVM.Runtime/AccessStubConstructorMethodWrapper.cs
@@ -33,7 +33,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class AccessStubConstructorMethodWrapper : SmartMethodWrapper
diff --git a/src/IKVM.Runtime/AccessStubMethodWrapper.cs b/src/IKVM.Runtime/AccessStubMethodWrapper.cs
index 6f2370b033..f3b0c1e01a 100644
--- a/src/IKVM.Runtime/AccessStubMethodWrapper.cs
+++ b/src/IKVM.Runtime/AccessStubMethodWrapper.cs
@@ -33,7 +33,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class AccessStubMethodWrapper : SmartMethodWrapper
diff --git a/src/IKVM.Runtime/Accessors/FieldAccessor.cs b/src/IKVM.Runtime/Accessors/FieldAccessor.cs
index 846734ef9d..ae6de18a0d 100644
--- a/src/IKVM.Runtime/Accessors/FieldAccessor.cs
+++ b/src/IKVM.Runtime/Accessors/FieldAccessor.cs
@@ -4,8 +4,6 @@
using System.Reflection.Emit;
using System.Threading;
-using IKVM.Internal;
-
namespace IKVM.Runtime.Accessors
{
diff --git a/src/IKVM.Runtime/Accessors/MethodAccessor.cs b/src/IKVM.Runtime/Accessors/MethodAccessor.cs
index 938437443e..e4adcdf015 100644
--- a/src/IKVM.Runtime/Accessors/MethodAccessor.cs
+++ b/src/IKVM.Runtime/Accessors/MethodAccessor.cs
@@ -3,8 +3,6 @@
using System.Reflection;
using System.Reflection.Emit;
-using IKVM.Internal;
-
namespace IKVM.Runtime.Accessors
{
diff --git a/src/IKVM.Runtime/Accessors/PropertyAccessor.cs b/src/IKVM.Runtime/Accessors/PropertyAccessor.cs
index 5cc554b8bb..43aa1c0cc3 100644
--- a/src/IKVM.Runtime/Accessors/PropertyAccessor.cs
+++ b/src/IKVM.Runtime/Accessors/PropertyAccessor.cs
@@ -2,8 +2,6 @@
using System.Reflection;
using System.Reflection.Emit;
-using IKVM.Internal;
-
namespace IKVM.Runtime.Accessors
{
diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs
index b95a73ffef..d9767a64bd 100644
--- a/src/IKVM.Runtime/Annotation.cs
+++ b/src/IKVM.Runtime/Annotation.cs
@@ -41,7 +41,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
abstract class Annotation
diff --git a/src/IKVM.Runtime/AnonymousTypeWrapper.cs b/src/IKVM.Runtime/AnonymousTypeWrapper.cs
index 64026ff51c..30805adb9e 100644
--- a/src/IKVM.Runtime/AnonymousTypeWrapper.cs
+++ b/src/IKVM.Runtime/AnonymousTypeWrapper.cs
@@ -39,7 +39,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if !IMPORTER && !EXPORTER
diff --git a/src/IKVM.Runtime/ArrayTypeWrapper.cs b/src/IKVM.Runtime/ArrayTypeWrapper.cs
index 7b5a7032d0..c3de24514a 100644
--- a/src/IKVM.Runtime/ArrayTypeWrapper.cs
+++ b/src/IKVM.Runtime/ArrayTypeWrapper.cs
@@ -39,7 +39,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class ArrayTypeWrapper : TypeWrapper
{
diff --git a/src/IKVM.Runtime/ArrayUtil.cs b/src/IKVM.Runtime/ArrayUtil.cs
index 546436720b..f684e22d60 100644
--- a/src/IKVM.Runtime/ArrayUtil.cs
+++ b/src/IKVM.Runtime/ArrayUtil.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class ArrayUtil
diff --git a/src/IKVM.Runtime/AssemblyClassLoader.cs b/src/IKVM.Runtime/AssemblyClassLoader.cs
index fbd581ac16..e5360edf6e 100644
--- a/src/IKVM.Runtime/AssemblyClassLoader.cs
+++ b/src/IKVM.Runtime/AssemblyClassLoader.cs
@@ -47,7 +47,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
internal class AssemblyClassLoader : ClassLoaderWrapper
diff --git a/src/IKVM.Runtime/Assertions.cs b/src/IKVM.Runtime/Assertions.cs
index 02ba076e2d..9c50d0bb29 100644
--- a/src/IKVM.Runtime/Assertions.cs
+++ b/src/IKVM.Runtime/Assertions.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System;
using System.Globalization;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Runtime
{
diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs
index 476120b10f..2391daa94f 100644
--- a/src/IKVM.Runtime/AttributeHelper.cs
+++ b/src/IKVM.Runtime/AttributeHelper.cs
@@ -48,7 +48,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class AttributeHelper
diff --git a/src/IKVM.Runtime/Attributes/AnnotationAttributeAttribute.cs b/src/IKVM.Runtime/Attributes/AnnotationAttributeAttribute.cs
index fab68f8bef..87d7423de2 100644
--- a/src/IKVM.Runtime/Attributes/AnnotationAttributeAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/AnnotationAttributeAttribute.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Attributes
{
diff --git a/src/IKVM.Runtime/Attributes/AnnotationDefaultAttribute.cs b/src/IKVM.Runtime/Attributes/AnnotationDefaultAttribute.cs
index ed432367c9..633652b30e 100644
--- a/src/IKVM.Runtime/Attributes/AnnotationDefaultAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/AnnotationDefaultAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Method)]
public sealed class AnnotationDefaultAttribute : Attribute
{
+
public const byte TAG_ENUM = (byte)'e';
public const byte TAG_CLASS = (byte)'c';
public const byte TAG_ANNOTATION = (byte)'@';
diff --git a/src/IKVM.Runtime/Attributes/ConstantPoolAttribute.cs b/src/IKVM.Runtime/Attributes/ConstantPoolAttribute.cs
index 2b43038bf8..d1c26a115b 100644
--- a/src/IKVM.Runtime/Attributes/ConstantPoolAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/ConstantPoolAttribute.cs
@@ -24,17 +24,15 @@ Jeroen Frijters
using System;
using System.Collections.Generic;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public sealed class ConstantPoolAttribute : Attribute
{
+
internal readonly object[] constantPool;
public ConstantPoolAttribute(object[] constantPool)
@@ -112,5 +110,7 @@ private static object Escape(object obj)
}
return obj;
}
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/DynamicAnnotationAttribute.cs b/src/IKVM.Runtime/Attributes/DynamicAnnotationAttribute.cs
index f984fdf32a..d8913c6655 100644
--- a/src/IKVM.Runtime/Attributes/DynamicAnnotationAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/DynamicAnnotationAttribute.cs
@@ -23,15 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class DynamicAnnotationAttribute : Attribute
{
+
private readonly object[] definition;
public DynamicAnnotationAttribute(object[] definition)
@@ -43,5 +41,7 @@ public object[] Definition
{
get { return definition; }
}
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs
index d45ba2363b..07c02a3674 100644
--- a/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/EnclosingMethodAttribute.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
#if IMPORTER || EXPORTER
using Type = IKVM.Reflection.Type;
@@ -31,9 +31,11 @@ Jeroen Frijters
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public sealed class EnclosingMethodAttribute : Attribute
{
+
private string className;
private string methodName;
private string methodSig;
@@ -48,34 +50,17 @@ public EnclosingMethodAttribute(string className, string methodName, string meth
internal EnclosingMethodAttribute SetClassName(Type type)
{
if (className == null)
- {
- className = IKVM.Internal.ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).Name;
- }
+ className = IKVM.Runtime.ClassLoaderWrapper.GetWrapperFromType(type.DeclaringType).Name;
+
return this;
}
- public string ClassName
- {
- get
- {
- return className;
- }
- }
+ public string ClassName => className;
- public string MethodName
- {
- get
- {
- return methodName;
- }
- }
+ public string MethodName => methodName;
+
+ public string MethodSignature => methodSig;
+
+ }
- public string MethodSignature
- {
- get
- {
- return methodSig;
- }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/ExceptionIsUnsafeForMappingAttribute.cs b/src/IKVM.Runtime/Attributes/ExceptionIsUnsafeForMappingAttribute.cs
index 66c0fa11d6..51ca7a45a9 100644
--- a/src/IKVM.Runtime/Attributes/ExceptionIsUnsafeForMappingAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/ExceptionIsUnsafeForMappingAttribute.cs
@@ -23,14 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class)]
public sealed class ExceptionIsUnsafeForMappingAttribute : Attribute
{
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/GhostInterfaceAttribute.cs b/src/IKVM.Runtime/Attributes/GhostInterfaceAttribute.cs
index 974a972609..432066719e 100644
--- a/src/IKVM.Runtime/Attributes/GhostInterfaceAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/GhostInterfaceAttribute.cs
@@ -23,14 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Struct)]
public sealed class GhostInterfaceAttribute : Attribute
{
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/HideFromJavaAttribute.cs b/src/IKVM.Runtime/Attributes/HideFromJavaAttribute.cs
index e999de0ed6..d9d6e47b62 100644
--- a/src/IKVM.Runtime/Attributes/HideFromJavaAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/HideFromJavaAttribute.cs
@@ -23,10 +23,6 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
diff --git a/src/IKVM.Runtime/Attributes/HideFromJavaFlags.cs b/src/IKVM.Runtime/Attributes/HideFromJavaFlags.cs
index d9e5fabfd4..9101d2ef92 100644
--- a/src/IKVM.Runtime/Attributes/HideFromJavaFlags.cs
+++ b/src/IKVM.Runtime/Attributes/HideFromJavaFlags.cs
@@ -23,10 +23,6 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
diff --git a/src/IKVM.Runtime/Attributes/ImplementsAttribute.cs b/src/IKVM.Runtime/Attributes/ImplementsAttribute.cs
index e83822a2c4..4bd1bb3fec 100644
--- a/src/IKVM.Runtime/Attributes/ImplementsAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/ImplementsAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public sealed class ImplementsAttribute : Attribute
{
+
private string[] interfaces;
// NOTE this is not CLS compliant, so maybe we should have a couple of overloads
@@ -42,12 +40,8 @@ public ImplementsAttribute(string[] interfaces)
this.interfaces = UnicodeUtil.UnescapeInvalidSurrogates(interfaces);
}
- public string[] Interfaces
- {
- get
- {
- return interfaces;
- }
- }
- }
+ public string[] Interfaces => interfaces;
+
+ }
+
}
diff --git a/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs b/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs
index d87c44d9ea..08c36ff3f9 100644
--- a/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/InnerClassAttribute.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
#if IMPORTER || EXPORTER
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Runtime/Attributes/JavaModuleAttribute.cs b/src/IKVM.Runtime/Attributes/JavaModuleAttribute.cs
index d004336a58..ff6ab346d4 100644
--- a/src/IKVM.Runtime/Attributes/JavaModuleAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/JavaModuleAttribute.cs
@@ -23,11 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
diff --git a/src/IKVM.Runtime/Attributes/JavaResourceAttribute.cs b/src/IKVM.Runtime/Attributes/JavaResourceAttribute.cs
index e4e0207513..c4c3d317a4 100644
--- a/src/IKVM.Runtime/Attributes/JavaResourceAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/JavaResourceAttribute.cs
@@ -23,16 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class JavaResourceAttribute : Attribute
{
+
private readonly string javaName;
private readonly string resourceName;
@@ -42,14 +39,10 @@ public JavaResourceAttribute(string javaName, string resourceName)
this.resourceName = resourceName;
}
- public string JavaName
- {
- get { return javaName; }
- }
+ public string JavaName => javaName;
+
+ public string ResourceName => resourceName;
+
+ }
- public string ResourceName
- {
- get { return resourceName; }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs b/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs
index b5355db5eb..2ce05c73c9 100644
--- a/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/LineNumberTableAttribute.cs
@@ -23,15 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
public sealed class LineNumberTableAttribute : Attribute
{
+
private byte[] table;
public LineNumberTableAttribute(ushort lineno)
@@ -249,5 +247,7 @@ public int GetLineNumber(int ilOffset)
}
return line;
}
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/MethodParametersAttribute.cs b/src/IKVM.Runtime/Attributes/MethodParametersAttribute.cs
index 2b513a44b9..c592ecafc4 100644
--- a/src/IKVM.Runtime/Attributes/MethodParametersAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/MethodParametersAttribute.cs
@@ -23,15 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
public sealed class MethodParametersAttribute : Attribute
{
+
private readonly Modifiers[] modifiers;
public MethodParametersAttribute(Modifiers[] modifiers)
@@ -39,14 +37,10 @@ public MethodParametersAttribute(Modifiers[] modifiers)
this.modifiers = modifiers;
}
- public Modifiers[] Modifiers
- {
- get { return modifiers; }
- }
+ public Modifiers[] Modifiers => modifiers;
+
+ public bool IsMalformed => modifiers == null;
+
+ }
- public bool IsMalformed
- {
- get { return modifiers == null; }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/ModifiersAttribute.cs b/src/IKVM.Runtime/Attributes/ModifiersAttribute.cs
index 9460ab3308..10b252ffcc 100644
--- a/src/IKVM.Runtime/Attributes/ModifiersAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/ModifiersAttribute.cs
@@ -23,14 +23,10 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
- [AttributeUsage(AttributeTargets.All)]
+ [AttributeUsage(AttributeTargets.All)]
public sealed class ModifiersAttribute : Attribute
{
diff --git a/src/IKVM.Runtime/Attributes/NameSigAttribute.cs b/src/IKVM.Runtime/Attributes/NameSigAttribute.cs
index 7a995c9ba3..c4aa2b5cbe 100644
--- a/src/IKVM.Runtime/Attributes/NameSigAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/NameSigAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field)]
public sealed class NameSigAttribute : Attribute
{
+
private string name;
private string sig;
@@ -43,20 +41,10 @@ public NameSigAttribute(string name, string sig)
this.sig = UnicodeUtil.UnescapeInvalidSurrogates(sig);
}
- public string Name
- {
- get
- {
- return name;
- }
- }
+ public string Name => name;
+
+ public string Sig => sig;
+
+ }
- public string Sig
- {
- get
- {
- return sig;
- }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/NoPackagePrefixAttribute.cs b/src/IKVM.Runtime/Attributes/NoPackagePrefixAttribute.cs
index 13b6115c4b..d8dccb92fa 100644
--- a/src/IKVM.Runtime/Attributes/NoPackagePrefixAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/NoPackagePrefixAttribute.cs
@@ -23,14 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Assembly)]
public sealed class NoPackagePrefixAttribute : Attribute
{
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/NonNestedInnerClassAttribute.cs b/src/IKVM.Runtime/Attributes/NonNestedInnerClassAttribute.cs
index 1a4b41201a..3094e86e6b 100644
--- a/src/IKVM.Runtime/Attributes/NonNestedInnerClassAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/NonNestedInnerClassAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)]
public sealed class NonNestedInnerClassAttribute : Attribute
{
+
private string innerClassName;
public NonNestedInnerClassAttribute(string innerClassName)
@@ -41,12 +39,8 @@ public NonNestedInnerClassAttribute(string innerClassName)
this.innerClassName = UnicodeUtil.UnescapeInvalidSurrogates(innerClassName);
}
- public string InnerClassName
- {
- get
- {
- return innerClassName;
- }
- }
+ public string InnerClassName => innerClassName;
+
}
+
}
diff --git a/src/IKVM.Runtime/Attributes/NonNestedOuterClassAttribute.cs b/src/IKVM.Runtime/Attributes/NonNestedOuterClassAttribute.cs
index 92cfca60fc..614970a8ed 100644
--- a/src/IKVM.Runtime/Attributes/NonNestedOuterClassAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/NonNestedOuterClassAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public sealed class NonNestedOuterClassAttribute : Attribute
{
+
private string outerClassName;
public NonNestedOuterClassAttribute(string outerClassName)
@@ -41,12 +39,8 @@ public NonNestedOuterClassAttribute(string outerClassName)
this.outerClassName = UnicodeUtil.UnescapeInvalidSurrogates(outerClassName);
}
- public string OuterClassName
- {
- get
- {
- return outerClassName;
- }
- }
- }
+ public string OuterClassName => outerClassName;
+
+ }
+
}
diff --git a/src/IKVM.Runtime/Attributes/PackageListAttribute.cs b/src/IKVM.Runtime/Attributes/PackageListAttribute.cs
index fab144d1d0..f2dcf32f43 100644
--- a/src/IKVM.Runtime/Attributes/PackageListAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/PackageListAttribute.cs
@@ -23,17 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Module, AllowMultiple = true)]
public sealed class PackageListAttribute : Attribute
{
+
internal string jar;
internal string[] packages;
@@ -43,9 +41,8 @@ public PackageListAttribute(string jar, string[] packages)
this.packages = UnicodeUtil.UnescapeInvalidSurrogates(packages);
}
- public string[] GetPackages()
- {
- return packages;
- }
- }
+ public string[] GetPackages() => packages;
+
+ }
+
}
diff --git a/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs b/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs
index 7df7b78b3a..522bb201a5 100644
--- a/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/RemappedClassAttribute.cs
@@ -38,10 +38,12 @@ public sealed class RemappedClassAttribute : Attribute
private Type remappedType;
#if EXPORTER
+
public RemappedClassAttribute(string name, System.Type remappedType)
{
}
+
#endif
public RemappedClassAttribute(string name, Type remappedType)
@@ -50,22 +52,10 @@ public RemappedClassAttribute(string name, Type remappedType)
this.remappedType = remappedType;
}
- public string Name
- {
- get
- {
- return name;
- }
- }
+ public string Name => name;
- public Type RemappedType
- {
- get
- {
- return remappedType;
- }
- }
+ public Type RemappedType => remappedType;
- }
+ }
}
diff --git a/src/IKVM.Runtime/Attributes/RemappedInterfaceMethodAttribute.cs b/src/IKVM.Runtime/Attributes/RemappedInterfaceMethodAttribute.cs
index 322ca38ded..5528b32880 100644
--- a/src/IKVM.Runtime/Attributes/RemappedInterfaceMethodAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/RemappedInterfaceMethodAttribute.cs
@@ -23,15 +23,13 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Interface)]
public sealed class RemappedInterfaceMethodAttribute : Attribute
{
+
private string name;
private string mappedTo;
private string[] throws;
@@ -43,28 +41,12 @@ public RemappedInterfaceMethodAttribute(string name, string mappedTo, string[] t
this.throws = throws;
}
- public string Name
- {
- get
- {
- return name;
- }
- }
+ public string Name => name;
- public string MappedTo
- {
- get
- {
- return mappedTo;
- }
- }
+ public string MappedTo => mappedTo;
+
+ public string[] Throws => throws;
+
+ }
- public string[] Throws
- {
- get
- {
- return throws;
- }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs b/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs
index ea7802a026..da10979780 100644
--- a/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/RemappedTypeAttribute.cs
@@ -29,28 +29,29 @@ Jeroen Frijters
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
- public sealed class RemappedTypeAttribute : Attribute
- {
- private Type type;
+ public sealed class RemappedTypeAttribute : Attribute
+ {
+
+ private Type type;
#if EXPORTER
+
public RemappedTypeAttribute(System.Type type)
{
+
}
+
#endif
- public RemappedTypeAttribute(Type type)
- {
- this.type = type;
- }
+ public RemappedTypeAttribute(Type type)
+ {
+ this.type = type;
+ }
+
+ public Type Type => type;
+
+ }
- public Type Type
- {
- get
- {
- return type;
- }
- }
- }
}
diff --git a/src/IKVM.Runtime/Attributes/RuntimeVisibleTypeAnnotationsAttribute.cs b/src/IKVM.Runtime/Attributes/RuntimeVisibleTypeAnnotationsAttribute.cs
index ba32d02572..fb0ae54312 100644
--- a/src/IKVM.Runtime/Attributes/RuntimeVisibleTypeAnnotationsAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/RuntimeVisibleTypeAnnotationsAttribute.cs
@@ -23,10 +23,6 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using Type = IKVM.Reflection.Type;
-#endif
-
namespace IKVM.Attributes
{
diff --git a/src/IKVM.Runtime/Attributes/SignatureAttribute.cs b/src/IKVM.Runtime/Attributes/SignatureAttribute.cs
index d4bb76e89d..7e70976523 100644
--- a/src/IKVM.Runtime/Attributes/SignatureAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/SignatureAttribute.cs
@@ -23,13 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Field)]
public sealed class SignatureAttribute : Attribute
{
+
private string signature;
public SignatureAttribute(string signature)
@@ -37,12 +39,8 @@ public SignatureAttribute(string signature)
this.signature = UnicodeUtil.UnescapeInvalidSurrogates(signature);
}
- public string Signature
- {
- get
- {
- return signature;
- }
- }
- }
+ public string Signature => signature;
+
+ }
+
}
diff --git a/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs b/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs
index d77f4efd81..94a481223b 100644
--- a/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs
+++ b/src/IKVM.Runtime/Attributes/ThrowsAttribute.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
#if IMPORTER || EXPORTER
using Type = IKVM.Reflection.Type;
@@ -31,9 +31,11 @@ Jeroen Frijters
namespace IKVM.Attributes
{
+
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method)]
public sealed class ThrowsAttribute : Attribute
{
+
internal string[] classes;
internal Type[] types;
@@ -53,14 +55,10 @@ public ThrowsAttribute(params Type[] types)
this.types = types;
}
- // dotted Java class names (e.g. java.lang.Throwable)
- [Obsolete]
- public string[] Classes
- {
- get
- {
- return classes;
- }
- }
- }
+ // dotted Java class names (e.g. java.lang.Throwable)
+ [Obsolete]
+ public string[] Classes => classes;
+
+ }
+
}
diff --git a/src/IKVM.Runtime/BigEndianBinaryReader.cs b/src/IKVM.Runtime/BigEndianBinaryReader.cs
index 587c0b0770..826c4e215c 100644
--- a/src/IKVM.Runtime/BigEndianBinaryReader.cs
+++ b/src/IKVM.Runtime/BigEndianBinaryReader.cs
@@ -24,215 +24,220 @@ Jeroen Frijters
using System;
using System.Text;
-sealed class BigEndianBinaryReader
+namespace IKVM.Runtime
{
- readonly ReadOnlyMemory buf;
+ sealed class BigEndianBinaryReader
+ {
- int pos;
+ readonly ReadOnlyMemory buf;
- ///
- /// Initializes a new instance.
- ///
- ///
- ///
- internal BigEndianBinaryReader(ReadOnlyMemory buf)
- {
- this.buf = buf;
- this.pos = 0;
- }
+ int pos;
- internal BigEndianBinaryReader Section(uint length)
- {
- var br = new BigEndianBinaryReader(buf.Slice(pos, checked((int)length)));
- Skip(length);
- return br;
- }
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ internal BigEndianBinaryReader(ReadOnlyMemory buf)
+ {
+ this.buf = buf;
+ this.pos = 0;
+ }
- internal bool IsAtEnd => pos == buf.Length;
+ internal BigEndianBinaryReader Section(uint length)
+ {
+ var br = new BigEndianBinaryReader(buf.Slice(pos, checked((int)length)));
+ Skip(length);
+ return br;
+ }
- internal int Position => pos;
+ internal bool IsAtEnd => pos == buf.Length;
- internal void Skip(uint count)
- {
- if (buf.Length - pos < count)
- throw new ClassFormatError("Truncated class file");
+ internal int Position => pos;
- checked
+ internal void Skip(uint count)
{
- pos += (int)count;
- }
- }
+ if (buf.Length - pos < count)
+ throw new ClassFormatError("Truncated class file");
- internal byte ReadByte()
- {
- if (pos == buf.Length)
- throw new ClassFormatError("Truncated class file");
+ checked
+ {
+ pos += (int)count;
+ }
+ }
- return buf.Span[pos++];
- }
+ internal byte ReadByte()
+ {
+ if (pos == buf.Length)
+ throw new ClassFormatError("Truncated class file");
- internal sbyte ReadSByte()
- {
- if (pos == buf.Length)
- throw new ClassFormatError("Truncated class file");
+ return buf.Span[pos++];
+ }
- return (sbyte)buf.Span[pos++];
- }
+ internal sbyte ReadSByte()
+ {
+ if (pos == buf.Length)
+ throw new ClassFormatError("Truncated class file");
- internal double ReadDouble()
- {
- return BitConverter.Int64BitsToDouble(ReadInt64());
- }
+ return (sbyte)buf.Span[pos++];
+ }
- internal short ReadInt16()
- {
- if (buf.Length - pos < 2)
- throw new ClassFormatError("Truncated class file");
+ internal double ReadDouble()
+ {
+ return BitConverter.Int64BitsToDouble(ReadInt64());
+ }
- var s = (short)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
- pos += 2;
+ internal short ReadInt16()
+ {
+ if (buf.Length - pos < 2)
+ throw new ClassFormatError("Truncated class file");
- return s;
- }
+ var s = (short)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
+ pos += 2;
- internal int ReadInt32()
- {
- if (buf.Length - pos < 4)
- throw new ClassFormatError("Truncated class file");
+ return s;
+ }
- var i = (int)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
- pos += 4;
- return i;
- }
+ internal int ReadInt32()
+ {
+ if (buf.Length - pos < 4)
+ throw new ClassFormatError("Truncated class file");
- internal long ReadInt64()
- {
- if (buf.Length - pos < 8)
- throw new ClassFormatError("Truncated class file");
-
- var i1 = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
- var i2 = (uint)((buf.Span[pos + 4] << 24) + (buf.Span[pos + 5] << 16) + (buf.Span[pos + 6] << 8) + buf.Span[pos + 7]);
- var l = (((long)i1) << 32) + i2;
- pos += 8;
- return l;
- }
+ var i = (int)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
+ pos += 4;
+ return i;
+ }
- internal float ReadSingle()
- {
- return BitConverter.ToSingle(BitConverter.GetBytes(ReadInt32()), 0);
- }
+ internal long ReadInt64()
+ {
+ if (buf.Length - pos < 8)
+ throw new ClassFormatError("Truncated class file");
+
+ var i1 = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
+ var i2 = (uint)((buf.Span[pos + 4] << 24) + (buf.Span[pos + 5] << 16) + (buf.Span[pos + 6] << 8) + buf.Span[pos + 7]);
+ var l = (((long)i1) << 32) + i2;
+ pos += 8;
+ return l;
+ }
- internal unsafe string ReadString(string classFile, int majorVersion)
- {
- int len = ReadUInt16();
- if (buf.Length - pos < len)
- throw new ClassFormatError("{0} (Truncated class file)", classFile);
+ internal float ReadSingle()
+ {
+ return BitConverter.ToSingle(BitConverter.GetBytes(ReadInt32()), 0);
+ }
- // special code path for ASCII strings (which occur *very* frequently)
- for (int j = 0; j < len; j++)
+ internal unsafe string ReadString(string classFile, int majorVersion)
{
- if (buf.Span[pos + j] == 0 || buf.Span[pos + j] >= 128)
+ int len = ReadUInt16();
+ if (buf.Length - pos < len)
+ throw new ClassFormatError("{0} (Truncated class file)", classFile);
+
+ // special code path for ASCII strings (which occur *very* frequently)
+ for (int j = 0; j < len; j++)
{
- // NOTE we *cannot* use System.Text.UTF8Encoding, because this is *not* compatible
- // (esp. for embedded nulls)
- char[] ch = new char[len];
- int l = 0;
- for (int i = 0; i < len; i++)
+ if (buf.Span[pos + j] == 0 || buf.Span[pos + j] >= 128)
{
- int c = buf.Span[pos + i];
- int char2, char3;
- switch (c >> 4)
+ // NOTE we *cannot* use System.Text.UTF8Encoding, because this is *not* compatible
+ // (esp. for embedded nulls)
+ char[] ch = new char[len];
+ int l = 0;
+ for (int i = 0; i < len; i++)
{
- case 0:
- if (c == 0)
- {
- goto default;
- }
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- // 0xxxxxxx
- break;
- case 12:
- case 13:
- // 110x xxxx 10xx xxxx
- char2 = buf.Span[pos + ++i];
- if ((char2 & 0xc0) != 0x80 || i >= len)
- {
- goto default;
- }
- c = (((c & 0x1F) << 6) | (char2 & 0x3F));
- if (c < 0x80 && c != 0 && majorVersion >= 48)
- {
- goto default;
- }
- break;
- case 14:
- // 1110 xxxx 10xx xxxx 10xx xxxx
- char2 = buf.Span[pos + ++i];
- char3 = buf.Span[pos + ++i];
- if ((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80 || i >= len)
- {
- goto default;
- }
- c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
- if (c < 0x800 && majorVersion >= 48)
- {
- goto default;
- }
- break;
- default:
- throw new ClassFormatError("Illegal UTF8 string in constant pool in class file {0}", classFile ?? "");
+ int c = buf.Span[pos + i];
+ int char2, char3;
+ switch (c >> 4)
+ {
+ case 0:
+ if (c == 0)
+ {
+ goto default;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 0xxxxxxx
+ break;
+ case 12:
+ case 13:
+ // 110x xxxx 10xx xxxx
+ char2 = buf.Span[pos + ++i];
+ if ((char2 & 0xc0) != 0x80 || i >= len)
+ {
+ goto default;
+ }
+ c = (((c & 0x1F) << 6) | (char2 & 0x3F));
+ if (c < 0x80 && c != 0 && majorVersion >= 48)
+ {
+ goto default;
+ }
+ break;
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ char2 = buf.Span[pos + ++i];
+ char3 = buf.Span[pos + ++i];
+ if ((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80 || i >= len)
+ {
+ goto default;
+ }
+ c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
+ if (c < 0x800 && majorVersion >= 48)
+ {
+ goto default;
+ }
+ break;
+ default:
+ throw new ClassFormatError("Illegal UTF8 string in constant pool in class file {0}", classFile ?? "");
+ }
+ ch[l++] = (char)c;
}
- ch[l++] = (char)c;
+ pos += len;
+ return new string(ch, 0, l);
}
- pos += len;
- return new string(ch, 0, l);
}
- }
#if NETFRAMEWORK
- string s;
- fixed (byte* p = buf.Slice(pos, len).Span)
- s = Encoding.ASCII.GetString(p, buf.Length);
+ string s;
+ fixed (byte* p = buf.Slice(pos, len).Span)
+ s = Encoding.ASCII.GetString(p, buf.Length);
#else
var s = Encoding.ASCII.GetString(buf.Slice(pos, len).Span);
#endif
- pos += len;
- return s;
- }
+ pos += len;
+ return s;
+ }
- internal ushort ReadUInt16()
- {
- if (buf.Length - pos < 2)
- throw new ClassFormatError("Truncated class file");
+ internal ushort ReadUInt16()
+ {
+ if (buf.Length - pos < 2)
+ throw new ClassFormatError("Truncated class file");
- var s = (ushort)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
- pos += 2;
- return s;
- }
+ var s = (ushort)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
+ pos += 2;
+ return s;
+ }
- internal uint ReadUInt32()
- {
- if (buf.Length - pos < 4)
- throw new ClassFormatError("Truncated class file");
+ internal uint ReadUInt32()
+ {
+ if (buf.Length - pos < 4)
+ throw new ClassFormatError("Truncated class file");
- uint i = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
- pos += 4;
- return i;
- }
+ uint i = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
+ pos += 4;
+ return i;
+ }
+
+ internal byte[] ToArray()
+ {
+ var res = new byte[buf.Length - pos];
+ buf.Slice(pos, res.Length).CopyTo(res);
+ return res;
+ }
- internal byte[] ToArray()
- {
- var res = new byte[buf.Length - pos];
- buf.Slice(pos, res.Length).CopyTo(res);
- return res;
}
}
diff --git a/src/IKVM.Runtime/Boxer.cs b/src/IKVM.Runtime/Boxer.cs
index 932756b103..3439dfb7bb 100644
--- a/src/IKVM.Runtime/Boxer.cs
+++ b/src/IKVM.Runtime/Boxer.cs
@@ -23,8 +23,9 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class Boxer
{
diff --git a/src/IKVM.Runtime/ByteCode.cs b/src/IKVM.Runtime/ByteCode.cs
new file mode 100644
index 0000000000..5670aba9a7
--- /dev/null
+++ b/src/IKVM.Runtime/ByteCode.cs
@@ -0,0 +1,236 @@
+/*
+ Copyright (C) 2002, 2004, 2005, 2006 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+namespace IKVM.Runtime
+{
+
+ enum ByteCode : byte
+ {
+
+ __nop = 0,
+ __aconst_null = 1,
+ __iconst_m1 = 2,
+ __iconst_0 = 3,
+ __iconst_1 = 4,
+ __iconst_2 = 5,
+ __iconst_3 = 6,
+ __iconst_4 = 7,
+ __iconst_5 = 8,
+ __lconst_0 = 9,
+ __lconst_1 = 10,
+ __fconst_0 = 11,
+ __fconst_1 = 12,
+ __fconst_2 = 13,
+ __dconst_0 = 14,
+ __dconst_1 = 15,
+ __bipush = 16,
+ __sipush = 17,
+ __ldc = 18,
+ __ldc_w = 19,
+ __ldc2_w = 20,
+ __iload = 21,
+ __lload = 22,
+ __fload = 23,
+ __dload = 24,
+ __aload = 25,
+ __iload_0 = 26,
+ __iload_1 = 27,
+ __iload_2 = 28,
+ __iload_3 = 29,
+ __lload_0 = 30,
+ __lload_1 = 31,
+ __lload_2 = 32,
+ __lload_3 = 33,
+ __fload_0 = 34,
+ __fload_1 = 35,
+ __fload_2 = 36,
+ __fload_3 = 37,
+ __dload_0 = 38,
+ __dload_1 = 39,
+ __dload_2 = 40,
+ __dload_3 = 41,
+ __aload_0 = 42,
+ __aload_1 = 43,
+ __aload_2 = 44,
+ __aload_3 = 45,
+ __iaload = 46,
+ __laload = 47,
+ __faload = 48,
+ __daload = 49,
+ __aaload = 50,
+ __baload = 51,
+ __caload = 52,
+ __saload = 53,
+ __istore = 54,
+ __lstore = 55,
+ __fstore = 56,
+ __dstore = 57,
+ __astore = 58,
+ __istore_0 = 59,
+ __istore_1 = 60,
+ __istore_2 = 61,
+ __istore_3 = 62,
+ __lstore_0 = 63,
+ __lstore_1 = 64,
+ __lstore_2 = 65,
+ __lstore_3 = 66,
+ __fstore_0 = 67,
+ __fstore_1 = 68,
+ __fstore_2 = 69,
+ __fstore_3 = 70,
+ __dstore_0 = 71,
+ __dstore_1 = 72,
+ __dstore_2 = 73,
+ __dstore_3 = 74,
+ __astore_0 = 75,
+ __astore_1 = 76,
+ __astore_2 = 77,
+ __astore_3 = 78,
+ __iastore = 79,
+ __lastore = 80,
+ __fastore = 81,
+ __dastore = 82,
+ __aastore = 83,
+ __bastore = 84,
+ __castore = 85,
+ __sastore = 86,
+ __pop = 87,
+ __pop2 = 88,
+ __dup = 89,
+ __dup_x1 = 90,
+ __dup_x2 = 91,
+ __dup2 = 92,
+ __dup2_x1 = 93,
+ __dup2_x2 = 94,
+ __swap = 95,
+ __iadd = 96,
+ __ladd = 97,
+ __fadd = 98,
+ __dadd = 99,
+ __isub = 100,
+ __lsub = 101,
+ __fsub = 102,
+ __dsub = 103,
+ __imul = 104,
+ __lmul = 105,
+ __fmul = 106,
+ __dmul = 107,
+ __idiv = 108,
+ __ldiv = 109,
+ __fdiv = 110,
+ __ddiv = 111,
+ __irem = 112,
+ __lrem = 113,
+ __frem = 114,
+ __drem = 115,
+ __ineg = 116,
+ __lneg = 117,
+ __fneg = 118,
+ __dneg = 119,
+ __ishl = 120,
+ __lshl = 121,
+ __ishr = 122,
+ __lshr = 123,
+ __iushr = 124,
+ __lushr = 125,
+ __iand = 126,
+ __land = 127,
+ __ior = 128,
+ __lor = 129,
+ __ixor = 130,
+ __lxor = 131,
+ __iinc = 132,
+ __i2l = 133,
+ __i2f = 134,
+ __i2d = 135,
+ __l2i = 136,
+ __l2f = 137,
+ __l2d = 138,
+ __f2i = 139,
+ __f2l = 140,
+ __f2d = 141,
+ __d2i = 142,
+ __d2l = 143,
+ __d2f = 144,
+ __i2b = 145,
+ __i2c = 146,
+ __i2s = 147,
+ __lcmp = 148,
+ __fcmpl = 149,
+ __fcmpg = 150,
+ __dcmpl = 151,
+ __dcmpg = 152,
+ __ifeq = 153,
+ __ifne = 154,
+ __iflt = 155,
+ __ifge = 156,
+ __ifgt = 157,
+ __ifle = 158,
+ __if_icmpeq = 159,
+ __if_icmpne = 160,
+ __if_icmplt = 161,
+ __if_icmpge = 162,
+ __if_icmpgt = 163,
+ __if_icmple = 164,
+ __if_acmpeq = 165,
+ __if_acmpne = 166,
+ __goto = 167,
+ __jsr = 168,
+ __ret = 169,
+ __tableswitch = 170,
+ __lookupswitch = 171,
+ __ireturn = 172,
+ __lreturn = 173,
+ __freturn = 174,
+ __dreturn = 175,
+ __areturn = 176,
+ __return = 177,
+ __getstatic = 178,
+ __putstatic = 179,
+ __getfield = 180,
+ __putfield = 181,
+ __invokevirtual = 182,
+ __invokespecial = 183,
+ __invokestatic = 184,
+ __invokeinterface = 185,
+ __invokedynamic = 186,
+ __new = 187,
+ __newarray = 188,
+ __anewarray = 189,
+ __arraylength = 190,
+ __athrow = 191,
+ __checkcast = 192,
+ __instanceof = 193,
+ __monitorenter = 194,
+ __monitorexit = 195,
+ __wide = 196,
+ __multianewarray = 197,
+ __ifnull = 198,
+ __ifnonnull = 199,
+ __goto_w = 200,
+ __jsr_w = 201
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/ByteCodeFlags.cs b/src/IKVM.Runtime/ByteCodeFlags.cs
index 629bdac36e..618565e945 100644
--- a/src/IKVM.Runtime/ByteCodeFlags.cs
+++ b/src/IKVM.Runtime/ByteCodeFlags.cs
@@ -23,12 +23,17 @@ Jeroen Frijters
*/
using System;
-[Flags]
-enum ByteCodeFlags : byte
+namespace IKVM.Runtime
{
- None = 0,
- FixedArg = 1,
- CannotThrow = 2
+ [Flags]
+ enum ByteCodeFlags : byte
+ {
+
+ None = 0,
+ FixedArg = 1,
+ CannotThrow = 2
+
+ }
}
diff --git a/src/IKVM.Runtime/ByteCodeFlowControl.cs b/src/IKVM.Runtime/ByteCodeFlowControl.cs
index 11252d7b9a..2a5eace55d 100644
--- a/src/IKVM.Runtime/ByteCodeFlowControl.cs
+++ b/src/IKVM.Runtime/ByteCodeFlowControl.cs
@@ -22,12 +22,17 @@ Jeroen Frijters
*/
-enum ByteCodeFlowControl : byte
+namespace IKVM.Runtime
{
- Next,
- Branch,
- CondBranch,
- Return,
- Throw,
- Switch,
+
+ enum ByteCodeFlowControl : byte
+ {
+ Next,
+ Branch,
+ CondBranch,
+ Return,
+ Throw,
+ Switch,
+ }
+
}
diff --git a/src/IKVM.Runtime/ByteCodeHelper.cs b/src/IKVM.Runtime/ByteCodeHelper.cs
index 95f99ff5a7..70af395a14 100644
--- a/src/IKVM.Runtime/ByteCodeHelper.cs
+++ b/src/IKVM.Runtime/ByteCodeHelper.cs
@@ -29,7 +29,6 @@ Jeroen Frijters
using IKVM.Attributes;
using IKVM.ByteCode;
-using IKVM.Internal;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
diff --git a/src/IKVM.Runtime/ByteCodeHelperMethods.cs b/src/IKVM.Runtime/ByteCodeHelperMethods.cs
index 83ea5cf229..e2468faa89 100644
--- a/src/IKVM.Runtime/ByteCodeHelperMethods.cs
+++ b/src/IKVM.Runtime/ByteCodeHelperMethods.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
diff --git a/src/IKVM.Runtime/ByteCodeMetaData.cs b/src/IKVM.Runtime/ByteCodeMetaData.cs
new file mode 100644
index 0000000000..4705c03510
--- /dev/null
+++ b/src/IKVM.Runtime/ByteCodeMetaData.cs
@@ -0,0 +1,399 @@
+/*
+ Copyright (C) 2002, 2004, 2005, 2006 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+namespace IKVM.Runtime
+{
+
+ struct ByteCodeMetaData
+ {
+
+ private static ByteCodeMetaData[] data = new ByteCodeMetaData[256];
+ private ByteCodeMode reg;
+ private ByteCodeModeWide wide;
+ private NormalizedByteCode normbc;
+ private ByteCodeFlags flags;
+ private int arg;
+
+ private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
+ {
+ this.reg = reg;
+ this.wide = wide;
+ this.normbc = (NormalizedByteCode)bc;
+ this.arg = 0;
+ this.flags = ByteCodeFlags.None;
+ if (cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
+ data[(int)bc] = this;
+ }
+
+ private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
+ {
+ this.reg = reg;
+ this.wide = wide;
+ this.normbc = normbc;
+ this.arg = 0;
+ this.flags = ByteCodeFlags.None;
+ if (cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
+ data[(int)bc] = this;
+ }
+
+ private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
+ {
+ this.reg = reg;
+ this.wide = wide;
+ this.normbc = normbc;
+ this.arg = arg;
+ this.flags = ByteCodeFlags.FixedArg;
+ if (cannotThrow)
+ {
+ this.flags |= ByteCodeFlags.CannotThrow;
+ }
+ data[(int)bc] = this;
+ }
+
+ internal static NormalizedByteCode GetNormalizedByteCode(ByteCode bc)
+ {
+ return data[(int)bc].normbc;
+ }
+
+ internal static int GetArg(ByteCode bc, int arg)
+ {
+ if ((data[(int)bc].flags & ByteCodeFlags.FixedArg) != 0)
+ {
+ return data[(int)bc].arg;
+ }
+ return arg;
+ }
+
+ internal static ByteCodeMode GetMode(ByteCode bc)
+ {
+ return data[(int)bc].reg;
+ }
+
+ internal static ByteCodeModeWide GetWideMode(ByteCode bc)
+ {
+ return data[(int)bc].wide;
+ }
+
+ internal static ByteCodeFlowControl GetFlowControl(NormalizedByteCode bc)
+ {
+ switch (bc)
+ {
+ case NormalizedByteCode.__tableswitch:
+ case NormalizedByteCode.__lookupswitch:
+ return ByteCodeFlowControl.Switch;
+
+ case NormalizedByteCode.__goto:
+ case NormalizedByteCode.__goto_finally:
+ return ByteCodeFlowControl.Branch;
+
+ case NormalizedByteCode.__ifeq:
+ case NormalizedByteCode.__ifne:
+ case NormalizedByteCode.__iflt:
+ case NormalizedByteCode.__ifge:
+ case NormalizedByteCode.__ifgt:
+ case NormalizedByteCode.__ifle:
+ case NormalizedByteCode.__if_icmpeq:
+ case NormalizedByteCode.__if_icmpne:
+ case NormalizedByteCode.__if_icmplt:
+ case NormalizedByteCode.__if_icmpge:
+ case NormalizedByteCode.__if_icmpgt:
+ case NormalizedByteCode.__if_icmple:
+ case NormalizedByteCode.__if_acmpeq:
+ case NormalizedByteCode.__if_acmpne:
+ case NormalizedByteCode.__ifnull:
+ case NormalizedByteCode.__ifnonnull:
+ return ByteCodeFlowControl.CondBranch;
+
+ case NormalizedByteCode.__ireturn:
+ case NormalizedByteCode.__lreturn:
+ case NormalizedByteCode.__freturn:
+ case NormalizedByteCode.__dreturn:
+ case NormalizedByteCode.__areturn:
+ case NormalizedByteCode.__return:
+ return ByteCodeFlowControl.Return;
+
+ case NormalizedByteCode.__athrow:
+ case NormalizedByteCode.__athrow_no_unmap:
+ case NormalizedByteCode.__static_error:
+ return ByteCodeFlowControl.Throw;
+
+ default:
+ return ByteCodeFlowControl.Next;
+ }
+ }
+
+ internal static bool CanThrowException(NormalizedByteCode bc)
+ {
+ switch (bc)
+ {
+ case NormalizedByteCode.__dynamic_invokeinterface:
+ case NormalizedByteCode.__dynamic_invokestatic:
+ case NormalizedByteCode.__dynamic_invokevirtual:
+ case NormalizedByteCode.__dynamic_getstatic:
+ case NormalizedByteCode.__dynamic_putstatic:
+ case NormalizedByteCode.__dynamic_getfield:
+ case NormalizedByteCode.__dynamic_putfield:
+ case NormalizedByteCode.__clone_array:
+ case NormalizedByteCode.__static_error:
+ case NormalizedByteCode.__methodhandle_invoke:
+ case NormalizedByteCode.__methodhandle_link:
+ return true;
+ case NormalizedByteCode.__iconst:
+ case NormalizedByteCode.__ldc_nothrow:
+ return false;
+ default:
+ return (data[(int)bc].flags & ByteCodeFlags.CannotThrow) == 0;
+ }
+ }
+
+ internal static bool IsBranch(NormalizedByteCode bc)
+ {
+ switch (data[(int)bc].reg)
+ {
+ case ByteCodeMode.Branch_2:
+ case ByteCodeMode.Branch_4:
+ case ByteCodeMode.Lookupswitch:
+ case ByteCodeMode.Tableswitch:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ static ByteCodeMetaData()
+ {
+ new ByteCodeMetaData(ByteCode.__nop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aconst_null, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_m1, NormalizedByteCode.__iconst, -1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_0, NormalizedByteCode.__iconst, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_1, NormalizedByteCode.__iconst, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_2, NormalizedByteCode.__iconst, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_3, NormalizedByteCode.__iconst, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_4, NormalizedByteCode.__iconst, 4, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iconst_5, NormalizedByteCode.__iconst, 5, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fconst_2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__bipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__sipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ldc, ByteCodeMode.Constant_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__ldc_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__ldc2_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__iload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__lload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__fload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__dload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__aload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__iload_0, NormalizedByteCode.__iload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_1, NormalizedByteCode.__iload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_2, NormalizedByteCode.__iload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iload_3, NormalizedByteCode.__iload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_0, NormalizedByteCode.__lload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_1, NormalizedByteCode.__lload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_2, NormalizedByteCode.__lload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lload_3, NormalizedByteCode.__lload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_0, NormalizedByteCode.__fload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_1, NormalizedByteCode.__fload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_2, NormalizedByteCode.__fload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fload_3, NormalizedByteCode.__fload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_0, NormalizedByteCode.__dload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_1, NormalizedByteCode.__dload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_2, NormalizedByteCode.__dload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dload_3, NormalizedByteCode.__dload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_0, NormalizedByteCode.__aload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_1, NormalizedByteCode.__aload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_2, NormalizedByteCode.__aload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__aload_3, NormalizedByteCode.__aload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__laload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__faload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__daload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__aaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__baload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__caload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__saload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__istore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__lstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__fstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__dstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__astore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__istore_0, NormalizedByteCode.__istore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_1, NormalizedByteCode.__istore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_2, NormalizedByteCode.__istore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__istore_3, NormalizedByteCode.__istore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_0, NormalizedByteCode.__lstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_1, NormalizedByteCode.__lstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_2, NormalizedByteCode.__lstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lstore_3, NormalizedByteCode.__lstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_0, NormalizedByteCode.__fstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_1, NormalizedByteCode.__fstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_2, NormalizedByteCode.__fstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fstore_3, NormalizedByteCode.__fstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_0, NormalizedByteCode.__dstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_1, NormalizedByteCode.__dstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_2, NormalizedByteCode.__dstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dstore_3, NormalizedByteCode.__dstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_0, NormalizedByteCode.__astore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_1, NormalizedByteCode.__astore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_2, NormalizedByteCode.__astore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__astore_3, NormalizedByteCode.__astore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__lastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__fastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__dastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__aastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__bastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__castore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__sastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__pop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__pop2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dup2_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__swap, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ladd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__isub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__imul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__idiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__ldiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__fdiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ddiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__irem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__lrem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__frem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__drem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ineg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ishl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lshl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ishr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lshr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iand, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__land, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ior, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ixor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lxor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iinc, ByteCodeMode.Local_1_Immediate_1, ByteCodeModeWide.Local_2_Immediate_2, true);
+ new ByteCodeMetaData(ByteCode.__i2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__l2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__f2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__d2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2b, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2c, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__i2s, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lcmp, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__fcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__iflt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifle, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmplt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmpgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_icmple, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_acmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__if_acmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__goto, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__jsr, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ret, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
+ new ByteCodeMetaData(ByteCode.__tableswitch, ByteCodeMode.Tableswitch, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lookupswitch, ByteCodeMode.Lookupswitch, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ireturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__lreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__freturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__dreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__areturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__return, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__getstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__putstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__getfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__putfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokevirtual, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokespecial, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokestatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokeinterface, ByteCodeMode.Constant_2_1_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__invokedynamic, ByteCodeMode.Constant_2_1_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__new, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__newarray, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__anewarray, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__arraylength, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__athrow, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__checkcast, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__instanceof, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__monitorenter, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__monitorexit, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__wide, NormalizedByteCode.__nop, ByteCodeMode.WidePrefix, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__multianewarray, ByteCodeMode.Constant_2_Immediate_1, ByteCodeModeWide.Unused, false);
+ new ByteCodeMetaData(ByteCode.__ifnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__ifnonnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__goto_w, NormalizedByteCode.__goto, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
+ new ByteCodeMetaData(ByteCode.__jsr_w, NormalizedByteCode.__jsr, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
+
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/ClassFile/ByteCodeMode.cs b/src/IKVM.Runtime/ByteCodeMode.cs
similarity index 77%
rename from src/IKVM.Runtime/ClassFile/ByteCodeMode.cs
rename to src/IKVM.Runtime/ByteCodeMode.cs
index 3cb75daba8..98e989e9b8 100644
--- a/src/IKVM.Runtime/ClassFile/ByteCodeMode.cs
+++ b/src/IKVM.Runtime/ByteCodeMode.cs
@@ -22,21 +22,28 @@ Jeroen Frijters
*/
-enum ByteCodeMode : byte
+namespace IKVM.Runtime
{
- Unused,
- Simple,
- Constant_1,
- Constant_2,
- Branch_2,
- Local_1,
- Constant_2_1_1,
- Immediate_1,
- Immediate_2,
- Local_1_Immediate_1,
- Tableswitch,
- Lookupswitch,
- Constant_2_Immediate_1,
- Branch_4,
- WidePrefix
-}
+
+ enum ByteCodeMode : byte
+ {
+
+ Unused,
+ Simple,
+ Constant_1,
+ Constant_2,
+ Branch_2,
+ Local_1,
+ Constant_2_1_1,
+ Immediate_1,
+ Immediate_2,
+ Local_1_Immediate_1,
+ Tableswitch,
+ Lookupswitch,
+ Constant_2_Immediate_1,
+ Branch_4,
+ WidePrefix
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.Runtime/ByteCodeModeWide.cs b/src/IKVM.Runtime/ByteCodeModeWide.cs
index e6a309fc8b..4fb5b52de2 100644
--- a/src/IKVM.Runtime/ByteCodeModeWide.cs
+++ b/src/IKVM.Runtime/ByteCodeModeWide.cs
@@ -22,9 +22,14 @@ Jeroen Frijters
*/
-enum ByteCodeModeWide : byte
+namespace IKVM.Runtime
{
- Unused,
- Local_2,
- Local_2_Immediate_2
+
+ enum ByteCodeModeWide : byte
+ {
+ Unused,
+ Local_2,
+ Local_2_Immediate_2
+ }
+
}
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.BootstrapMethod.cs b/src/IKVM.Runtime/ClassFile.BootstrapMethod.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.BootstrapMethod.cs
rename to src/IKVM.Runtime/ClassFile.BootstrapMethod.cs
index cc76bb6d7c..9820107791 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.BootstrapMethod.cs
+++ b/src/IKVM.Runtime/ClassFile.BootstrapMethod.cs
@@ -22,13 +22,14 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
{
internal struct BootstrapMethod
{
+
private ushort bsm_index;
private ushort[] args;
@@ -52,7 +53,9 @@ internal int GetArgument(int index)
{
return args[index];
}
+
}
+
}
}
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Constant.cs b/src/IKVM.Runtime/ClassFile.Constant.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Constant.cs
rename to src/IKVM.Runtime/ClassFile.Constant.cs
index dee3c30377..24b31f28eb 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Constant.cs
+++ b/src/IKVM.Runtime/ClassFile.Constant.cs
@@ -22,11 +22,12 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
{
+
internal enum Constant
{
Utf8 = 1,
@@ -44,6 +45,7 @@ internal enum Constant
MethodType = 16,
InvokeDynamic = 18,
}
+
}
}
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItem.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItem.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItem.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItem.cs
index d63c7e087a..8506018232 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItem.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItem.cs
@@ -23,19 +23,23 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
{
+
internal abstract class ConstantPoolItem
{
+
internal virtual void Resolve(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions options)
{
+
}
internal virtual void Link(TypeWrapper thisType, LoadMode mode)
{
+
}
internal virtual ConstantType GetConstantType()
@@ -45,6 +49,7 @@ internal virtual ConstantType GetConstantType()
internal virtual void MarkLinkRequired()
{
+
}
// this is used for sun.reflect.ConstantPool
@@ -53,7 +58,9 @@ internal virtual object GetRuntimeValue()
{
return null;
}
+
}
+
}
}
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemClass.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemClass.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs
index 0a825a685a..ea5e4e7c3f 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemClass.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemDouble.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemDouble.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemDouble.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemDouble.cs
index c7d67c49b9..ab1420eaa5 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemDouble.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemDouble.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFMI.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFMI.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFMI.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemFMI.cs
index 2d5d5811f1..3842596b8e 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFMI.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFMI.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFieldref.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFieldref.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs
index 0063137d53..04917d5f94 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFieldref.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFloat.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFloat.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFloat.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemFloat.cs
index 04e882106a..1bfd77bf01 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemFloat.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFloat.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInteger.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInteger.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInteger.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemInteger.cs
index e156ce7f02..2ba0f74924 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInteger.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInteger.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInterfaceMethodref.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInterfaceMethodref.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInterfaceMethodref.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemInterfaceMethodref.cs
index a693495349..4828405534 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInterfaceMethodref.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInterfaceMethodref.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInvokeDynamic.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInvokeDynamic.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs
index b108241312..439a55c005 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemInvokeDynamic.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLiveObject.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemLiveObject.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLiveObject.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemLiveObject.cs
index 9289d14bed..48b5a547a6 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLiveObject.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemLiveObject.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLong.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemLong.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLong.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemLong.cs
index 13f2bf3ce0..a5f1517416 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemLong.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemLong.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMI.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMI.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs
index 86dea52bd5..16b6f6a57b 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMI.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodHandle.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodHandle.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodHandle.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodHandle.cs
index 37b4f67c34..6c206bc2bf 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodHandle.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodHandle.cs
@@ -27,7 +27,7 @@ Jeroen Frijters
using IKVM.ByteCode;
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodType.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodType.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs
index a280438258..333b80e90d 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodType.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodref.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodref.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodref.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodref.cs
index adf6ed1767..cb499501e9 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemMethodref.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodref.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
using IKVM.Runtime;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemNameAndType.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemNameAndType.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemNameAndType.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemNameAndType.cs
index 9a2c381bd0..42243da418 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemNameAndType.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemNameAndType.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemString.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemString.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemString.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemString.cs
index c870bc53ba..3c0fd1694d 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemString.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemString.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemUtf8.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemUtf8.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemUtf8.cs
rename to src/IKVM.Runtime/ClassFile.ConstantPoolItemUtf8.cs
index a9c19ffbe4..52d09d83e9 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantPoolItemUtf8.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemUtf8.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantType.cs b/src/IKVM.Runtime/ClassFile.ConstantType.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.ConstantType.cs
rename to src/IKVM.Runtime/ClassFile.ConstantType.cs
index 2db6705f23..3fd0bee94f 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.ConstantType.cs
+++ b/src/IKVM.Runtime/ClassFile.ConstantType.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Field.cs b/src/IKVM.Runtime/ClassFile.Field.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Field.cs
rename to src/IKVM.Runtime/ClassFile.Field.cs
index 3b70595d04..ea90842c34 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Field.cs
+++ b/src/IKVM.Runtime/ClassFile.Field.cs
@@ -27,7 +27,7 @@ Jeroen Frijters
using IKVM.ByteCode;
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.FieldOrMethod.cs b/src/IKVM.Runtime/ClassFile.FieldOrMethod.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.FieldOrMethod.cs
rename to src/IKVM.Runtime/ClassFile.FieldOrMethod.cs
index ff47745968..718ab0a715 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.FieldOrMethod.cs
+++ b/src/IKVM.Runtime/ClassFile.FieldOrMethod.cs
@@ -28,7 +28,7 @@ Jeroen Frijters
using IKVM.ByteCode;
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.InnerClass.cs b/src/IKVM.Runtime/ClassFile.InnerClass.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.InnerClass.cs
rename to src/IKVM.Runtime/ClassFile.InnerClass.cs
index 7edde4f238..49e71db614 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.InnerClass.cs
+++ b/src/IKVM.Runtime/ClassFile.InnerClass.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using IKVM.Attributes;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.Code.cs b/src/IKVM.Runtime/ClassFile.Method.Code.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.Code.cs
rename to src/IKVM.Runtime/ClassFile.Method.Code.cs
index baa0a1ea41..f23d43c82e 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.Code.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.Code.cs
@@ -26,7 +26,7 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.ExceptionTableEntry.cs b/src/IKVM.Runtime/ClassFile.Method.ExceptionTableEntry.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.ExceptionTableEntry.cs
rename to src/IKVM.Runtime/ClassFile.Method.ExceptionTableEntry.cs
index 9614c51e19..25e5008420 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.ExceptionTableEntry.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.ExceptionTableEntry.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.Instruction.cs b/src/IKVM.Runtime/ClassFile.Method.Instruction.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.Instruction.cs
rename to src/IKVM.Runtime/ClassFile.Method.Instruction.cs
index 35b45e72e5..50ab0955d0 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.Instruction.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.Instruction.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
@@ -118,7 +118,7 @@ internal void MapSwitchTargets(int[] pcIndexMap)
internal void Read(ushort pc, BigEndianBinaryReader br, ClassFile classFile)
{
this.pc = pc;
- var bc = (global::ByteCode)br.ReadByte();
+ var bc = (ByteCode)br.ReadByte();
switch (ByteCodeMetaData.GetMode(bc))
{
case ByteCodeMode.Simple:
@@ -213,7 +213,7 @@ internal void Read(ushort pc, BigEndianBinaryReader br, ClassFile classFile)
break;
}
case ByteCodeMode.WidePrefix:
- bc = (global::ByteCode)br.ReadByte();
+ bc = (ByteCode)br.ReadByte();
// NOTE the PC of a wide instruction is actually the PC of the
// wide prefix, not the following instruction (vmspec 4.9.2)
switch (ByteCodeMetaData.GetWideMode(bc))
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.InstructionFlags.cs b/src/IKVM.Runtime/ClassFile.Method.InstructionFlags.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.InstructionFlags.cs
rename to src/IKVM.Runtime/ClassFile.Method.InstructionFlags.cs
index 6074d9a0dd..b8b8afca9a 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.InstructionFlags.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.InstructionFlags.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LineNumberTableEntry.cs b/src/IKVM.Runtime/ClassFile.Method.LineNumberTableEntry.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.LineNumberTableEntry.cs
rename to src/IKVM.Runtime/ClassFile.Method.LineNumberTableEntry.cs
index 6d08be72b9..e754acda71 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LineNumberTableEntry.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.LineNumberTableEntry.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LocalVariableTableEntry.cs b/src/IKVM.Runtime/ClassFile.Method.LocalVariableTableEntry.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.LocalVariableTableEntry.cs
rename to src/IKVM.Runtime/ClassFile.Method.LocalVariableTableEntry.cs
index 495753d7eb..1f948a6896 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LocalVariableTableEntry.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.LocalVariableTableEntry.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LowFreqData.cs b/src/IKVM.Runtime/ClassFile.Method.LowFreqData.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.LowFreqData.cs
rename to src/IKVM.Runtime/ClassFile.Method.LowFreqData.cs
index 3ec561f09c..45a02e0f09 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.LowFreqData.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.LowFreqData.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.Method.cs b/src/IKVM.Runtime/ClassFile.Method.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.Method.cs
rename to src/IKVM.Runtime/ClassFile.Method.cs
index 4675b982fc..c14509b42c 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.Method.cs
+++ b/src/IKVM.Runtime/ClassFile.Method.cs
@@ -22,7 +22,6 @@ Jeroen Frijters
*/
using System.Collections.Generic;
-using System.Linq;
using IKVM.Attributes;
using IKVM.ByteCode.Reading;
@@ -31,7 +30,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.SupportedVersions.cs b/src/IKVM.Runtime/ClassFile.SupportedVersions.cs
similarity index 97%
rename from src/IKVM.Runtime/ClassFile/ClassFile.SupportedVersions.cs
rename to src/IKVM.Runtime/ClassFile.SupportedVersions.cs
index ec19979d2d..9802c287e3 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.SupportedVersions.cs
+++ b/src/IKVM.Runtime/ClassFile.SupportedVersions.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
diff --git a/src/IKVM.Runtime/ClassFile/ClassFile.cs b/src/IKVM.Runtime/ClassFile.cs
similarity index 99%
rename from src/IKVM.Runtime/ClassFile/ClassFile.cs
rename to src/IKVM.Runtime/ClassFile.cs
index d573c7ae7e..9cf39608f7 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFile.cs
+++ b/src/IKVM.Runtime/ClassFile.cs
@@ -30,7 +30,7 @@ Jeroen Frijters
using IKVM.ByteCode;
using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed partial class ClassFile
@@ -639,23 +639,23 @@ static object ReadAnnotationElementValue(ElementValueReader reader, ClassFile cl
{
switch (reader)
{
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Boolean:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Boolean:
return classFile.GetConstantPoolConstantInteger(r.Value.Index) != 0;
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Byte:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Byte:
return (byte)classFile.GetConstantPoolConstantInteger(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Char:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Char:
return (char)classFile.GetConstantPoolConstantInteger(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Short:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Short:
return (short)classFile.GetConstantPoolConstantInteger(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Integer:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Integer:
return classFile.GetConstantPoolConstantInteger(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Float:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Float:
return classFile.GetConstantPoolConstantFloat(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Long:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Long:
return classFile.GetConstantPoolConstantLong(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.Double:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.Double:
return classFile.GetConstantPoolConstantDouble(r.Value.Index);
- case ElementValueConstantReader r when r.Tag == ByteCode.Parsing.ElementValueTag.String:
+ case ElementValueConstantReader r when r.Tag == IKVM.ByteCode.Parsing.ElementValueTag.String:
return classFile.GetConstantPoolUtf8String(utf8_cp, r.Value.Index);
case ElementValueEnumConstantReader r:
return new object[] {
diff --git a/src/IKVM.Runtime/ClassFile/ByteCode.cs b/src/IKVM.Runtime/ClassFile/ByteCode.cs
deleted file mode 100644
index bd8358bd2d..0000000000
--- a/src/IKVM.Runtime/ClassFile/ByteCode.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- Copyright (C) 2002, 2004, 2005, 2006 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-enum ByteCode : byte
-{
-
- __nop = 0,
- __aconst_null = 1,
- __iconst_m1 = 2,
- __iconst_0 = 3,
- __iconst_1 = 4,
- __iconst_2 = 5,
- __iconst_3 = 6,
- __iconst_4 = 7,
- __iconst_5 = 8,
- __lconst_0 = 9,
- __lconst_1 = 10,
- __fconst_0 = 11,
- __fconst_1 = 12,
- __fconst_2 = 13,
- __dconst_0 = 14,
- __dconst_1 = 15,
- __bipush = 16,
- __sipush = 17,
- __ldc = 18,
- __ldc_w = 19,
- __ldc2_w = 20,
- __iload = 21,
- __lload = 22,
- __fload = 23,
- __dload = 24,
- __aload = 25,
- __iload_0 = 26,
- __iload_1 = 27,
- __iload_2 = 28,
- __iload_3 = 29,
- __lload_0 = 30,
- __lload_1 = 31,
- __lload_2 = 32,
- __lload_3 = 33,
- __fload_0 = 34,
- __fload_1 = 35,
- __fload_2 = 36,
- __fload_3 = 37,
- __dload_0 = 38,
- __dload_1 = 39,
- __dload_2 = 40,
- __dload_3 = 41,
- __aload_0 = 42,
- __aload_1 = 43,
- __aload_2 = 44,
- __aload_3 = 45,
- __iaload = 46,
- __laload = 47,
- __faload = 48,
- __daload = 49,
- __aaload = 50,
- __baload = 51,
- __caload = 52,
- __saload = 53,
- __istore = 54,
- __lstore = 55,
- __fstore = 56,
- __dstore = 57,
- __astore = 58,
- __istore_0 = 59,
- __istore_1 = 60,
- __istore_2 = 61,
- __istore_3 = 62,
- __lstore_0 = 63,
- __lstore_1 = 64,
- __lstore_2 = 65,
- __lstore_3 = 66,
- __fstore_0 = 67,
- __fstore_1 = 68,
- __fstore_2 = 69,
- __fstore_3 = 70,
- __dstore_0 = 71,
- __dstore_1 = 72,
- __dstore_2 = 73,
- __dstore_3 = 74,
- __astore_0 = 75,
- __astore_1 = 76,
- __astore_2 = 77,
- __astore_3 = 78,
- __iastore = 79,
- __lastore = 80,
- __fastore = 81,
- __dastore = 82,
- __aastore = 83,
- __bastore = 84,
- __castore = 85,
- __sastore = 86,
- __pop = 87,
- __pop2 = 88,
- __dup = 89,
- __dup_x1 = 90,
- __dup_x2 = 91,
- __dup2 = 92,
- __dup2_x1 = 93,
- __dup2_x2 = 94,
- __swap = 95,
- __iadd = 96,
- __ladd = 97,
- __fadd = 98,
- __dadd = 99,
- __isub = 100,
- __lsub = 101,
- __fsub = 102,
- __dsub = 103,
- __imul = 104,
- __lmul = 105,
- __fmul = 106,
- __dmul = 107,
- __idiv = 108,
- __ldiv = 109,
- __fdiv = 110,
- __ddiv = 111,
- __irem = 112,
- __lrem = 113,
- __frem = 114,
- __drem = 115,
- __ineg = 116,
- __lneg = 117,
- __fneg = 118,
- __dneg = 119,
- __ishl = 120,
- __lshl = 121,
- __ishr = 122,
- __lshr = 123,
- __iushr = 124,
- __lushr = 125,
- __iand = 126,
- __land = 127,
- __ior = 128,
- __lor = 129,
- __ixor = 130,
- __lxor = 131,
- __iinc = 132,
- __i2l = 133,
- __i2f = 134,
- __i2d = 135,
- __l2i = 136,
- __l2f = 137,
- __l2d = 138,
- __f2i = 139,
- __f2l = 140,
- __f2d = 141,
- __d2i = 142,
- __d2l = 143,
- __d2f = 144,
- __i2b = 145,
- __i2c = 146,
- __i2s = 147,
- __lcmp = 148,
- __fcmpl = 149,
- __fcmpg = 150,
- __dcmpl = 151,
- __dcmpg = 152,
- __ifeq = 153,
- __ifne = 154,
- __iflt = 155,
- __ifge = 156,
- __ifgt = 157,
- __ifle = 158,
- __if_icmpeq = 159,
- __if_icmpne = 160,
- __if_icmplt = 161,
- __if_icmpge = 162,
- __if_icmpgt = 163,
- __if_icmple = 164,
- __if_acmpeq = 165,
- __if_acmpne = 166,
- __goto = 167,
- __jsr = 168,
- __ret = 169,
- __tableswitch = 170,
- __lookupswitch = 171,
- __ireturn = 172,
- __lreturn = 173,
- __freturn = 174,
- __dreturn = 175,
- __areturn = 176,
- __return = 177,
- __getstatic = 178,
- __putstatic = 179,
- __getfield = 180,
- __putfield = 181,
- __invokevirtual = 182,
- __invokespecial = 183,
- __invokestatic = 184,
- __invokeinterface = 185,
- __invokedynamic = 186,
- __new = 187,
- __newarray = 188,
- __anewarray = 189,
- __arraylength = 190,
- __athrow = 191,
- __checkcast = 192,
- __instanceof = 193,
- __monitorenter = 194,
- __monitorexit = 195,
- __wide = 196,
- __multianewarray = 197,
- __ifnull = 198,
- __ifnonnull = 199,
- __goto_w = 200,
- __jsr_w = 201
-
-}
diff --git a/src/IKVM.Runtime/ClassFile/ByteCodeMetaData.cs b/src/IKVM.Runtime/ClassFile/ByteCodeMetaData.cs
deleted file mode 100644
index 042fef9362..0000000000
--- a/src/IKVM.Runtime/ClassFile/ByteCodeMetaData.cs
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- Copyright (C) 2002, 2004, 2005, 2006 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-struct ByteCodeMetaData
-{
-
- private static ByteCodeMetaData[] data = new ByteCodeMetaData[256];
- private ByteCodeMode reg;
- private ByteCodeModeWide wide;
- private NormalizedByteCode normbc;
- private ByteCodeFlags flags;
- private int arg;
-
- private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
- {
- this.reg = reg;
- this.wide = wide;
- this.normbc = (NormalizedByteCode)bc;
- this.arg = 0;
- this.flags = ByteCodeFlags.None;
- if (cannotThrow)
- {
- this.flags |= ByteCodeFlags.CannotThrow;
- }
- data[(int)bc] = this;
- }
-
- private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
- {
- this.reg = reg;
- this.wide = wide;
- this.normbc = normbc;
- this.arg = 0;
- this.flags = ByteCodeFlags.None;
- if (cannotThrow)
- {
- this.flags |= ByteCodeFlags.CannotThrow;
- }
- data[(int)bc] = this;
- }
-
- private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
- {
- this.reg = reg;
- this.wide = wide;
- this.normbc = normbc;
- this.arg = arg;
- this.flags = ByteCodeFlags.FixedArg;
- if (cannotThrow)
- {
- this.flags |= ByteCodeFlags.CannotThrow;
- }
- data[(int)bc] = this;
- }
-
- internal static NormalizedByteCode GetNormalizedByteCode(ByteCode bc)
- {
- return data[(int)bc].normbc;
- }
-
- internal static int GetArg(ByteCode bc, int arg)
- {
- if ((data[(int)bc].flags & ByteCodeFlags.FixedArg) != 0)
- {
- return data[(int)bc].arg;
- }
- return arg;
- }
-
- internal static ByteCodeMode GetMode(ByteCode bc)
- {
- return data[(int)bc].reg;
- }
-
- internal static ByteCodeModeWide GetWideMode(ByteCode bc)
- {
- return data[(int)bc].wide;
- }
-
- internal static ByteCodeFlowControl GetFlowControl(NormalizedByteCode bc)
- {
- switch (bc)
- {
- case NormalizedByteCode.__tableswitch:
- case NormalizedByteCode.__lookupswitch:
- return ByteCodeFlowControl.Switch;
-
- case NormalizedByteCode.__goto:
- case NormalizedByteCode.__goto_finally:
- return ByteCodeFlowControl.Branch;
-
- case NormalizedByteCode.__ifeq:
- case NormalizedByteCode.__ifne:
- case NormalizedByteCode.__iflt:
- case NormalizedByteCode.__ifge:
- case NormalizedByteCode.__ifgt:
- case NormalizedByteCode.__ifle:
- case NormalizedByteCode.__if_icmpeq:
- case NormalizedByteCode.__if_icmpne:
- case NormalizedByteCode.__if_icmplt:
- case NormalizedByteCode.__if_icmpge:
- case NormalizedByteCode.__if_icmpgt:
- case NormalizedByteCode.__if_icmple:
- case NormalizedByteCode.__if_acmpeq:
- case NormalizedByteCode.__if_acmpne:
- case NormalizedByteCode.__ifnull:
- case NormalizedByteCode.__ifnonnull:
- return ByteCodeFlowControl.CondBranch;
-
- case NormalizedByteCode.__ireturn:
- case NormalizedByteCode.__lreturn:
- case NormalizedByteCode.__freturn:
- case NormalizedByteCode.__dreturn:
- case NormalizedByteCode.__areturn:
- case NormalizedByteCode.__return:
- return ByteCodeFlowControl.Return;
-
- case NormalizedByteCode.__athrow:
- case NormalizedByteCode.__athrow_no_unmap:
- case NormalizedByteCode.__static_error:
- return ByteCodeFlowControl.Throw;
-
- default:
- return ByteCodeFlowControl.Next;
- }
- }
-
- internal static bool CanThrowException(NormalizedByteCode bc)
- {
- switch (bc)
- {
- case NormalizedByteCode.__dynamic_invokeinterface:
- case NormalizedByteCode.__dynamic_invokestatic:
- case NormalizedByteCode.__dynamic_invokevirtual:
- case NormalizedByteCode.__dynamic_getstatic:
- case NormalizedByteCode.__dynamic_putstatic:
- case NormalizedByteCode.__dynamic_getfield:
- case NormalizedByteCode.__dynamic_putfield:
- case NormalizedByteCode.__clone_array:
- case NormalizedByteCode.__static_error:
- case NormalizedByteCode.__methodhandle_invoke:
- case NormalizedByteCode.__methodhandle_link:
- return true;
- case NormalizedByteCode.__iconst:
- case NormalizedByteCode.__ldc_nothrow:
- return false;
- default:
- return (data[(int)bc].flags & ByteCodeFlags.CannotThrow) == 0;
- }
- }
-
- internal static bool IsBranch(NormalizedByteCode bc)
- {
- switch (data[(int)bc].reg)
- {
- case ByteCodeMode.Branch_2:
- case ByteCodeMode.Branch_4:
- case ByteCodeMode.Lookupswitch:
- case ByteCodeMode.Tableswitch:
- return true;
- default:
- return false;
- }
- }
-
- static ByteCodeMetaData()
- {
- new ByteCodeMetaData(ByteCode.__nop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__aconst_null, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_m1, NormalizedByteCode.__iconst, -1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_0, NormalizedByteCode.__iconst, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_1, NormalizedByteCode.__iconst, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_2, NormalizedByteCode.__iconst, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_3, NormalizedByteCode.__iconst, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_4, NormalizedByteCode.__iconst, 4, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iconst_5, NormalizedByteCode.__iconst, 5, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fconst_2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dconst_0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dconst_1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__bipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__sipush, NormalizedByteCode.__iconst, ByteCodeMode.Immediate_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ldc, ByteCodeMode.Constant_1, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__ldc_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__ldc2_w, NormalizedByteCode.__ldc, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__iload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__lload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__fload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__dload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__aload, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__iload_0, NormalizedByteCode.__iload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_1, NormalizedByteCode.__iload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_2, NormalizedByteCode.__iload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iload_3, NormalizedByteCode.__iload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_0, NormalizedByteCode.__lload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_1, NormalizedByteCode.__lload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_2, NormalizedByteCode.__lload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lload_3, NormalizedByteCode.__lload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_0, NormalizedByteCode.__fload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_1, NormalizedByteCode.__fload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_2, NormalizedByteCode.__fload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fload_3, NormalizedByteCode.__fload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_0, NormalizedByteCode.__dload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_1, NormalizedByteCode.__dload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_2, NormalizedByteCode.__dload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dload_3, NormalizedByteCode.__dload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_0, NormalizedByteCode.__aload, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_1, NormalizedByteCode.__aload, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_2, NormalizedByteCode.__aload, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__aload_3, NormalizedByteCode.__aload, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__laload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__faload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__daload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__aaload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__baload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__caload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__saload, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__istore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__lstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__fstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__dstore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__astore, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__istore_0, NormalizedByteCode.__istore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_1, NormalizedByteCode.__istore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_2, NormalizedByteCode.__istore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__istore_3, NormalizedByteCode.__istore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_0, NormalizedByteCode.__lstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_1, NormalizedByteCode.__lstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_2, NormalizedByteCode.__lstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lstore_3, NormalizedByteCode.__lstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_0, NormalizedByteCode.__fstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_1, NormalizedByteCode.__fstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_2, NormalizedByteCode.__fstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fstore_3, NormalizedByteCode.__fstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_0, NormalizedByteCode.__dstore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_1, NormalizedByteCode.__dstore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_2, NormalizedByteCode.__dstore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dstore_3, NormalizedByteCode.__dstore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_0, NormalizedByteCode.__astore, 0, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_1, NormalizedByteCode.__astore, 1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_2, NormalizedByteCode.__astore, 2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__astore_3, NormalizedByteCode.__astore, 3, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__lastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__fastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__dastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__aastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__bastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__castore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__sastore, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__pop, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__pop2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2_x1, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dup2_x2, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__swap, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ladd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dadd, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__isub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dsub, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__imul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dmul, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__idiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__ldiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__fdiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ddiv, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__irem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__lrem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__frem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__drem, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ineg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dneg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ishl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lshl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ishr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lshr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lushr, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iand, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__land, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ior, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ixor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lxor, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iinc, ByteCodeMode.Local_1_Immediate_1, ByteCodeModeWide.Local_2_Immediate_2, true);
- new ByteCodeMetaData(ByteCode.__i2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__l2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__f2d, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2i, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2l, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__d2f, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2b, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2c, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__i2s, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lcmp, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__fcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dcmpl, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dcmpg, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__iflt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifle, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmplt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpge, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmpgt, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_icmple, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_acmpeq, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__if_acmpne, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__goto, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__jsr, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ret, ByteCodeMode.Local_1, ByteCodeModeWide.Local_2, true);
- new ByteCodeMetaData(ByteCode.__tableswitch, ByteCodeMode.Tableswitch, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lookupswitch, ByteCodeMode.Lookupswitch, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ireturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__lreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__freturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__dreturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__areturn, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__return, ByteCodeMode.Simple, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__getstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__putstatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__getfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__putfield, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokevirtual, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokespecial, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokestatic, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokeinterface, ByteCodeMode.Constant_2_1_1, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__invokedynamic, ByteCodeMode.Constant_2_1_1, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__new, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__newarray, ByteCodeMode.Immediate_1, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__anewarray, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__arraylength, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__athrow, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__checkcast, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__instanceof, ByteCodeMode.Constant_2, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__monitorenter, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__monitorexit, ByteCodeMode.Simple, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__wide, NormalizedByteCode.__nop, ByteCodeMode.WidePrefix, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__multianewarray, ByteCodeMode.Constant_2_Immediate_1, ByteCodeModeWide.Unused, false);
- new ByteCodeMetaData(ByteCode.__ifnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__ifnonnull, ByteCodeMode.Branch_2, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__goto_w, NormalizedByteCode.__goto, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
- new ByteCodeMetaData(ByteCode.__jsr_w, NormalizedByteCode.__jsr, ByteCodeMode.Branch_4, ByteCodeModeWide.Unused, true);
-
- }
-
-}
diff --git a/src/IKVM.Runtime/ClassFile/ClassFileParseOptions.cs b/src/IKVM.Runtime/ClassFileParseOptions.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/ClassFileParseOptions.cs
rename to src/IKVM.Runtime/ClassFileParseOptions.cs
index f4491e3d7f..a7fc6c9a95 100644
--- a/src/IKVM.Runtime/ClassFile/ClassFileParseOptions.cs
+++ b/src/IKVM.Runtime/ClassFileParseOptions.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
[Flags]
diff --git a/src/IKVM.Runtime/ClassLoaderWrapper.cs b/src/IKVM.Runtime/ClassLoaderWrapper.cs
index a880d38be8..0614c38cbe 100644
--- a/src/IKVM.Runtime/ClassLoaderWrapper.cs
+++ b/src/IKVM.Runtime/ClassLoaderWrapper.cs
@@ -53,7 +53,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
class ClassLoaderWrapper
diff --git a/src/IKVM.Runtime/CodeEmitter.cs b/src/IKVM.Runtime/CodeEmitter.cs
index a476672f0c..fd7cb3fcf6 100644
--- a/src/IKVM.Runtime/CodeEmitter.cs
+++ b/src/IKVM.Runtime/CodeEmitter.cs
@@ -39,7 +39,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class CodeEmitter
@@ -2878,7 +2878,7 @@ internal void CheckLabels()
foreach(System.Diagnostics.StackFrame frame in labels.Values)
{
string name = frame.GetFileName() + ":" + frame.GetFileLineNumber();
- IKVM.Internal.JVM.CriticalFailure("Label failure: " + name, null);
+ IKVM.Runtime.JVM.CriticalFailure("Label failure: " + name, null);
}
#endif
}
diff --git a/src/IKVM.Runtime/CodeEmitterLabel.cs b/src/IKVM.Runtime/CodeEmitterLabel.cs
index 3f1c3f8d3c..07232aa41d 100644
--- a/src/IKVM.Runtime/CodeEmitterLabel.cs
+++ b/src/IKVM.Runtime/CodeEmitterLabel.cs
@@ -29,7 +29,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class CodeEmitterLabel
diff --git a/src/IKVM.Runtime/CodeEmitterLocal.cs b/src/IKVM.Runtime/CodeEmitterLocal.cs
index 01f0a9885a..3005afa572 100644
--- a/src/IKVM.Runtime/CodeEmitterLocal.cs
+++ b/src/IKVM.Runtime/CodeEmitterLocal.cs
@@ -31,7 +31,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class CodeEmitterLocal
diff --git a/src/IKVM.Runtime/CodeGenOptions.cs b/src/IKVM.Runtime/CodeGenOptions.cs
index f9f1e5779d..b7bb5967dc 100644
--- a/src/IKVM.Runtime/CodeGenOptions.cs
+++ b/src/IKVM.Runtime/CodeGenOptions.cs
@@ -26,17 +26,20 @@ Jeroen Frijters
#if IMPORTER || EXPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+
using Type = IKVM.Reflection.Type;
using ProtectionDomain = System.Object;
#else
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
[Flags]
enum CodeGenOptions
{
+
None = 0,
Debug = 1,
NoStackTraceInfo = 2,
@@ -47,5 +50,7 @@ enum CodeGenOptions
DisableDynamicBinding = 64,
NoRefEmitHelpers = 128,
RemoveUnusedFields = 256,
+
}
+
}
diff --git a/src/IKVM.Runtime/CodeInfo.cs b/src/IKVM.Runtime/CodeInfo.cs
new file mode 100644
index 0000000000..b26a196a75
--- /dev/null
+++ b/src/IKVM.Runtime/CodeInfo.cs
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+namespace IKVM.Runtime
+{
+
+ readonly struct CodeInfo
+ {
+
+ private readonly InstructionState[] state;
+
+ internal CodeInfo(InstructionState[] state)
+ {
+ this.state = state;
+ }
+
+ internal bool HasState(int index)
+ {
+ return state[index] != null;
+ }
+
+ internal int GetStackHeight(int index)
+ {
+ return state[index].GetStackHeight();
+ }
+
+ internal TypeWrapper GetStackTypeWrapper(int index, int pos)
+ {
+ TypeWrapper type = state[index].GetStackSlot(pos);
+ if (VerifierTypeWrapper.IsThis(type))
+ {
+ type = ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ return type;
+ }
+
+ internal TypeWrapper GetRawStackTypeWrapper(int index, int pos)
+ {
+ return state[index].GetStackSlot(pos);
+ }
+
+ internal bool IsStackTypeExtendedDouble(int index, int pos)
+ {
+ return state[index].GetStackSlotEx(pos) == VerifierTypeWrapper.ExtendedDouble;
+ }
+
+ internal TypeWrapper GetLocalTypeWrapper(int index, int local)
+ {
+ return state[index].GetLocalTypeEx(local);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/CompiledAccessStubFieldWrapper.cs b/src/IKVM.Runtime/CompiledAccessStubFieldWrapper.cs
index ff8c43eacc..9446025100 100644
--- a/src/IKVM.Runtime/CompiledAccessStubFieldWrapper.cs
+++ b/src/IKVM.Runtime/CompiledAccessStubFieldWrapper.cs
@@ -33,11 +33,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class CompiledAccessStubFieldWrapper : FieldWrapper
diff --git a/src/IKVM.Runtime/CompiledPropertyFieldWrapper.cs b/src/IKVM.Runtime/CompiledPropertyFieldWrapper.cs
index bc7e26a78b..b24da5024e 100644
--- a/src/IKVM.Runtime/CompiledPropertyFieldWrapper.cs
+++ b/src/IKVM.Runtime/CompiledPropertyFieldWrapper.cs
@@ -32,11 +32,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/CompiledTypeWrapper.cs b/src/IKVM.Runtime/CompiledTypeWrapper.cs
index ffe612c3c8..a7516325c3 100644
--- a/src/IKVM.Runtime/CompiledTypeWrapper.cs
+++ b/src/IKVM.Runtime/CompiledTypeWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
using IKVM.Runtime.Syntax;
using IKVM.ByteCode;
@@ -44,7 +43,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
class CompiledTypeWrapper : TypeWrapper
diff --git a/src/IKVM.Runtime/ConstantFieldWrapper.cs b/src/IKVM.Runtime/ConstantFieldWrapper.cs
index ff12655d96..33609694c1 100644
--- a/src/IKVM.Runtime/ConstantFieldWrapper.cs
+++ b/src/IKVM.Runtime/ConstantFieldWrapper.cs
@@ -25,7 +25,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -37,11 +36,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/CoreClasses.cs b/src/IKVM.Runtime/CoreClasses.cs
index fa7f736c94..d185ffb838 100644
--- a/src/IKVM.Runtime/CoreClasses.cs
+++ b/src/IKVM.Runtime/CoreClasses.cs
@@ -22,9 +22,9 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
- internal static class CoreClasses
+ internal static class CoreClasses
{
internal static class cli
diff --git a/src/IKVM.Runtime/DefaultInterfaceMethodWrapper.cs b/src/IKVM.Runtime/DefaultInterfaceMethodWrapper.cs
index f4b65d185b..016840f258 100644
--- a/src/IKVM.Runtime/DefaultInterfaceMethodWrapper.cs
+++ b/src/IKVM.Runtime/DefaultInterfaceMethodWrapper.cs
@@ -33,7 +33,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class DefaultInterfaceMethodWrapper : SmartMethodWrapper
diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs
index 4766d415de..cde1c007c3 100644
--- a/src/IKVM.Runtime/DefineMethodHelper.cs
+++ b/src/IKVM.Runtime/DefineMethodHelper.cs
@@ -36,7 +36,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class DefineMethodHelper
diff --git a/src/IKVM.Runtime/DotNetTypeWrapper.cs b/src/IKVM.Runtime/DotNetTypeWrapper.cs
index 4a7fdd819c..fc2d437909 100644
--- a/src/IKVM.Runtime/DotNetTypeWrapper.cs
+++ b/src/IKVM.Runtime/DotNetTypeWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -42,7 +41,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class DotNetTypeWrapper : TypeWrapper
diff --git a/src/IKVM.Runtime/DynamicCallerIDProvider.cs b/src/IKVM.Runtime/DynamicCallerIDProvider.cs
index 3c81fb635e..9cad095b5f 100644
--- a/src/IKVM.Runtime/DynamicCallerIDProvider.cs
+++ b/src/IKVM.Runtime/DynamicCallerIDProvider.cs
@@ -22,21 +22,11 @@ Jeroen Frijters
*/
using System.Diagnostics;
-
-#if IMPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-using IKVM.Tools.Importer;
-
-using Type = IKVM.Reflection.Type;
-using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
-#else
using System.Reflection;
-#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
#if !IMPORTER
sealed class DynamicCallerIDProvider
diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs
index 0f625c3ab9..f68f5d731e 100644
--- a/src/IKVM.Runtime/DynamicClassLoader.cs
+++ b/src/IKVM.Runtime/DynamicClassLoader.cs
@@ -27,8 +27,6 @@ Jeroen Frijters
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
-using IKVM.Runtime;
-
#if IMPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
@@ -43,7 +41,7 @@ Jeroen Frijters
using ProtectionDomain = java.security.ProtectionDomain;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/DynamicMethodUtil.cs b/src/IKVM.Runtime/DynamicMethodUtil.cs
index b7792438fa..81cde41b18 100644
--- a/src/IKVM.Runtime/DynamicMethodUtil.cs
+++ b/src/IKVM.Runtime/DynamicMethodUtil.cs
@@ -3,8 +3,6 @@
using System.Reflection.Emit;
using System.Security;
-using IKVM.Internal;
-
namespace IKVM.Runtime
{
diff --git a/src/IKVM.Runtime/DynamicPropertyFieldWrapper.cs b/src/IKVM.Runtime/DynamicPropertyFieldWrapper.cs
index 6543bdd696..36b846e510 100644
--- a/src/IKVM.Runtime/DynamicPropertyFieldWrapper.cs
+++ b/src/IKVM.Runtime/DynamicPropertyFieldWrapper.cs
@@ -37,7 +37,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if EXPORTER == false
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.DynamicImpl.cs b/src/IKVM.Runtime/DynamicTypeWrapper.DynamicImpl.cs
index fe06ee2a48..040648a981 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.DynamicImpl.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.DynamicImpl.cs
@@ -27,17 +27,13 @@ Jeroen Frijters
#if IMPORTER
using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-using IKVM.Tools.Importer;
using Type = IKVM.Reflection.Type;
-using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
#else
using System.Reflection;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
@@ -47,8 +43,10 @@ abstract partial class DynamicTypeWrapper : TypeWrapper
sealed partial class DynamicTypeWrapper
#endif
{
+
private abstract class DynamicImpl
{
+
internal abstract Type Type { get; }
internal abstract TypeWrapper[] InnerClasses { get; }
internal abstract TypeWrapper DeclaringTypeWrapper { get; }
@@ -73,7 +71,9 @@ private abstract class DynamicImpl
internal abstract byte[] GetMethodRawTypeAnnotations(int index);
internal abstract byte[] GetFieldRawTypeAnnotations(int index);
internal abstract TypeWrapper Host { get; }
+
}
+
}
}
\ No newline at end of file
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.FinishContext.cs b/src/IKVM.Runtime/DynamicTypeWrapper.FinishContext.cs
index a1e4cb9a70..62a77e90b6 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.FinishContext.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.FinishContext.cs
@@ -27,7 +27,6 @@ Jeroen Frijters
using IKVM.ByteCode.Reading;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
@@ -36,15 +35,14 @@ Jeroen Frijters
using Type = IKVM.Reflection.Type;
using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
#else
using System.Reflection;
using System.Reflection.Emit;
-using DynamicOrAotTypeWrapper = IKVM.Internal.DynamicTypeWrapper;
+using DynamicOrAotTypeWrapper = IKVM.Runtime.DynamicTypeWrapper;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
@@ -54,8 +52,10 @@ abstract partial class DynamicTypeWrapper : TypeWrapper
sealed partial class DynamicTypeWrapper
#endif
{
+
internal sealed class FinishContext
{
+
private readonly TypeWrapper host;
private readonly ClassFile classFile;
private readonly DynamicOrAotTypeWrapper wrapper;
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.FinishedTypeImpl.cs b/src/IKVM.Runtime/DynamicTypeWrapper.FinishedTypeImpl.cs
index 37e159c689..d9887dfdc5 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.FinishedTypeImpl.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.FinishedTypeImpl.cs
@@ -32,14 +32,12 @@ Jeroen Frijters
using IKVM.Tools.Importer;
using Type = IKVM.Reflection.Type;
-using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
#else
using System.Reflection;
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
@@ -49,6 +47,7 @@ abstract partial class DynamicTypeWrapper : TypeWrapper
sealed partial class DynamicTypeWrapper
#endif
{
+
sealed class FinishedTypeImpl : DynamicImpl
{
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.JavaTypeImpl.cs b/src/IKVM.Runtime/DynamicTypeWrapper.JavaTypeImpl.cs
index a336fd28e9..941a6085ee 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.JavaTypeImpl.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.JavaTypeImpl.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
@@ -35,15 +34,14 @@ Jeroen Frijters
using Type = IKVM.Reflection.Type;
using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
#else
using System.Reflection;
using System.Reflection.Emit;
-using DynamicOrAotTypeWrapper = IKVM.Internal.DynamicTypeWrapper;
+using DynamicOrAotTypeWrapper = IKVM.Runtime.DynamicTypeWrapper;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
@@ -53,6 +51,7 @@ abstract partial class DynamicTypeWrapper : TypeWrapper
sealed partial class DynamicTypeWrapper
#endif
{
+
private sealed class JavaTypeImpl : DynamicImpl
{
private readonly TypeWrapper host;
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.Metadata.cs b/src/IKVM.Runtime/DynamicTypeWrapper.Metadata.cs
index a9354ec210..62d2c2fc08 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.Metadata.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.Metadata.cs
@@ -22,24 +22,12 @@ Jeroen Frijters
*/
using System.Collections.Generic;
-
-using IKVM.Runtime;
-using IKVM.ByteCode.Reading;
-using IKVM.ByteCode.Parsing;
-
using System.Linq;
-#if IMPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-using IKVM.Tools.Importer;
-
-using Type = IKVM.Reflection.Type;
-using DynamicOrAotTypeWrapper = IKVM.Tools.Importer.AotTypeWrapper;
-using ProtectionDomain = System.Object;
-#endif
+using IKVM.ByteCode.Parsing;
+using IKVM.ByteCode.Reading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
@@ -49,6 +37,7 @@ abstract partial class DynamicTypeWrapper : TypeWrapper
sealed partial class DynamicTypeWrapper
#endif
{
+
sealed class Metadata
{
diff --git a/src/IKVM.Runtime/DynamicTypeWrapper.cs b/src/IKVM.Runtime/DynamicTypeWrapper.cs
index 8304866631..ce7e0c6b95 100644
--- a/src/IKVM.Runtime/DynamicTypeWrapper.cs
+++ b/src/IKVM.Runtime/DynamicTypeWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
@@ -40,11 +39,11 @@ Jeroen Frijters
using System.Reflection;
using System.Reflection.Emit;
-using DynamicOrAotTypeWrapper = IKVM.Internal.DynamicTypeWrapper;
+using DynamicOrAotTypeWrapper = IKVM.Runtime.DynamicTypeWrapper;
using ProtectionDomain = java.security.ProtectionDomain;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if IMPORTER
diff --git a/src/IKVM.Runtime/EmitIntrinsicContext.cs b/src/IKVM.Runtime/EmitIntrinsicContext.cs
new file mode 100644
index 0000000000..0ff3644aaa
--- /dev/null
+++ b/src/IKVM.Runtime/EmitIntrinsicContext.cs
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2008-2013 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+using Instruction = IKVM.Runtime.ClassFile.Method.Instruction;
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
+
+namespace IKVM.Runtime
+{
+
+ sealed class EmitIntrinsicContext
+ {
+
+ internal readonly MethodWrapper Method;
+ internal readonly DynamicTypeWrapper.FinishContext Context;
+ internal readonly CodeEmitter Emitter;
+ readonly CodeInfo ma;
+ internal readonly int OpcodeIndex;
+ internal readonly MethodWrapper Caller;
+ internal readonly ClassFile ClassFile;
+ internal readonly Instruction[] Code;
+ internal readonly InstructionFlags[] Flags;
+ internal bool NonLeaf = true;
+
+ internal EmitIntrinsicContext(MethodWrapper method, DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, CodeInfo ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
+ {
+ this.Method = method;
+ this.Context = context;
+ this.Emitter = ilgen;
+ this.ma = ma;
+ this.OpcodeIndex = opcodeIndex;
+ this.Caller = caller;
+ this.ClassFile = classFile;
+ this.Code = code;
+ this.Flags = flags;
+ }
+
+ internal bool MatchRange(int offset, int length)
+ {
+ if (OpcodeIndex + offset < 0)
+ return false;
+
+ if (OpcodeIndex + offset + length > Code.Length)
+ return false;
+
+ // we check for branches *into* the range, the start of the range may be a branch target
+ for (int i = OpcodeIndex + offset + 1, end = OpcodeIndex + offset + length; i < end; i++)
+ if ((Flags[i] & InstructionFlags.BranchTarget) != 0)
+ return false;
+
+ return true;
+ }
+
+ internal bool Match(int offset, NormalizedByteCode opcode)
+ {
+ return Code[OpcodeIndex + offset].NormalizedOpCode == opcode;
+ }
+
+ internal bool Match(int offset, NormalizedByteCode opcode, int arg)
+ {
+ return Code[OpcodeIndex + offset].NormalizedOpCode == opcode && Code[OpcodeIndex + offset].Arg1 == arg;
+ }
+
+ internal TypeWrapper GetStackTypeWrapper(int offset, int pos)
+ {
+ return ma.GetStackTypeWrapper(OpcodeIndex + offset, pos);
+ }
+
+ internal ClassFile.ConstantPoolItemMI GetMethodref(int offset)
+ {
+ return ClassFile.GetMethodref(Code[OpcodeIndex + offset].Arg1);
+ }
+
+ internal ClassFile.ConstantPoolItemFieldref GetFieldref(int offset)
+ {
+ return ClassFile.GetFieldref(Code[OpcodeIndex + offset].Arg1);
+ }
+
+ internal TypeWrapper GetClassLiteral(int offset)
+ {
+ return ClassFile.GetConstantPoolClassType(Code[OpcodeIndex + offset].Arg1);
+ }
+
+ internal string GetStringLiteral(int offset)
+ {
+ return ClassFile.GetConstantPoolConstantString(Code[OpcodeIndex + offset].Arg1);
+ }
+
+ internal ClassFile.ConstantType GetConstantType(int offset)
+ {
+ return ClassFile.GetConstantPoolConstantType(Code[OpcodeIndex + offset].Arg1);
+ }
+
+ internal void PatchOpCode(int offset, NormalizedByteCode opc)
+ {
+ Code[OpcodeIndex + offset].PatchOpCode(opc);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/EnumHelper.cs b/src/IKVM.Runtime/EnumHelper.cs
index 2e6550984f..93a0537608 100644
--- a/src/IKVM.Runtime/EnumHelper.cs
+++ b/src/IKVM.Runtime/EnumHelper.cs
@@ -24,26 +24,21 @@ Jeroen Frijters
using System;
using System.Diagnostics;
-using IKVM.Runtime;
-
#if IMPORTER || EXPORTER
using IKVM.Reflection;
-using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;
-#else
-#endif
-
-#if IMPORTER
-using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class EnumHelper
{
+
internal static Type GetUnderlyingType(Type enumType)
{
+
#if IMPORTER || EXPORTER
return enumType.GetEnumUnderlyingType();
#else
@@ -52,6 +47,7 @@ internal static Type GetUnderlyingType(Type enumType)
}
#if IMPORTER
+
internal static object Parse(Type type, string value)
{
object retval = null;
@@ -147,6 +143,7 @@ internal static object GetPrimitiveValue(Type underlyingType, object obj)
throw new InvalidOperationException();
}
}
+
}
}
diff --git a/src/IKVM.Runtime/ExModifiers.cs b/src/IKVM.Runtime/ExModifiers.cs
index bd6187098e..ce7a3d86eb 100644
--- a/src/IKVM.Runtime/ExModifiers.cs
+++ b/src/IKVM.Runtime/ExModifiers.cs
@@ -23,8 +23,9 @@ Jeroen Frijters
*/
using IKVM.Attributes;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
struct ExModifiers
{
diff --git a/src/IKVM.Runtime/ExceptionHelper.cs b/src/IKVM.Runtime/ExceptionHelper.cs
index d45e0e60a9..2cb495fdea 100644
--- a/src/IKVM.Runtime/ExceptionHelper.cs
+++ b/src/IKVM.Runtime/ExceptionHelper.cs
@@ -29,7 +29,6 @@ Jeroen Frijters
using System.Security;
using IKVM.Attributes;
-using IKVM.Runtime;
using IDictionary = System.Collections.IDictionary;
using Interlocked = System.Threading.Interlocked;
@@ -43,7 +42,7 @@ Jeroen Frijters
using Throwable = java.lang.Throwable;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class ExceptionHelper
diff --git a/src/IKVM.Runtime/ExceptionSorter.cs b/src/IKVM.Runtime/ExceptionSorter.cs
new file mode 100644
index 0000000000..35d1932bfd
--- /dev/null
+++ b/src/IKVM.Runtime/ExceptionSorter.cs
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System.Collections.Generic;
+
+using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry;
+
+namespace IKVM.Runtime
+{
+
+ sealed class ExceptionSorter : IComparer
+ {
+
+ public int Compare(ExceptionTableEntry e1, ExceptionTableEntry e2)
+ {
+ if (e1.startIndex < e2.startIndex)
+ {
+ return -1;
+ }
+ if (e1.startIndex == e2.startIndex)
+ {
+ if (e1.endIndex == e2.endIndex)
+ {
+ if (e1.ordinal > e2.ordinal)
+ {
+ return -1;
+ }
+ if (e1.ordinal == e2.ordinal)
+ {
+ return 0;
+ }
+ return 1;
+ }
+ if (e1.endIndex > e2.endIndex)
+ {
+ return -1;
+ }
+ }
+ return 1;
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/FieldWrapper.cs b/src/IKVM.Runtime/FieldWrapper.cs
index 5d13982080..cfa6e3d38b 100644
--- a/src/IKVM.Runtime/FieldWrapper.cs
+++ b/src/IKVM.Runtime/FieldWrapper.cs
@@ -27,9 +27,6 @@ Jeroen Frijters
using IKVM.Attributes;
using System.Threading;
-using System.CodeDom;
-using System.Linq;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -41,7 +38,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
abstract class FieldWrapper : MemberWrapper
diff --git a/src/IKVM.Runtime/GenericClassLoaderWrapper.cs b/src/IKVM.Runtime/GenericClassLoaderWrapper.cs
index 81e4e9f366..5e56b16421 100644
--- a/src/IKVM.Runtime/GenericClassLoaderWrapper.cs
+++ b/src/IKVM.Runtime/GenericClassLoaderWrapper.cs
@@ -23,18 +23,7 @@ Jeroen Frijters
*/
using System;
-#if NETCOREAPP
-using System.Runtime.Loader;
-#endif
-
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-using Type = IKVM.Reflection.Type;
-using ProtectionDomain = System.Object;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class GenericClassLoaderWrapper : ClassLoaderWrapper
diff --git a/src/IKVM.Runtime/GhostMethodWrapper.cs b/src/IKVM.Runtime/GhostMethodWrapper.cs
index 15beff69d1..6760702a5e 100644
--- a/src/IKVM.Runtime/GhostMethodWrapper.cs
+++ b/src/IKVM.Runtime/GhostMethodWrapper.cs
@@ -28,14 +28,12 @@ Jeroen Frijters
#if IMPORTER || EXPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class GhostMethodWrapper : SmartMethodWrapper
diff --git a/src/IKVM.Runtime/GhostTag.cs b/src/IKVM.Runtime/GhostTag.cs
index 1e60bd338f..f172051933 100644
--- a/src/IKVM.Runtime/GhostTag.cs
+++ b/src/IKVM.Runtime/GhostTag.cs
@@ -26,15 +26,6 @@ Jeroen Frijters
using System.Threading;
using IKVM.Attributes;
-using IKVM.Internal;
-
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
-#else
-#endif
namespace IKVM.Runtime
{
@@ -103,6 +94,7 @@ internal static void ThrowClassCastException(object obj, RuntimeTypeHandle typeH
throw new global::java.lang.ClassCastException(sb.ToString());
#endif
}
+
}
}
diff --git a/src/IKVM.Runtime/ClassFile/HardError.cs b/src/IKVM.Runtime/HardError.cs
similarity index 98%
rename from src/IKVM.Runtime/ClassFile/HardError.cs
rename to src/IKVM.Runtime/HardError.cs
index c24be17987..b6021c1e07 100644
--- a/src/IKVM.Runtime/ClassFile/HardError.cs
+++ b/src/IKVM.Runtime/HardError.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
enum HardError : short
diff --git a/src/IKVM.Runtime/IKVM.Runtime.csproj b/src/IKVM.Runtime/IKVM.Runtime.csproj
index 2ad4359872..0631d33f93 100644
--- a/src/IKVM.Runtime/IKVM.Runtime.csproj
+++ b/src/IKVM.Runtime/IKVM.Runtime.csproj
@@ -69,15 +69,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/IKVM.Runtime/InstructionState.cs b/src/IKVM.Runtime/InstructionState.cs
new file mode 100644
index 0000000000..e7bbe84fec
--- /dev/null
+++ b/src/IKVM.Runtime/InstructionState.cs
@@ -0,0 +1,943 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System;
+using System.Collections.Generic;
+
+#if IMPORTER
+using IKVM.Tools.Importer;
+#endif
+
+namespace IKVM.Runtime
+{
+
+ sealed class InstructionState
+ {
+
+ private struct LocalStoreSites
+ {
+
+ private int[] data;
+ private int count;
+ private bool shared;
+
+ internal LocalStoreSites Copy()
+ {
+ LocalStoreSites n = new LocalStoreSites();
+ n.data = data;
+ n.count = count;
+ n.shared = true;
+ return n;
+ }
+
+ internal static LocalStoreSites Alloc()
+ {
+ LocalStoreSites n = new LocalStoreSites();
+ n.data = new int[4];
+ return n;
+ }
+
+ internal void Add(int store)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (data[i] == store)
+ {
+ return;
+ }
+ }
+ if (count == data.Length)
+ {
+ int[] newarray = new int[data.Length * 2];
+ Buffer.BlockCopy(data, 0, newarray, 0, data.Length * 4);
+ data = newarray;
+ shared = false;
+ }
+ if (shared)
+ {
+ shared = false;
+ data = (int[])data.Clone();
+ }
+ data[count++] = store;
+ }
+
+ internal int this[int index]
+ {
+ get
+ {
+ return data[index];
+ }
+ }
+
+ internal int Count
+ {
+ get
+ {
+ return count;
+ }
+ }
+
+ internal static void MarkShared(LocalStoreSites[] localStoreSites)
+ {
+ for (int i = 0; i < localStoreSites.Length; i++)
+ {
+ localStoreSites[i].shared = true;
+ }
+ }
+ }
+
+ TypeWrapper[] stack;
+ int stackSize;
+ int stackEnd;
+ TypeWrapper[] locals;
+ bool unitializedThis;
+ internal bool changed = true;
+
+ private enum ShareFlags : byte
+ {
+ None = 0,
+ Stack = 1,
+ Locals = 2,
+ All = Stack | Locals
+ }
+ private ShareFlags flags;
+
+ private InstructionState(TypeWrapper[] stack, int stackSize, int stackEnd, TypeWrapper[] locals, bool unitializedThis)
+ {
+ this.flags = ShareFlags.All;
+ this.stack = stack;
+ this.stackSize = stackSize;
+ this.stackEnd = stackEnd;
+ this.locals = locals;
+ this.unitializedThis = unitializedThis;
+ }
+
+ internal InstructionState(int maxLocals, int maxStack)
+ {
+ this.flags = ShareFlags.None;
+ this.stack = new TypeWrapper[maxStack];
+ this.stackEnd = maxStack;
+ this.locals = new TypeWrapper[maxLocals];
+ }
+
+ internal InstructionState Copy()
+ {
+ return new InstructionState(stack, stackSize, stackEnd, locals, unitializedThis);
+ }
+
+ internal void CopyTo(InstructionState target)
+ {
+ target.flags = ShareFlags.All;
+ target.stack = stack;
+ target.stackSize = stackSize;
+ target.stackEnd = stackEnd;
+ target.locals = locals;
+ target.unitializedThis = unitializedThis;
+ target.changed = true;
+ }
+
+ internal InstructionState CopyLocals()
+ {
+ InstructionState copy = new InstructionState(new TypeWrapper[stack.Length], 0, stack.Length, locals, unitializedThis);
+ copy.flags &= ~ShareFlags.Stack;
+ return copy;
+ }
+
+ public static InstructionState operator +(InstructionState s1, InstructionState s2)
+ {
+ if (s1 == null)
+ {
+ return s2.Copy();
+ }
+ if (s1.stackSize != s2.stackSize || s1.stackEnd != s2.stackEnd)
+ {
+ throw new VerifyError(string.Format("Inconsistent stack height: {0} != {1}",
+ s1.stackSize + s1.stack.Length - s1.stackEnd,
+ s2.stackSize + s2.stack.Length - s2.stackEnd));
+ }
+ InstructionState s = s1.Copy();
+ s.changed = s1.changed;
+ for (int i = 0; i < s.stackSize; i++)
+ {
+ TypeWrapper type = s.stack[i];
+ TypeWrapper type2 = s2.stack[i];
+ if (type == type2)
+ {
+ // perfect match, nothing to do
+ }
+ else if ((type == VerifierTypeWrapper.ExtendedDouble && type2 == PrimitiveTypeWrapper.DOUBLE)
+ || (type2 == VerifierTypeWrapper.ExtendedDouble && type == PrimitiveTypeWrapper.DOUBLE))
+ {
+ if (type != VerifierTypeWrapper.ExtendedDouble)
+ {
+ s.StackCopyOnWrite();
+ s.stack[i] = VerifierTypeWrapper.ExtendedDouble;
+ s.changed = true;
+ }
+ }
+ else if ((type == VerifierTypeWrapper.ExtendedFloat && type2 == PrimitiveTypeWrapper.FLOAT)
+ || (type2 == VerifierTypeWrapper.ExtendedFloat && type == PrimitiveTypeWrapper.FLOAT))
+ {
+ if (type != VerifierTypeWrapper.ExtendedFloat)
+ {
+ s.StackCopyOnWrite();
+ s.stack[i] = VerifierTypeWrapper.ExtendedFloat;
+ s.changed = true;
+ }
+ }
+ else if (!type.IsPrimitive)
+ {
+ TypeWrapper baseType = InstructionState.FindCommonBaseType(type, type2);
+ if (baseType == VerifierTypeWrapper.Invalid)
+ {
+ throw new VerifyError(string.Format("cannot merge {0} and {1}", type.Name, type2.Name));
+ }
+ if (type != baseType)
+ {
+ s.StackCopyOnWrite();
+ s.stack[i] = baseType;
+ s.changed = true;
+ }
+ }
+ else
+ {
+ throw new VerifyError(string.Format("cannot merge {0} and {1}", type.Name, type2.Name));
+ }
+ }
+ for (int i = 0; i < s.locals.Length; i++)
+ {
+ TypeWrapper type = s.locals[i];
+ TypeWrapper type2 = s2.locals[i];
+ TypeWrapper baseType = InstructionState.FindCommonBaseType(type, type2);
+ if (type != baseType)
+ {
+ s.LocalsCopyOnWrite();
+ s.locals[i] = baseType;
+ s.changed = true;
+ }
+ }
+ if (!s.unitializedThis && s2.unitializedThis)
+ {
+ s.unitializedThis = true;
+ s.changed = true;
+ }
+ return s;
+ }
+
+ private static LocalStoreSites MergeStoreSites(LocalStoreSites h1, LocalStoreSites h2)
+ {
+ if (h1.Count == 0)
+ {
+ return h2.Copy();
+ }
+ if (h2.Count == 0)
+ {
+ return h1.Copy();
+ }
+ LocalStoreSites h = h1.Copy();
+ for (int i = 0; i < h2.Count; i++)
+ {
+ h.Add(h2[i]);
+ }
+ return h;
+ }
+
+ internal void SetUnitializedThis(bool state)
+ {
+ unitializedThis = state;
+ }
+
+ internal void CheckUninitializedThis()
+ {
+ if (unitializedThis)
+ {
+ throw new VerifyError("Base class constructor wasn't called");
+ }
+ }
+
+ internal static TypeWrapper FindCommonBaseType(TypeWrapper type1, TypeWrapper type2)
+ {
+ if (type1 == type2)
+ {
+ return type1;
+ }
+ if (type1 == VerifierTypeWrapper.Null)
+ {
+ return type2;
+ }
+ if (type2 == VerifierTypeWrapper.Null)
+ {
+ return type1;
+ }
+ if (type1 == VerifierTypeWrapper.Invalid || type2 == VerifierTypeWrapper.Invalid)
+ {
+ return VerifierTypeWrapper.Invalid;
+ }
+ if (VerifierTypeWrapper.IsFaultBlockException(type1))
+ {
+ VerifierTypeWrapper.ClearFaultBlockException(type1);
+ return FindCommonBaseType(CoreClasses.java.lang.Throwable.Wrapper, type2);
+ }
+ if (VerifierTypeWrapper.IsFaultBlockException(type2))
+ {
+ VerifierTypeWrapper.ClearFaultBlockException(type2);
+ return FindCommonBaseType(type1, CoreClasses.java.lang.Throwable.Wrapper);
+ }
+ if (type1.IsPrimitive || type2.IsPrimitive)
+ {
+ return VerifierTypeWrapper.Invalid;
+ }
+ if (type1 == VerifierTypeWrapper.UninitializedThis || type2 == VerifierTypeWrapper.UninitializedThis)
+ {
+ return VerifierTypeWrapper.Invalid;
+ }
+ if (VerifierTypeWrapper.IsNew(type1) || VerifierTypeWrapper.IsNew(type2))
+ {
+ return VerifierTypeWrapper.Invalid;
+ }
+ if (VerifierTypeWrapper.IsThis(type1))
+ {
+ type1 = ((VerifierTypeWrapper)type1).UnderlyingType;
+ }
+ if (VerifierTypeWrapper.IsThis(type2))
+ {
+ type2 = ((VerifierTypeWrapper)type2).UnderlyingType;
+ }
+ if (type1.IsUnloadable || type2.IsUnloadable)
+ {
+ return VerifierTypeWrapper.Unloadable;
+ }
+ if (type1.ArrayRank > 0 && type2.ArrayRank > 0)
+ {
+ int rank = 1;
+ int rank1 = type1.ArrayRank - 1;
+ int rank2 = type2.ArrayRank - 1;
+ TypeWrapper elem1 = type1.ElementTypeWrapper;
+ TypeWrapper elem2 = type2.ElementTypeWrapper;
+ while (rank1 != 0 && rank2 != 0)
+ {
+ elem1 = elem1.ElementTypeWrapper;
+ elem2 = elem2.ElementTypeWrapper;
+ rank++;
+ rank1--;
+ rank2--;
+ }
+ // NOTE arrays of value types have special merging semantics!
+ // NOTE we don't have to test for the case where the element types are the same, because that
+ // is only relevant if the ranks are the same, but if that is the case the types are completely
+ // identical, in which case the identity test at the top of this method already returned.
+ TypeWrapper baseType;
+ if (elem1.IsPrimitive || elem2.IsPrimitive || elem1.IsNonPrimitiveValueType || elem2.IsNonPrimitiveValueType)
+ {
+ baseType = CoreClasses.java.lang.Object.Wrapper;
+ rank--;
+ if (rank == 0)
+ {
+ return baseType;
+ }
+ }
+ else
+ {
+ baseType = FindCommonBaseTypeHelper(elem1, elem2);
+ }
+ return baseType.MakeArrayType(rank);
+ }
+ return FindCommonBaseTypeHelper(type1, type2);
+ }
+
+ private static TypeWrapper FindCommonBaseTypeHelper(TypeWrapper t1, TypeWrapper t2)
+ {
+ if (t1 == t2)
+ {
+ return t1;
+ }
+ if (t1.IsInterface || t2.IsInterface)
+ {
+ // NOTE according to a paper by Alessandro Coglio & Allen Goldberg titled
+ // "Type Safety in the JVM: Some Problems in Java 2 SDK 1.2 and Proposed Solutions"
+ // the common base of two interfaces is java.lang.Object, and there is special
+ // treatment for java.lang.Object types that allow it to be assigned to any interface
+ // type, the JVM's typesafety then depends on the invokeinterface instruction to make
+ // sure that the reference actually implements the interface.
+ // NOTE the ECMA CLI spec also specifies this interface merging algorithm, so we can't
+ // really do anything more clever than this.
+ return CoreClasses.java.lang.Object.Wrapper;
+ }
+ Stack st1 = new Stack();
+ Stack st2 = new Stack();
+ while (t1 != null)
+ {
+ st1.Push(t1);
+ t1 = t1.BaseTypeWrapper;
+ }
+ while (t2 != null)
+ {
+ st2.Push(t2);
+ t2 = t2.BaseTypeWrapper;
+ }
+ if (HasMissingBaseType(st1) || HasMissingBaseType(st2))
+ {
+ return VerifierTypeWrapper.Unloadable;
+ }
+ TypeWrapper type = CoreClasses.java.lang.Object.Wrapper;
+ for (; ; )
+ {
+ t1 = st1.Count > 0 ? st1.Pop() : null;
+ t2 = st2.Count > 0 ? st2.Pop() : null;
+ if (t1 != t2)
+ {
+ return type;
+ }
+ type = t1;
+ }
+ }
+
+ private static bool HasMissingBaseType(Stack st)
+ {
+#if IMPORTER
+ if (st.Pop().IsUnloadable)
+ {
+ // we have a missing type in base class hierarchy
+ StaticCompiler.IssueMissingTypeMessage(st.Pop().TypeAsBaseType.BaseType);
+ return true;
+ }
+#endif
+ return false;
+ }
+
+ private void SetLocal1(int index, TypeWrapper type)
+ {
+ try
+ {
+ LocalsCopyOnWrite();
+ if (index > 0 && locals[index - 1] != VerifierTypeWrapper.Invalid && locals[index - 1].IsWidePrimitive)
+ {
+ locals[index - 1] = VerifierTypeWrapper.Invalid;
+ }
+ locals[index] = type;
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new VerifyError("Illegal local variable number");
+ }
+ }
+
+ private void SetLocal2(int index, TypeWrapper type)
+ {
+ try
+ {
+ LocalsCopyOnWrite();
+ if (index > 0 && locals[index - 1] != VerifierTypeWrapper.Invalid && locals[index - 1].IsWidePrimitive)
+ {
+ locals[index - 1] = VerifierTypeWrapper.Invalid;
+ }
+ locals[index] = type;
+ locals[index + 1] = VerifierTypeWrapper.Invalid;
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new VerifyError("Illegal local variable number");
+ }
+ }
+
+ internal void GetLocalInt(int index)
+ {
+ if (GetLocalType(index) != PrimitiveTypeWrapper.INT)
+ {
+ throw new VerifyError("Invalid local type");
+ }
+ }
+
+ internal void SetLocalInt(int index, int instructionIndex)
+ {
+ SetLocal1(index, PrimitiveTypeWrapper.INT);
+ }
+
+ internal void GetLocalLong(int index)
+ {
+ if (GetLocalType(index) != PrimitiveTypeWrapper.LONG)
+ {
+ throw new VerifyError("incorrect local type, not long");
+ }
+ }
+
+ internal void SetLocalLong(int index, int instructionIndex)
+ {
+ SetLocal2(index, PrimitiveTypeWrapper.LONG);
+ }
+
+ internal void GetLocalFloat(int index)
+ {
+ if (GetLocalType(index) != PrimitiveTypeWrapper.FLOAT)
+ {
+ throw new VerifyError("incorrect local type, not float");
+ }
+ }
+
+ internal void SetLocalFloat(int index, int instructionIndex)
+ {
+ SetLocal1(index, PrimitiveTypeWrapper.FLOAT);
+ }
+
+ internal void GetLocalDouble(int index)
+ {
+ if (GetLocalType(index) != PrimitiveTypeWrapper.DOUBLE)
+ {
+ throw new VerifyError("incorrect local type, not double");
+ }
+ }
+
+ internal void SetLocalDouble(int index, int instructionIndex)
+ {
+ SetLocal2(index, PrimitiveTypeWrapper.DOUBLE);
+ }
+
+ internal TypeWrapper GetLocalType(int index)
+ {
+ try
+ {
+ return locals[index];
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new VerifyError("Illegal local variable number");
+ }
+ }
+
+ // this is used by the compiler (indirectly, through MethodAnalyzer.GetLocalTypeWrapper),
+ // we've already verified the code so we know we won't run outside the array boundary,
+ // and we don't need to record the fact that we're reading the local.
+ internal TypeWrapper GetLocalTypeEx(int index)
+ {
+ return locals[index];
+ }
+
+ internal void SetLocalType(int index, TypeWrapper type, int instructionIndex)
+ {
+ if (type.IsWidePrimitive)
+ {
+ SetLocal2(index, type);
+ }
+ else
+ {
+ SetLocal1(index, type);
+ }
+ }
+
+ internal void PushType(TypeWrapper type)
+ {
+ if (type.IsIntOnStackPrimitive)
+ {
+ type = PrimitiveTypeWrapper.INT;
+ }
+ PushHelper(type);
+ }
+
+ internal void PushInt()
+ {
+ PushHelper(PrimitiveTypeWrapper.INT);
+ }
+
+ internal void PushLong()
+ {
+ PushHelper(PrimitiveTypeWrapper.LONG);
+ }
+
+ internal void PushFloat()
+ {
+ PushHelper(PrimitiveTypeWrapper.FLOAT);
+ }
+
+ internal void PushExtendedFloat()
+ {
+ PushHelper(VerifierTypeWrapper.ExtendedFloat);
+ }
+
+ internal void PushDouble()
+ {
+ PushHelper(PrimitiveTypeWrapper.DOUBLE);
+ }
+
+ internal void PushExtendedDouble()
+ {
+ PushHelper(VerifierTypeWrapper.ExtendedDouble);
+ }
+
+ internal void PopInt()
+ {
+ PopIntImpl(PopAnyType());
+ }
+
+ internal static void PopIntImpl(TypeWrapper type)
+ {
+ if (type != PrimitiveTypeWrapper.INT)
+ {
+ throw new VerifyError("Int expected on stack");
+ }
+ }
+
+ internal bool PopFloat()
+ {
+ TypeWrapper tw = PopAnyType();
+ PopFloatImpl(tw);
+ return tw == VerifierTypeWrapper.ExtendedFloat;
+ }
+
+ internal static void PopFloatImpl(TypeWrapper tw)
+ {
+ if (tw != PrimitiveTypeWrapper.FLOAT && tw != VerifierTypeWrapper.ExtendedFloat)
+ {
+ throw new VerifyError("Float expected on stack");
+ }
+ }
+
+ internal bool PopDouble()
+ {
+ TypeWrapper tw = PopAnyType();
+ PopDoubleImpl(tw);
+ return tw == VerifierTypeWrapper.ExtendedDouble;
+ }
+
+ internal static void PopDoubleImpl(TypeWrapper tw)
+ {
+ if (tw != PrimitiveTypeWrapper.DOUBLE && tw != VerifierTypeWrapper.ExtendedDouble)
+ {
+ throw new VerifyError("Double expected on stack");
+ }
+ }
+
+ internal void PopLong()
+ {
+ PopLongImpl(PopAnyType());
+ }
+
+ internal static void PopLongImpl(TypeWrapper tw)
+ {
+ if (tw != PrimitiveTypeWrapper.LONG)
+ {
+ throw new VerifyError("Long expected on stack");
+ }
+ }
+
+ internal TypeWrapper PopArrayType()
+ {
+ return PopArrayTypeImpl(PopAnyType());
+ }
+
+ internal static TypeWrapper PopArrayTypeImpl(TypeWrapper type)
+ {
+ if (!VerifierTypeWrapper.IsNullOrUnloadable(type) && type.ArrayRank == 0)
+ {
+ throw new VerifyError("Array reference expected on stack");
+ }
+ return type;
+ }
+
+ // null or an initialized object reference
+ internal TypeWrapper PopObjectType()
+ {
+ return PopObjectTypeImpl(PopType());
+ }
+
+ internal static TypeWrapper PopObjectTypeImpl(TypeWrapper type)
+ {
+ if (type.IsPrimitive || VerifierTypeWrapper.IsNew(type) || type == VerifierTypeWrapper.UninitializedThis)
+ {
+ throw new VerifyError("Expected object reference on stack");
+ }
+ return type;
+ }
+
+ // null or an initialized object reference derived from baseType (or baseType)
+ internal TypeWrapper PopObjectType(TypeWrapper baseType)
+ {
+ return PopObjectTypeImpl(baseType, PopObjectType());
+ }
+
+ internal static TypeWrapper PopObjectTypeImpl(TypeWrapper baseType, TypeWrapper type)
+ {
+ // HACK because of the way interfaces references works, if baseType
+ // is an interface or array of interfaces, any reference will be accepted
+ if (!baseType.IsUnloadable && !baseType.IsInterfaceOrInterfaceArray && !(type.IsUnloadable || type.IsAssignableTo(baseType)))
+ {
+ throw new VerifyError("Unexpected type " + type.Name + " where " + baseType.Name + " was expected");
+ }
+ return type;
+ }
+
+ internal TypeWrapper PeekType()
+ {
+ if (stackSize == 0)
+ {
+ throw new VerifyError("Unable to pop operand off an empty stack");
+ }
+ return stack[stackSize - 1];
+ }
+
+ internal void MultiPopAnyType(int count)
+ {
+ while (count-- != 0)
+ {
+ PopAnyType();
+ }
+ }
+
+ internal TypeWrapper PopFaultBlockException()
+ {
+ return stack[--stackSize];
+ }
+
+ internal TypeWrapper PopAnyType()
+ {
+ if (stackSize == 0)
+ {
+ throw new VerifyError("Unable to pop operand off an empty stack");
+ }
+ TypeWrapper type = stack[--stackSize];
+ if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
+ {
+ stackEnd++;
+ }
+ if (VerifierTypeWrapper.IsThis(type))
+ {
+ type = ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ if (VerifierTypeWrapper.IsFaultBlockException(type))
+ {
+ VerifierTypeWrapper.ClearFaultBlockException(type);
+ type = CoreClasses.java.lang.Throwable.Wrapper;
+ }
+ return type;
+ }
+
+ // NOTE this can *not* be used to pop double or long
+ internal TypeWrapper PopType()
+ {
+ return PopTypeImpl(PopAnyType());
+ }
+
+ internal static TypeWrapper PopTypeImpl(TypeWrapper type)
+ {
+ if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
+ {
+ throw new VerifyError("Attempt to split long or double on the stack");
+ }
+ return type;
+ }
+
+ // this will accept null, a primitive type of the specified type or an initialized reference of the
+ // specified type or derived from it
+ // NOTE this can also be used to pop double or long
+ internal TypeWrapper PopType(TypeWrapper baseType)
+ {
+ return PopTypeImpl(baseType, PopAnyType());
+ }
+
+ internal static TypeWrapper PopTypeImpl(TypeWrapper baseType, TypeWrapper type)
+ {
+ if (baseType.IsIntOnStackPrimitive)
+ {
+ baseType = PrimitiveTypeWrapper.INT;
+ }
+ if (VerifierTypeWrapper.IsNew(type) || type == VerifierTypeWrapper.UninitializedThis)
+ {
+ throw new VerifyError("Expecting to find object/array on stack");
+ }
+ if (type == baseType)
+ {
+ return type;
+ }
+ else if (type == VerifierTypeWrapper.ExtendedDouble && baseType == PrimitiveTypeWrapper.DOUBLE)
+ {
+ return type;
+ }
+ else if (type == VerifierTypeWrapper.ExtendedFloat && baseType == PrimitiveTypeWrapper.FLOAT)
+ {
+ return type;
+ }
+ else if (type.IsPrimitive || baseType.IsPrimitive)
+ {
+ // throw at the end of the method
+ }
+ else if (baseType == CoreClasses.java.lang.Object.Wrapper)
+ {
+ return type;
+ }
+ else if (type.IsUnloadable || baseType.IsUnloadable)
+ {
+ return type;
+ }
+ else if (baseType.IsInterfaceOrInterfaceArray)
+ {
+ // because of the way interfaces references works, if baseType
+ // is an interface or array of interfaces, any reference will be accepted
+ return type;
+ }
+ else if (type.IsAssignableTo(baseType))
+ {
+ return type;
+ }
+ else if (HasMissingBaseType(type) || HasMissingBaseType(baseType))
+ {
+ return type;
+ }
+ throw new VerifyError("Unexpected type " + type.Name + " where " + baseType.Name + " was expected");
+ }
+
+ private static bool HasMissingBaseType(TypeWrapper tw)
+ {
+#if IMPORTER
+ for (TypeWrapper baseTypeWrapper; (baseTypeWrapper = tw.BaseTypeWrapper) != null; tw = baseTypeWrapper)
+ {
+ if (baseTypeWrapper.IsUnloadable)
+ {
+ StaticCompiler.IssueMissingTypeMessage(tw.TypeAsBaseType.BaseType);
+ return true;
+ }
+ }
+#endif
+ return false;
+ }
+
+ internal int GetStackHeight()
+ {
+ return stackSize;
+ }
+
+ internal TypeWrapper GetStackSlot(int pos)
+ {
+ TypeWrapper tw = stack[stackSize - 1 - pos];
+ if (tw == VerifierTypeWrapper.ExtendedDouble)
+ {
+ tw = PrimitiveTypeWrapper.DOUBLE;
+ }
+ else if (tw == VerifierTypeWrapper.ExtendedFloat)
+ {
+ tw = PrimitiveTypeWrapper.FLOAT;
+ }
+ return tw;
+ }
+
+ internal TypeWrapper GetStackSlotEx(int pos)
+ {
+ return stack[stackSize - 1 - pos];
+ }
+
+ internal TypeWrapper GetStackByIndex(int index)
+ {
+ return stack[index];
+ }
+
+ private void PushHelper(TypeWrapper type)
+ {
+ if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
+ {
+ stackEnd--;
+ }
+ if (stackSize >= stackEnd)
+ {
+ throw new VerifyError("Stack overflow");
+ }
+ StackCopyOnWrite();
+ stack[stackSize++] = type;
+ }
+
+ internal void MarkInitialized(TypeWrapper type, TypeWrapper initType, int instructionIndex)
+ {
+ System.Diagnostics.Debug.Assert(type != null && initType != null);
+
+ for (int i = 0; i < locals.Length; i++)
+ {
+ if (locals[i] == type)
+ {
+ LocalsCopyOnWrite();
+ locals[i] = initType;
+ }
+ }
+ for (int i = 0; i < stackSize; i++)
+ {
+ if (stack[i] == type)
+ {
+ StackCopyOnWrite();
+ stack[i] = initType;
+ }
+ }
+ }
+
+ private void StackCopyOnWrite()
+ {
+ if ((flags & ShareFlags.Stack) != 0)
+ {
+ flags &= ~ShareFlags.Stack;
+ stack = (TypeWrapper[])stack.Clone();
+ }
+ }
+
+ private void LocalsCopyOnWrite()
+ {
+ if ((flags & ShareFlags.Locals) != 0)
+ {
+ flags &= ~ShareFlags.Locals;
+ locals = (TypeWrapper[])locals.Clone();
+ }
+ }
+
+ internal void DumpLocals()
+ {
+ Console.Write("// ");
+ string sep = "";
+ for (int i = 0; i < locals.Length; i++)
+ {
+ Console.Write(sep);
+ Console.Write(locals[i]);
+ sep = ", ";
+ }
+ Console.WriteLine();
+ }
+
+ internal void DumpStack()
+ {
+ Console.Write("// ");
+ string sep = "";
+ for (int i = 0; i < stackSize; i++)
+ {
+ Console.Write(sep);
+ Console.Write(stack[i]);
+ sep = ", ";
+ }
+ Console.WriteLine();
+ }
+
+ internal void ClearFaultBlockException()
+ {
+ if (VerifierTypeWrapper.IsFaultBlockException(stack[0]))
+ {
+ StackCopyOnWrite();
+ changed = true;
+ stack[0] = CoreClasses.java.lang.Throwable.Wrapper;
+ }
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs
index 49eeeabe52..57ab6e7c8f 100644
--- a/src/IKVM.Runtime/JNI/JNIEnv.cs
+++ b/src/IKVM.Runtime/JNI/JNIEnv.cs
@@ -29,7 +29,7 @@ Jeroen Frijters
using System.Runtime.InteropServices;
using IKVM.ByteCode.Text;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Runtime.JNI
{
diff --git a/src/IKVM.Runtime/JNI/JNIFrame.cs b/src/IKVM.Runtime/JNI/JNIFrame.cs
index efedfb7bc9..da8e8917c6 100644
--- a/src/IKVM.Runtime/JNI/JNIFrame.cs
+++ b/src/IKVM.Runtime/JNI/JNIFrame.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Diagnostics;
using System.Text;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Runtime.JNI
{
diff --git a/src/IKVM.Runtime/JNI/JNINativeLoader.cs b/src/IKVM.Runtime/JNI/JNINativeLoader.cs
index 6fa610bb11..e8c5be14b4 100644
--- a/src/IKVM.Runtime/JNI/JNINativeLoader.cs
+++ b/src/IKVM.Runtime/JNI/JNINativeLoader.cs
@@ -26,7 +26,7 @@ Jeroen Frijters
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Runtime.JNI
{
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs b/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs
index 25787ade5d..d35fd31e39 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.ikvm.@internal
{
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AppDomainAssemblyClassLoader.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AppDomainAssemblyClassLoader.cs
index f43411b02b..a410f915d7 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AppDomainAssemblyClassLoader.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AppDomainAssemblyClassLoader.cs
@@ -39,7 +39,7 @@ static class AppDomainAssemblyClassLoader
///
static object LoadClassFromAssembly(Assembly assembly, string className)
{
- return assembly.IsDynamic == false ? (Internal.AssemblyClassLoader.FromAssembly(assembly).DoLoad(className)?.ClassObject) : null;
+ return assembly.IsDynamic == false ? (IKVM.Runtime.AssemblyClassLoader.FromAssembly(assembly).DoLoad(className)?.ClassObject) : null;
}
///
@@ -68,14 +68,14 @@ static object LoadClassFromAssembly(Assembly assembly, string className)
///
static IEnumerable FindResources(string name)
{
- var done = new HashSet();
+ var done = new HashSet();
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
if (asm.IsDynamic)
continue;
- var acl = Internal.AssemblyClassLoader.FromAssembly(asm);
+ var acl = IKVM.Runtime.AssemblyClassLoader.FromAssembly(asm);
if (done.Add(acl))
foreach (var url in acl.FindResources(name))
yield return url;
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs
index 97484049a0..91c588de59 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs
@@ -24,11 +24,11 @@ Jeroen Frijters
using System;
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Lang;
-using AssemblyClassLoader_ = IKVM.Internal.AssemblyClassLoader;
+using AssemblyClassLoader_ = IKVM.Runtime.AssemblyClassLoader;
namespace IKVM.Java.Externs.ikvm.runtime
{
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/GenericClassLoader.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/GenericClassLoader.cs
index cbc9d2ed5d..63b2688df2 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/GenericClassLoader.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/GenericClassLoader.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.ikvm.runtime
{
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs
index 3de245b6f7..0c74746789 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Launcher.cs
@@ -2,7 +2,7 @@
using System.Collections;
using System.Collections.Generic;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.ikvm.runtime
{
@@ -32,7 +32,7 @@ public static int run(Type main, string[] args, string jvmArgPrefix, global::jav
// statically compiled entry points need to be explicitly added to the classpath
// this is sort of a hack and should be removed with a better class loader hierarchy
if (main != null && main.Assembly.IsDynamic == false)
- ClassLoaderWrapper.GetBootstrapClassLoader().AddDelegate(IKVM.Internal.AssemblyClassLoader.FromAssembly(main.Assembly));
+ ClassLoaderWrapper.GetBootstrapClassLoader().AddDelegate(IKVM.Runtime.AssemblyClassLoader.FromAssembly(main.Assembly));
// copy properties to a CLR type
var p = new Dictionary();
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs
index 1af2fabbad..7971d0a24c 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Startup.cs
@@ -1,6 +1,6 @@
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.ikvm.runtime
{
@@ -13,7 +13,7 @@ static class Startup
public static void addBootClassPathAssembly(Assembly asm)
{
- ClassLoaderWrapper.GetBootstrapClassLoader().AddDelegate(IKVM.Internal.AssemblyClassLoader.FromAssembly(asm));
+ ClassLoaderWrapper.GetBootstrapClassLoader().AddDelegate(IKVM.Runtime.AssemblyClassLoader.FromAssembly(asm));
}
}
diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs
index 2484f89224..eb2eae7ba9 100644
--- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs
+++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/Util.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Reflection.Emit;
using IKVM.Attributes;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
diff --git a/src/IKVM.Runtime/Java/Externs/java/io/FileDescriptor.cs b/src/IKVM.Runtime/Java/Externs/java/io/FileDescriptor.cs
index b9492ced03..bf991ab0d1 100644
--- a/src/IKVM.Runtime/Java/Externs/java/io/FileDescriptor.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/io/FileDescriptor.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Runtime.InteropServices;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Io;
diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs
index bbfe169003..8a109a27ee 100644
--- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs
@@ -26,7 +26,7 @@ Jeroen Frijters
#if !NO_REF_EMIT
using System.Reflection.Emit;
#endif
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
namespace IKVM.Java.Externs.java.io
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs
index 0ab3acb4c4..2c37d0fca1 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System;
using System.Collections.Generic;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Lang;
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.NativeLibrary.cs b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.NativeLibrary.cs
index df31015381..046276891b 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.NativeLibrary.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.NativeLibrary.cs
@@ -28,7 +28,7 @@ Jeroen Frijters
using System.Security;
using System.Threading;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime.JNI;
namespace IKVM.Java.Externs.java.lang
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs
index 6e015d5948..5fe038934d 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Linq;
using IKVM.ByteCode.Reading;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs
index f6c6927df5..f540ef183d 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/Package.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.IO;
using System.Threading;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Vfs;
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs
index bd1ffa5d6a..6a1e42df13 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs
@@ -27,7 +27,7 @@ Jeroen Frijters
using System.Diagnostics;
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Thread.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Thread.cs
index 4915057859..3460cb8a6f 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/Thread.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/Thread.cs
@@ -27,7 +27,7 @@ Jeroen Frijters
using System.Diagnostics;
using System.Threading;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Lang;
using IKVM.Runtime.Util.Java.Security;
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/DirectMethodHandle.cs b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/DirectMethodHandle.cs
index 887cbcb46c..686952683f 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/DirectMethodHandle.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/DirectMethodHandle.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.invoke
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs
index ad387a8476..c4e3f4f7ef 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/invoke/MethodHandleNatives.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Reflection;
using System.Threading;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.invoke
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/ref/Reference.cs b/src/IKVM.Runtime/Java/Externs/java/lang/ref/Reference.cs
index 1727d62954..c8abd2d2cd 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/ref/Reference.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/ref/Reference.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.@ref
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs
index 615de07b7b..1184c4bcc1 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Array.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.reflect
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs
index bf45b93b4d..fe4ffd720f 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System.Collections.Generic;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.reflect
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs
index f142fd9236..04685ebff4 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.reflect
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Method.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Method.cs
index 40c49a19df..78cd4152b9 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Method.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Method.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.reflect
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs
index 2f3f9038fa..587c44e168 100644
--- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Proxy.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.lang.reflect
{
diff --git a/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs b/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs
index a040a044d5..5e852b5d9c 100644
--- a/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/net/PlainDatagramSocketImpl.cs
@@ -8,7 +8,7 @@
using System.Reflection;
using System.Runtime.InteropServices;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Io;
using IKVM.Runtime.Util.Java.Net;
diff --git a/src/IKVM.Runtime/Java/Externs/java/net/PlainSocketImpl.cs b/src/IKVM.Runtime/Java/Externs/java/net/PlainSocketImpl.cs
index 400fe4f31e..bcf5154541 100644
--- a/src/IKVM.Runtime/Java/Externs/java/net/PlainSocketImpl.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/net/PlainSocketImpl.cs
@@ -7,7 +7,7 @@
using System.Reflection;
using System.Runtime.InteropServices;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Io;
using IKVM.Runtime.Util.Java.Net;
diff --git a/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs b/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs
index 6607cd01a0..5860b942c1 100644
--- a/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs
+++ b/src/IKVM.Runtime/Java/Externs/java/security/AccessController.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Collections.Generic;
using System.Diagnostics;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.java.security
{
diff --git a/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs b/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs
index 8808763f83..0a024e109a 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.sun.invoke.util
{
diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/MiscHelper.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/MiscHelper.cs
index 52fd97a0c9..f4e76e8e2c 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/misc/MiscHelper.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/misc/MiscHelper.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
*/
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Java.Externs.sun.misc
{
diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs
index 665c7795f0..5d0ce6d5a5 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs
@@ -9,7 +9,7 @@
using System.Threading;
using IKVM.ByteCode.Reading;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
namespace IKVM.Java.Externs.sun.misc
diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs
index 2d0473d327..cd70ad3984 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System;
using System.Diagnostics;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
namespace IKVM.Java.Externs.sun.misc
diff --git a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs
index 7f32edadad..a91005362c 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.IO;
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
#if NETCOREAPP
diff --git a/src/IKVM.Runtime/Java/Externs/sun/nio/ch/Net.cs b/src/IKVM.Runtime/Java/Externs/sun/nio/ch/Net.cs
index 11f2832e4a..24a7ae3615 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/nio/ch/Net.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/nio/ch/Net.cs
@@ -6,7 +6,7 @@
using System.Runtime.InteropServices;
using System.Threading.Tasks;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Io;
using IKVM.Runtime.Util.Java.Net;
diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/IReflectionException.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/IReflectionException.cs
index 67510beb59..7c874fd747 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/reflect/IReflectionException.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/IReflectionException.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if !FIRST_PASS
diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs
index a91f57a5f0..c5e3b63389 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/Reflection.cs
@@ -28,7 +28,7 @@ Jeroen Frijters
using System.Runtime.CompilerServices;
using IKVM.Attributes;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
namespace IKVM.Java.Externs.sun.reflect
diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs
index ce8aaf7aab..857d822bd7 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs
@@ -31,7 +31,7 @@ Jeroen Frijters
using System.Runtime.Serialization;
using System.Security;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Io;
using IKVM.Runtime.Accessors.Java.Lang;
diff --git a/src/IKVM.Runtime/Java/Externs/sun/util/locale/provider/JRELocaleProviderAdapter.cs b/src/IKVM.Runtime/Java/Externs/sun/util/locale/provider/JRELocaleProviderAdapter.cs
index 61336cbcf0..f378403ac8 100644
--- a/src/IKVM.Runtime/Java/Externs/sun/util/locale/provider/JRELocaleProviderAdapter.cs
+++ b/src/IKVM.Runtime/Java/Externs/sun/util/locale/provider/JRELocaleProviderAdapter.cs
@@ -28,7 +28,7 @@ static class JRELocaleProviderAdapter
// the Java implementation is redirected via map.xml
internal static bool isNonENLangSupported()
{
- return IKVM.Internal.ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast("sun.text.resources.nl.FormatData_nl") != null;
+ return IKVM.Runtime.ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast("sun.text.resources.nl.FormatData_nl") != null;
}
}
diff --git a/src/IKVM.Runtime/JsrInliner.cs b/src/IKVM.Runtime/JsrInliner.cs
index cea7484ae2..314f1fdbbd 100644
--- a/src/IKVM.Runtime/JsrInliner.cs
+++ b/src/IKVM.Runtime/JsrInliner.cs
@@ -23,13 +23,15 @@ Jeroen Frijters
*/
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
-namespace IKVM.Internal
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
+
+namespace IKVM.Runtime
{
- sealed class JsrInliner
+
+ sealed class JsrInliner
{
+
private ClassFile.Method.Instruction[] codeCopy;
private int codeLength;
private InstructionFlags[] flags;
diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs
index 8f3dc0b674..e942e23cdb 100644
--- a/src/IKVM.Runtime/LambdaMetafactory.cs
+++ b/src/IKVM.Runtime/LambdaMetafactory.cs
@@ -25,9 +25,7 @@ Jeroen Frijters
using System.Collections.Generic;
using System.Diagnostics;
-using IKVM.Attributes;
using IKVM.ByteCode;
-using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
@@ -41,7 +39,7 @@ Jeroen Frijters
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class LambdaMetafactory
@@ -1075,4 +1073,5 @@ private static bool HasUnloadable(TypeWrapper[] wrappers)
return false;
}
}
+
}
diff --git a/src/IKVM.Runtime/Launcher.cs b/src/IKVM.Runtime/Launcher.cs
index 6f5836624e..01d0058a01 100644
--- a/src/IKVM.Runtime/Launcher.cs
+++ b/src/IKVM.Runtime/Launcher.cs
@@ -13,7 +13,7 @@
using System.Threading;
using IKVM.Attributes;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime.Accessors.Ikvm.Internal;
using IKVM.Runtime.Accessors.Java.Lang;
using IKVM.Runtime.Accessors.Java.Lang.Reflect;
diff --git a/src/IKVM.Runtime/LoadMode.cs b/src/IKVM.Runtime/LoadMode.cs
index a9efa34006..582b3b1f35 100644
--- a/src/IKVM.Runtime/LoadMode.cs
+++ b/src/IKVM.Runtime/LoadMode.cs
@@ -23,16 +23,7 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-using Type = IKVM.Reflection.Type;
-using ProtectionDomain = System.Object;
-#else
-#endif
-
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
[Flags]
diff --git a/src/IKVM.Runtime/LocalVar.cs b/src/IKVM.Runtime/LocalVar.cs
new file mode 100644
index 0000000000..c68834affe
--- /dev/null
+++ b/src/IKVM.Runtime/LocalVar.cs
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2002-2010 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+namespace IKVM.Runtime
+{
+
+ sealed class LocalVar
+ {
+
+ internal bool isArg;
+ internal int local;
+ internal TypeWrapper type;
+ internal CodeEmitterLocal builder;
+ // used to emit debugging info, only available if ClassLoaderWrapper.EmitDebugInfo is true
+ internal string name;
+ internal int start_pc;
+ internal int end_pc;
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/LocalVarInfo.cs b/src/IKVM.Runtime/LocalVarInfo.cs
new file mode 100644
index 0000000000..308183e257
--- /dev/null
+++ b/src/IKVM.Runtime/LocalVarInfo.cs
@@ -0,0 +1,627 @@
+/*
+ Copyright (C) 2002-2010 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
+using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry;
+
+namespace IKVM.Runtime
+{
+
+ struct LocalVarInfo
+ {
+
+ private readonly LocalVar[/*instructionIndex*/] localVars;
+ private readonly LocalVar[/*instructionIndex*/][/*localIndex*/] invokespecialLocalVars;
+ private readonly LocalVar[/*index*/] allLocalVars;
+
+ internal LocalVarInfo(CodeInfo ma, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, MethodWrapper mw, ClassLoaderWrapper classLoader)
+ {
+ Dictionary[] localStoreReaders = FindLocalVariables(ma, mw, classFile, method);
+
+ // now that we've done the code flow analysis, we can do a liveness analysis on the local variables
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ Dictionary localByStoreSite = new Dictionary();
+ List locals = new List();
+ for (int i = 0; i < localStoreReaders.Length; i++)
+ {
+ if (localStoreReaders[i] != null)
+ {
+ VisitLocalLoads(ma, method, locals, localByStoreSite, localStoreReaders[i], i, classLoader.EmitDebugInfo);
+ }
+ }
+ Dictionary forwarders = new Dictionary();
+ if (classLoader.EmitDebugInfo)
+ {
+ InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(ma, method.Instructions, exceptions, 0, false);
+ // if we're emitting debug info, we need to keep dead stores as well...
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if ((flags[i] & InstructionFlags.Reachable) != 0
+ && IsStoreLocal(instructions[i].NormalizedOpCode))
+ {
+ if (!localByStoreSite.ContainsKey(MakeKey(i, instructions[i].NormalizedArg1)))
+ {
+ LocalVar v = new LocalVar();
+ v.local = instructions[i].NormalizedArg1;
+ v.type = ma.GetStackTypeWrapper(i, 0);
+ FindLvtEntry(v, method, i);
+ locals.Add(v);
+ localByStoreSite.Add(MakeKey(i, v.local), v);
+ }
+ }
+ }
+ // to make the debugging experience better, we have to trust the
+ // LocalVariableTable (unless it's clearly bogus) and merge locals
+ // together that are the same according to the LVT
+ for (int i = 0; i < locals.Count - 1; i++)
+ {
+ for (int j = i + 1; j < locals.Count; j++)
+ {
+ LocalVar v1 = (LocalVar)locals[i];
+ LocalVar v2 = (LocalVar)locals[j];
+ if (v1.name != null && v1.name == v2.name && v1.start_pc == v2.start_pc && v1.end_pc == v2.end_pc)
+ {
+ // we can only merge if the resulting type is valid (this protects against incorrect
+ // LVT data, but is also needed for constructors, where the uninitialized this is a different
+ // type from the initialized this)
+ TypeWrapper tw = InstructionState.FindCommonBaseType(v1.type, v2.type);
+ if (tw != VerifierTypeWrapper.Invalid)
+ {
+ v1.isArg |= v2.isArg;
+ v1.type = tw;
+ forwarders.Add(v2, v1);
+ locals.RemoveAt(j);
+ j--;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i < locals.Count - 1; i++)
+ {
+ for (int j = i + 1; j < locals.Count; j++)
+ {
+ LocalVar v1 = (LocalVar)locals[i];
+ LocalVar v2 = (LocalVar)locals[j];
+ // if the two locals are the same, we merge them, this is a small
+ // optimization, it should *not* be required for correctness.
+ if (v1.local == v2.local && v1.type == v2.type)
+ {
+ v1.isArg |= v2.isArg;
+ forwarders.Add(v2, v1);
+ locals.RemoveAt(j);
+ j--;
+ }
+ }
+ }
+ }
+ invokespecialLocalVars = new LocalVar[instructions.Length][];
+ localVars = new LocalVar[instructions.Length];
+ for (int i = 0; i < localVars.Length; i++)
+ {
+ LocalVar v = null;
+ if (localStoreReaders[i] != null)
+ {
+ Debug.Assert(IsLoadLocal(instructions[i].NormalizedOpCode));
+ // lame way to look up the local variable for a load
+ // (by indirecting through a corresponding store)
+ foreach (int store in localStoreReaders[i].Keys)
+ {
+ v = localByStoreSite[MakeKey(store, instructions[i].NormalizedArg1)];
+ break;
+ }
+ }
+ else
+ {
+ if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial || instructions[i].NormalizedOpCode == NormalizedByteCode.__dynamic_invokespecial)
+ {
+ invokespecialLocalVars[i] = new LocalVar[method.MaxLocals];
+ for (int j = 0; j < invokespecialLocalVars[i].Length; j++)
+ {
+ localByStoreSite.TryGetValue(MakeKey(i, j), out invokespecialLocalVars[i][j]);
+ }
+ }
+ else
+ {
+ localByStoreSite.TryGetValue(MakeKey(i, instructions[i].NormalizedArg1), out v);
+ }
+ }
+ if (v != null)
+ {
+ LocalVar fwd;
+ if (forwarders.TryGetValue(v, out fwd))
+ {
+ v = fwd;
+ }
+ localVars[i] = v;
+ }
+ }
+ this.allLocalVars = locals.ToArray();
+ }
+
+ private static void FindLvtEntry(LocalVar lv, ClassFile.Method method, int instructionIndex)
+ {
+ ClassFile.Method.LocalVariableTableEntry[] lvt = method.LocalVariableTableAttribute;
+ if (lvt != null)
+ {
+ int pc = method.Instructions[instructionIndex].PC;
+ int nextPC = method.Instructions[instructionIndex + 1].PC;
+ bool isStore = IsStoreLocal(method.Instructions[instructionIndex].NormalizedOpCode);
+ foreach (ClassFile.Method.LocalVariableTableEntry e in lvt)
+ {
+ // TODO validate the contents of the LVT entry
+ if (e.index == lv.local &&
+ (e.start_pc <= pc || (e.start_pc == nextPC && isStore)) &&
+ e.start_pc + e.length > pc)
+ {
+ lv.name = e.name;
+ lv.start_pc = e.start_pc;
+ lv.end_pc = e.start_pc + e.length;
+ break;
+ }
+ }
+ }
+ }
+
+ // NOTE for dead stores, this returns null
+ internal LocalVar GetLocalVar(int instructionIndex)
+ {
+ return localVars[instructionIndex];
+ }
+
+ internal LocalVar[] GetLocalVarsForInvokeSpecial(int instructionIndex)
+ {
+ return invokespecialLocalVars[instructionIndex];
+ }
+
+ internal LocalVar[] GetAllLocalVars()
+ {
+ return allLocalVars;
+ }
+
+ private static bool IsLoadLocal(NormalizedByteCode bc)
+ {
+ return bc == NormalizedByteCode.__aload ||
+ bc == NormalizedByteCode.__iload ||
+ bc == NormalizedByteCode.__lload ||
+ bc == NormalizedByteCode.__fload ||
+ bc == NormalizedByteCode.__dload ||
+ bc == NormalizedByteCode.__iinc ||
+ bc == NormalizedByteCode.__ret;
+ }
+
+ private static bool IsStoreLocal(NormalizedByteCode bc)
+ {
+ return bc == NormalizedByteCode.__astore ||
+ bc == NormalizedByteCode.__istore ||
+ bc == NormalizedByteCode.__lstore ||
+ bc == NormalizedByteCode.__fstore ||
+ bc == NormalizedByteCode.__dstore;
+ }
+
+ struct FindLocalVarState
+ {
+ internal bool changed;
+ internal FindLocalVarStoreSite[] sites;
+
+ internal void Store(int instructionIndex, int localIndex)
+ {
+ if (sites[localIndex].Count == 1 && sites[localIndex][0] == instructionIndex)
+ {
+ return;
+ }
+ sites = (FindLocalVarStoreSite[])sites.Clone();
+ sites[localIndex] = new FindLocalVarStoreSite();
+ sites[localIndex].Add(instructionIndex);
+ }
+
+ internal void Merge(FindLocalVarState state)
+ {
+ if (sites == null)
+ {
+ sites = state.sites;
+ changed = true;
+ }
+ else
+ {
+ bool dirty = true;
+ for (int i = 0; i < sites.Length; i++)
+ {
+ for (int j = 0; j < state.sites[i].Count; j++)
+ {
+ if (!sites[i].Contains(state.sites[i][j]))
+ {
+ if (dirty)
+ {
+ dirty = false;
+ sites = (FindLocalVarStoreSite[])sites.Clone();
+ }
+ sites[i].Add(state.sites[i][j]);
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+
+ internal FindLocalVarState Copy()
+ {
+ FindLocalVarState copy = new FindLocalVarState();
+ copy.sites = sites;
+ return copy;
+ }
+
+ public override string ToString()
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ if (sites != null)
+ {
+ foreach (FindLocalVarStoreSite site in sites)
+ {
+ sb.Append('[');
+ for (int i = 0; i < site.Count; i++)
+ {
+ sb.AppendFormat("{0}, ", site[i]);
+ }
+ sb.Append(']');
+ }
+ }
+ return sb.ToString();
+ }
+ }
+
+ struct FindLocalVarStoreSite
+ {
+ private int[] data;
+
+ internal bool Contains(int instructionIndex)
+ {
+ if (data != null)
+ {
+ for (int i = 0; i < data.Length; i++)
+ {
+ if (data[i] == instructionIndex)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ internal void Add(int instructionIndex)
+ {
+ if (data == null)
+ {
+ data = new int[] { instructionIndex };
+ }
+ else
+ {
+ data = ArrayUtil.Concat(data, instructionIndex);
+ }
+ }
+
+ internal int this[int index]
+ {
+ get { return data[index]; }
+ }
+
+ internal int Count
+ {
+ get { return data == null ? 0 : data.Length; }
+ }
+ }
+
+ private static Dictionary[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
+ {
+ FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
+ state[0].changed = true;
+ state[0].sites = new FindLocalVarStoreSite[method.MaxLocals];
+ TypeWrapper[] parameters = mw.GetParameters();
+ int argpos = 0;
+ if (!mw.IsStatic)
+ {
+ state[0].sites[argpos++].Add(-1);
+ }
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ state[0].sites[argpos++].Add(-1);
+ if (parameters[i].IsWidePrimitive)
+ {
+ argpos++;
+ }
+ }
+ return FindLocalVariablesImpl(codeInfo, classFile, method, state);
+ }
+
+ private static Dictionary[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
+ {
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ ExceptionTableEntry[] exceptions = method.ExceptionTable;
+ int maxLocals = method.MaxLocals;
+ Dictionary[] localStoreReaders = new Dictionary[instructions.Length];
+ bool done = false;
+
+ while (!done)
+ {
+ done = true;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if (state[i].changed)
+ {
+ done = false;
+ state[i].changed = false;
+
+ FindLocalVarState curr = state[i].Copy();
+
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
+ {
+ state[exceptions[j].handlerIndex].Merge(curr);
+ }
+ }
+
+ if (IsLoadLocal(instructions[i].NormalizedOpCode)
+ && (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
+ {
+ if (localStoreReaders[i] == null)
+ {
+ localStoreReaders[i] = new Dictionary();
+ }
+ for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
+ {
+ localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
+ }
+ }
+
+ if (IsStoreLocal(instructions[i].NormalizedOpCode)
+ && (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
+ {
+ curr.Store(i, instructions[i].NormalizedArg1);
+ // if this is a store at the end of an exception block,
+ // we need to propagate the new state to the exception handler
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (exceptions[j].endIndex == i + 1)
+ {
+ state[exceptions[j].handlerIndex].Merge(curr);
+ }
+ }
+ }
+
+ if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
+ {
+ ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
+ if (ReferenceEquals(cpi.Name, StringConstants.INIT))
+ {
+ TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
+ // after we've invoked the constructor, the uninitialized references
+ // are now initialized
+ if (type == VerifierTypeWrapper.UninitializedThis
+ || VerifierTypeWrapper.IsNew(type))
+ {
+ for (int j = 0; j < maxLocals; j++)
+ {
+ if (codeInfo.GetLocalTypeWrapper(i, j) == type)
+ {
+ curr.Store(i, j);
+ }
+ }
+ }
+ }
+ }
+ else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
+ {
+ int handler = instructions[i].HandlerIndex;
+
+ // Normally a store at the end of a try block doesn't affect the handler block,
+ // but in the case of a finally handler it does, so we need to make sure that
+ // we merge here in case the try block ended with a store.
+ state[handler].Merge(curr);
+
+ // Now we recursively analyse the handler and afterwards merge the endfault locations back to us
+ FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
+ handlerState[handler].Merge(curr);
+ curr = new FindLocalVarState();
+ FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);
+
+ // Merge back to the target of our __goto_finally
+ for (int j = 0; j < handlerState.Length; j++)
+ {
+ if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow
+ && codeInfo.HasState(j)
+ && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
+ && ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
+ {
+ curr.Merge(handlerState[j]);
+ }
+ }
+ }
+
+ switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Switch:
+ {
+ for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
+ {
+ state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
+ }
+ state[instructions[i].DefaultTarget].Merge(curr);
+ break;
+ }
+ case ByteCodeFlowControl.Branch:
+ state[instructions[i].TargetIndex].Merge(curr);
+ break;
+ case ByteCodeFlowControl.CondBranch:
+ state[instructions[i].TargetIndex].Merge(curr);
+ state[i + 1].Merge(curr);
+ break;
+ case ByteCodeFlowControl.Return:
+ case ByteCodeFlowControl.Throw:
+ break;
+ case ByteCodeFlowControl.Next:
+ state[i + 1].Merge(curr);
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+ }
+ return localStoreReaders;
+ }
+
+ private static void VisitLocalLoads(CodeInfo codeInfo, ClassFile.Method method, List locals, Dictionary localByStoreSite, Dictionary storeSites, int instructionIndex, bool debug)
+ {
+ Debug.Assert(IsLoadLocal(method.Instructions[instructionIndex].NormalizedOpCode));
+ LocalVar local = null;
+ TypeWrapper type = VerifierTypeWrapper.Null;
+ int localIndex = method.Instructions[instructionIndex].NormalizedArg1;
+ bool isArg = false;
+ foreach (int store in storeSites.Keys)
+ {
+ if (store == -1)
+ {
+ // it's a method argument, it has no initial store, but the type is simply the parameter type
+ type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(0, localIndex));
+ isArg = true;
+ }
+ else
+ {
+ if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__invokespecial)
+ {
+ type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(store + 1, localIndex));
+ }
+ else if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__static_error)
+ {
+ // it's an __invokespecial that turned into a __static_error
+ // (since a __static_error doesn't continue, we don't need to set type)
+ }
+ else
+ {
+ Debug.Assert(IsStoreLocal(method.Instructions[store].NormalizedOpCode));
+ type = InstructionState.FindCommonBaseType(type, codeInfo.GetStackTypeWrapper(store, 0));
+ }
+ }
+ // we can't have an invalid type, because that would have failed verification earlier
+ Debug.Assert(type != VerifierTypeWrapper.Invalid);
+
+ LocalVar l;
+ if (localByStoreSite.TryGetValue(MakeKey(store, localIndex), out l))
+ {
+ if (local == null)
+ {
+ local = l;
+ }
+ else if (local != l)
+ {
+ // If we've already defined a LocalVar and we find another one, then we merge them
+ // together.
+ // This happens for the following code fragment:
+ //
+ // int i = -1;
+ // try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
+ // try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
+ // System.out.println(i);
+ //
+ local = MergeLocals(locals, localByStoreSite, local, l);
+ }
+ }
+ }
+ if (local == null)
+ {
+ local = new LocalVar();
+ local.local = localIndex;
+ if (VerifierTypeWrapper.IsThis(type))
+ {
+ local.type = ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ else
+ {
+ local.type = type;
+ }
+ local.isArg = isArg;
+ if (debug)
+ {
+ FindLvtEntry(local, method, instructionIndex);
+ }
+ locals.Add(local);
+ }
+ else
+ {
+ local.isArg |= isArg;
+ local.type = InstructionState.FindCommonBaseType(local.type, type);
+ Debug.Assert(local.type != VerifierTypeWrapper.Invalid);
+ }
+ foreach (int store in storeSites.Keys)
+ {
+ LocalVar v;
+ if (!localByStoreSite.TryGetValue(MakeKey(store, localIndex), out v))
+ {
+ localByStoreSite[MakeKey(store, localIndex)] = local;
+ }
+ else if (v != local)
+ {
+ local = MergeLocals(locals, localByStoreSite, local, v);
+ }
+ }
+ }
+
+ private static long MakeKey(int i, int j)
+ {
+ return (((long)(uint)i) << 32) + (uint)j;
+ }
+
+ private static LocalVar MergeLocals(List locals, Dictionary localByStoreSite, LocalVar l1, LocalVar l2)
+ {
+ Debug.Assert(l1 != l2);
+ Debug.Assert(l1.local == l2.local);
+ for (int i = 0; i < locals.Count; i++)
+ {
+ if (locals[i] == l2)
+ {
+ locals.RemoveAt(i);
+ i--;
+ }
+ }
+ Dictionary temp = new Dictionary(localByStoreSite);
+ localByStoreSite.Clear();
+ foreach (KeyValuePair kv in temp)
+ {
+ localByStoreSite[kv.Key] = kv.Value == l2 ? l1 : kv.Value;
+ }
+ l1.isArg |= l2.isArg;
+ l1.type = InstructionState.FindCommonBaseType(l1.type, l2.type);
+ Debug.Assert(l1.type != VerifierTypeWrapper.Invalid);
+ return l1;
+ }
+ }
+
+}
diff --git a/src/IKVM.Runtime/LocalVars.cs b/src/IKVM.Runtime/LocalVars.cs
deleted file mode 100644
index 8294d5b04c..0000000000
--- a/src/IKVM.Runtime/LocalVars.cs
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- Copyright (C) 2002-2010 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-using IKVM.Internal;
-
-#if IMPORTER
-using IKVM.Reflection.Emit;
-using Type = IKVM.Reflection.Type;
-#else
-using System.Reflection.Emit;
-#endif
-
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
-using ExceptionTableEntry = IKVM.Internal.ClassFile.Method.ExceptionTableEntry;
-
-sealed class LocalVar
-{
- internal bool isArg;
- internal int local;
- internal TypeWrapper type;
- internal CodeEmitterLocal builder;
- // used to emit debugging info, only available if ClassLoaderWrapper.EmitDebugInfo is true
- internal string name;
- internal int start_pc;
- internal int end_pc;
-}
-
-struct LocalVarInfo
-{
- private readonly LocalVar[/*instructionIndex*/] localVars;
- private readonly LocalVar[/*instructionIndex*/][/*localIndex*/] invokespecialLocalVars;
- private readonly LocalVar[/*index*/] allLocalVars;
-
- internal LocalVarInfo(CodeInfo ma, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, MethodWrapper mw, ClassLoaderWrapper classLoader)
- {
- Dictionary[] localStoreReaders = FindLocalVariables(ma, mw, classFile, method);
-
- // now that we've done the code flow analysis, we can do a liveness analysis on the local variables
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- Dictionary localByStoreSite = new Dictionary();
- List locals = new List();
- for (int i = 0; i < localStoreReaders.Length; i++)
- {
- if (localStoreReaders[i] != null)
- {
- VisitLocalLoads(ma, method, locals, localByStoreSite, localStoreReaders[i], i, classLoader.EmitDebugInfo);
- }
- }
- Dictionary forwarders = new Dictionary();
- if (classLoader.EmitDebugInfo)
- {
- InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(ma, method.Instructions, exceptions, 0, false);
- // if we're emitting debug info, we need to keep dead stores as well...
- for (int i = 0; i < instructions.Length; i++)
- {
- if ((flags[i] & InstructionFlags.Reachable) != 0
- && IsStoreLocal(instructions[i].NormalizedOpCode))
- {
- if (!localByStoreSite.ContainsKey(MakeKey(i, instructions[i].NormalizedArg1)))
- {
- LocalVar v = new LocalVar();
- v.local = instructions[i].NormalizedArg1;
- v.type = ma.GetStackTypeWrapper(i, 0);
- FindLvtEntry(v, method, i);
- locals.Add(v);
- localByStoreSite.Add(MakeKey(i, v.local), v);
- }
- }
- }
- // to make the debugging experience better, we have to trust the
- // LocalVariableTable (unless it's clearly bogus) and merge locals
- // together that are the same according to the LVT
- for (int i = 0; i < locals.Count - 1; i++)
- {
- for (int j = i + 1; j < locals.Count; j++)
- {
- LocalVar v1 = (LocalVar)locals[i];
- LocalVar v2 = (LocalVar)locals[j];
- if (v1.name != null && v1.name == v2.name && v1.start_pc == v2.start_pc && v1.end_pc == v2.end_pc)
- {
- // we can only merge if the resulting type is valid (this protects against incorrect
- // LVT data, but is also needed for constructors, where the uninitialized this is a different
- // type from the initialized this)
- TypeWrapper tw = InstructionState.FindCommonBaseType(v1.type, v2.type);
- if (tw != VerifierTypeWrapper.Invalid)
- {
- v1.isArg |= v2.isArg;
- v1.type = tw;
- forwarders.Add(v2, v1);
- locals.RemoveAt(j);
- j--;
- }
- }
- }
- }
- }
- else
- {
- for (int i = 0; i < locals.Count - 1; i++)
- {
- for (int j = i + 1; j < locals.Count; j++)
- {
- LocalVar v1 = (LocalVar)locals[i];
- LocalVar v2 = (LocalVar)locals[j];
- // if the two locals are the same, we merge them, this is a small
- // optimization, it should *not* be required for correctness.
- if (v1.local == v2.local && v1.type == v2.type)
- {
- v1.isArg |= v2.isArg;
- forwarders.Add(v2, v1);
- locals.RemoveAt(j);
- j--;
- }
- }
- }
- }
- invokespecialLocalVars = new LocalVar[instructions.Length][];
- localVars = new LocalVar[instructions.Length];
- for (int i = 0; i < localVars.Length; i++)
- {
- LocalVar v = null;
- if (localStoreReaders[i] != null)
- {
- Debug.Assert(IsLoadLocal(instructions[i].NormalizedOpCode));
- // lame way to look up the local variable for a load
- // (by indirecting through a corresponding store)
- foreach (int store in localStoreReaders[i].Keys)
- {
- v = localByStoreSite[MakeKey(store, instructions[i].NormalizedArg1)];
- break;
- }
- }
- else
- {
- if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial || instructions[i].NormalizedOpCode == NormalizedByteCode.__dynamic_invokespecial)
- {
- invokespecialLocalVars[i] = new LocalVar[method.MaxLocals];
- for (int j = 0; j < invokespecialLocalVars[i].Length; j++)
- {
- localByStoreSite.TryGetValue(MakeKey(i, j), out invokespecialLocalVars[i][j]);
- }
- }
- else
- {
- localByStoreSite.TryGetValue(MakeKey(i, instructions[i].NormalizedArg1), out v);
- }
- }
- if (v != null)
- {
- LocalVar fwd;
- if (forwarders.TryGetValue(v, out fwd))
- {
- v = fwd;
- }
- localVars[i] = v;
- }
- }
- this.allLocalVars = locals.ToArray();
- }
-
- private static void FindLvtEntry(LocalVar lv, ClassFile.Method method, int instructionIndex)
- {
- ClassFile.Method.LocalVariableTableEntry[] lvt = method.LocalVariableTableAttribute;
- if (lvt != null)
- {
- int pc = method.Instructions[instructionIndex].PC;
- int nextPC = method.Instructions[instructionIndex + 1].PC;
- bool isStore = IsStoreLocal(method.Instructions[instructionIndex].NormalizedOpCode);
- foreach (ClassFile.Method.LocalVariableTableEntry e in lvt)
- {
- // TODO validate the contents of the LVT entry
- if (e.index == lv.local &&
- (e.start_pc <= pc || (e.start_pc == nextPC && isStore)) &&
- e.start_pc + e.length > pc)
- {
- lv.name = e.name;
- lv.start_pc = e.start_pc;
- lv.end_pc = e.start_pc + e.length;
- break;
- }
- }
- }
- }
-
- // NOTE for dead stores, this returns null
- internal LocalVar GetLocalVar(int instructionIndex)
- {
- return localVars[instructionIndex];
- }
-
- internal LocalVar[] GetLocalVarsForInvokeSpecial(int instructionIndex)
- {
- return invokespecialLocalVars[instructionIndex];
- }
-
- internal LocalVar[] GetAllLocalVars()
- {
- return allLocalVars;
- }
-
- private static bool IsLoadLocal(NormalizedByteCode bc)
- {
- return bc == NormalizedByteCode.__aload ||
- bc == NormalizedByteCode.__iload ||
- bc == NormalizedByteCode.__lload ||
- bc == NormalizedByteCode.__fload ||
- bc == NormalizedByteCode.__dload ||
- bc == NormalizedByteCode.__iinc ||
- bc == NormalizedByteCode.__ret;
- }
-
- private static bool IsStoreLocal(NormalizedByteCode bc)
- {
- return bc == NormalizedByteCode.__astore ||
- bc == NormalizedByteCode.__istore ||
- bc == NormalizedByteCode.__lstore ||
- bc == NormalizedByteCode.__fstore ||
- bc == NormalizedByteCode.__dstore;
- }
-
- struct FindLocalVarState
- {
- internal bool changed;
- internal FindLocalVarStoreSite[] sites;
-
- internal void Store(int instructionIndex, int localIndex)
- {
- if (sites[localIndex].Count == 1 && sites[localIndex][0] == instructionIndex)
- {
- return;
- }
- sites = (FindLocalVarStoreSite[])sites.Clone();
- sites[localIndex] = new FindLocalVarStoreSite();
- sites[localIndex].Add(instructionIndex);
- }
-
- internal void Merge(FindLocalVarState state)
- {
- if (sites == null)
- {
- sites = state.sites;
- changed = true;
- }
- else
- {
- bool dirty = true;
- for (int i = 0; i < sites.Length; i++)
- {
- for (int j = 0; j < state.sites[i].Count; j++)
- {
- if (!sites[i].Contains(state.sites[i][j]))
- {
- if (dirty)
- {
- dirty = false;
- sites = (FindLocalVarStoreSite[])sites.Clone();
- }
- sites[i].Add(state.sites[i][j]);
- changed = true;
- }
- }
- }
- }
- }
-
- internal FindLocalVarState Copy()
- {
- FindLocalVarState copy = new FindLocalVarState();
- copy.sites = sites;
- return copy;
- }
-
- public override string ToString()
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- if (sites != null)
- {
- foreach (FindLocalVarStoreSite site in sites)
- {
- sb.Append('[');
- for (int i = 0; i < site.Count; i++)
- {
- sb.AppendFormat("{0}, ", site[i]);
- }
- sb.Append(']');
- }
- }
- return sb.ToString();
- }
- }
-
- struct FindLocalVarStoreSite
- {
- private int[] data;
-
- internal bool Contains(int instructionIndex)
- {
- if (data != null)
- {
- for (int i = 0; i < data.Length; i++)
- {
- if (data[i] == instructionIndex)
- {
- return true;
- }
- }
- }
- return false;
- }
-
- internal void Add(int instructionIndex)
- {
- if (data == null)
- {
- data = new int[] { instructionIndex };
- }
- else
- {
- data = ArrayUtil.Concat(data, instructionIndex);
- }
- }
-
- internal int this[int index]
- {
- get { return data[index]; }
- }
-
- internal int Count
- {
- get { return data == null ? 0 : data.Length; }
- }
- }
-
- private static Dictionary[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
- {
- FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
- state[0].changed = true;
- state[0].sites = new FindLocalVarStoreSite[method.MaxLocals];
- TypeWrapper[] parameters = mw.GetParameters();
- int argpos = 0;
- if (!mw.IsStatic)
- {
- state[0].sites[argpos++].Add(-1);
- }
- for (int i = 0; i < parameters.Length; i++)
- {
- state[0].sites[argpos++].Add(-1);
- if (parameters[i].IsWidePrimitive)
- {
- argpos++;
- }
- }
- return FindLocalVariablesImpl(codeInfo, classFile, method, state);
- }
-
- private static Dictionary[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
- {
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- ExceptionTableEntry[] exceptions = method.ExceptionTable;
- int maxLocals = method.MaxLocals;
- Dictionary[] localStoreReaders = new Dictionary[instructions.Length];
- bool done = false;
-
- while (!done)
- {
- done = true;
- for (int i = 0; i < instructions.Length; i++)
- {
- if (state[i].changed)
- {
- done = false;
- state[i].changed = false;
-
- FindLocalVarState curr = state[i].Copy();
-
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
- {
- state[exceptions[j].handlerIndex].Merge(curr);
- }
- }
-
- if (IsLoadLocal(instructions[i].NormalizedOpCode)
- && (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
- {
- if (localStoreReaders[i] == null)
- {
- localStoreReaders[i] = new Dictionary();
- }
- for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
- {
- localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
- }
- }
-
- if (IsStoreLocal(instructions[i].NormalizedOpCode)
- && (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
- {
- curr.Store(i, instructions[i].NormalizedArg1);
- // if this is a store at the end of an exception block,
- // we need to propagate the new state to the exception handler
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (exceptions[j].endIndex == i + 1)
- {
- state[exceptions[j].handlerIndex].Merge(curr);
- }
- }
- }
-
- if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
- {
- ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
- if (ReferenceEquals(cpi.Name, StringConstants.INIT))
- {
- TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
- // after we've invoked the constructor, the uninitialized references
- // are now initialized
- if (type == VerifierTypeWrapper.UninitializedThis
- || VerifierTypeWrapper.IsNew(type))
- {
- for (int j = 0; j < maxLocals; j++)
- {
- if (codeInfo.GetLocalTypeWrapper(i, j) == type)
- {
- curr.Store(i, j);
- }
- }
- }
- }
- }
- else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
- {
- int handler = instructions[i].HandlerIndex;
-
- // Normally a store at the end of a try block doesn't affect the handler block,
- // but in the case of a finally handler it does, so we need to make sure that
- // we merge here in case the try block ended with a store.
- state[handler].Merge(curr);
-
- // Now we recursively analyse the handler and afterwards merge the endfault locations back to us
- FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
- handlerState[handler].Merge(curr);
- curr = new FindLocalVarState();
- FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);
-
- // Merge back to the target of our __goto_finally
- for (int j = 0; j < handlerState.Length; j++)
- {
- if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow
- && codeInfo.HasState(j)
- && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
- && ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
- {
- curr.Merge(handlerState[j]);
- }
- }
- }
-
- switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
- {
- case ByteCodeFlowControl.Switch:
- {
- for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
- {
- state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
- }
- state[instructions[i].DefaultTarget].Merge(curr);
- break;
- }
- case ByteCodeFlowControl.Branch:
- state[instructions[i].TargetIndex].Merge(curr);
- break;
- case ByteCodeFlowControl.CondBranch:
- state[instructions[i].TargetIndex].Merge(curr);
- state[i + 1].Merge(curr);
- break;
- case ByteCodeFlowControl.Return:
- case ByteCodeFlowControl.Throw:
- break;
- case ByteCodeFlowControl.Next:
- state[i + 1].Merge(curr);
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- }
- }
- return localStoreReaders;
- }
-
- private static void VisitLocalLoads(CodeInfo codeInfo, ClassFile.Method method, List locals, Dictionary localByStoreSite, Dictionary storeSites, int instructionIndex, bool debug)
- {
- Debug.Assert(IsLoadLocal(method.Instructions[instructionIndex].NormalizedOpCode));
- LocalVar local = null;
- TypeWrapper type = VerifierTypeWrapper.Null;
- int localIndex = method.Instructions[instructionIndex].NormalizedArg1;
- bool isArg = false;
- foreach (int store in storeSites.Keys)
- {
- if (store == -1)
- {
- // it's a method argument, it has no initial store, but the type is simply the parameter type
- type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(0, localIndex));
- isArg = true;
- }
- else
- {
- if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__invokespecial)
- {
- type = InstructionState.FindCommonBaseType(type, codeInfo.GetLocalTypeWrapper(store + 1, localIndex));
- }
- else if (method.Instructions[store].NormalizedOpCode == NormalizedByteCode.__static_error)
- {
- // it's an __invokespecial that turned into a __static_error
- // (since a __static_error doesn't continue, we don't need to set type)
- }
- else
- {
- Debug.Assert(IsStoreLocal(method.Instructions[store].NormalizedOpCode));
- type = InstructionState.FindCommonBaseType(type, codeInfo.GetStackTypeWrapper(store, 0));
- }
- }
- // we can't have an invalid type, because that would have failed verification earlier
- Debug.Assert(type != VerifierTypeWrapper.Invalid);
-
- LocalVar l;
- if (localByStoreSite.TryGetValue(MakeKey(store, localIndex), out l))
- {
- if (local == null)
- {
- local = l;
- }
- else if (local != l)
- {
- // If we've already defined a LocalVar and we find another one, then we merge them
- // together.
- // This happens for the following code fragment:
- //
- // int i = -1;
- // try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
- // try { i = 0; for(; ; ) System.out.println(i); } catch(Exception x) {}
- // System.out.println(i);
- //
- local = MergeLocals(locals, localByStoreSite, local, l);
- }
- }
- }
- if (local == null)
- {
- local = new LocalVar();
- local.local = localIndex;
- if (VerifierTypeWrapper.IsThis(type))
- {
- local.type = ((VerifierTypeWrapper)type).UnderlyingType;
- }
- else
- {
- local.type = type;
- }
- local.isArg = isArg;
- if (debug)
- {
- FindLvtEntry(local, method, instructionIndex);
- }
- locals.Add(local);
- }
- else
- {
- local.isArg |= isArg;
- local.type = InstructionState.FindCommonBaseType(local.type, type);
- Debug.Assert(local.type != VerifierTypeWrapper.Invalid);
- }
- foreach (int store in storeSites.Keys)
- {
- LocalVar v;
- if (!localByStoreSite.TryGetValue(MakeKey(store, localIndex), out v))
- {
- localByStoreSite[MakeKey(store, localIndex)] = local;
- }
- else if (v != local)
- {
- local = MergeLocals(locals, localByStoreSite, local, v);
- }
- }
- }
-
- private static long MakeKey(int i, int j)
- {
- return (((long)(uint)i) << 32) + (uint)j;
- }
-
- private static LocalVar MergeLocals(List locals, Dictionary localByStoreSite, LocalVar l1, LocalVar l2)
- {
- Debug.Assert(l1 != l2);
- Debug.Assert(l1.local == l2.local);
- for (int i = 0; i < locals.Count; i++)
- {
- if (locals[i] == l2)
- {
- locals.RemoveAt(i);
- i--;
- }
- }
- Dictionary temp = new Dictionary(localByStoreSite);
- localByStoreSite.Clear();
- foreach (KeyValuePair kv in temp)
- {
- localByStoreSite[kv.Key] = kv.Value == l2 ? l1 : kv.Value;
- }
- l1.isArg |= l2.isArg;
- l1.type = InstructionState.FindCommonBaseType(l1.type, l2.type);
- Debug.Assert(l1.type != VerifierTypeWrapper.Invalid);
- return l1;
- }
-}
diff --git a/src/IKVM.Runtime/MemberFlags.cs b/src/IKVM.Runtime/MemberFlags.cs
index d3d4269526..77efa0609f 100644
--- a/src/IKVM.Runtime/MemberFlags.cs
+++ b/src/IKVM.Runtime/MemberFlags.cs
@@ -23,7 +23,7 @@ Jeroen Frijters
*/
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
[Flags]
diff --git a/src/IKVM.Runtime/MemberWrapper.cs b/src/IKVM.Runtime/MemberWrapper.cs
index 157052b4f8..bba1b84753 100644
--- a/src/IKVM.Runtime/MemberWrapper.cs
+++ b/src/IKVM.Runtime/MemberWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Runtime.InteropServices;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -42,7 +41,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
abstract class MemberWrapper
diff --git a/src/IKVM.Runtime/MethodAnalyzer.cs b/src/IKVM.Runtime/MethodAnalyzer.cs
new file mode 100644
index 0000000000..00ef054b68
--- /dev/null
+++ b/src/IKVM.Runtime/MethodAnalyzer.cs
@@ -0,0 +1,3018 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+using IKVM.ByteCode;
+
+#if IMPORTER
+using IKVM.Tools.Importer;
+#endif
+
+using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry;
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
+
+namespace IKVM.Runtime
+{
+
+ sealed class MethodAnalyzer
+ {
+ private readonly static TypeWrapper ByteArrayType;
+ private readonly static TypeWrapper BooleanArrayType;
+ private readonly static TypeWrapper ShortArrayType;
+ private readonly static TypeWrapper CharArrayType;
+ private readonly static TypeWrapper IntArrayType;
+ private readonly static TypeWrapper FloatArrayType;
+ private readonly static TypeWrapper DoubleArrayType;
+ private readonly static TypeWrapper LongArrayType;
+ private readonly static TypeWrapper java_lang_ThreadDeath;
+ private readonly TypeWrapper host; // used to by Unsafe.defineAnonymousClass() to provide access to private members of the host
+ private readonly TypeWrapper wrapper;
+ private readonly MethodWrapper mw;
+ private readonly ClassFile classFile;
+ private readonly ClassFile.Method method;
+ private readonly ClassLoaderWrapper classLoader;
+ private readonly TypeWrapper thisType;
+ private readonly InstructionState[] state;
+ private List errorMessages;
+ private readonly Dictionary newTypes = new Dictionary();
+ private readonly Dictionary faultTypes = new Dictionary();
+
+ static MethodAnalyzer()
+ {
+ ByteArrayType = PrimitiveTypeWrapper.BYTE.MakeArrayType(1);
+ BooleanArrayType = PrimitiveTypeWrapper.BOOLEAN.MakeArrayType(1);
+ ShortArrayType = PrimitiveTypeWrapper.SHORT.MakeArrayType(1);
+ CharArrayType = PrimitiveTypeWrapper.CHAR.MakeArrayType(1);
+ IntArrayType = PrimitiveTypeWrapper.INT.MakeArrayType(1);
+ FloatArrayType = PrimitiveTypeWrapper.FLOAT.MakeArrayType(1);
+ DoubleArrayType = PrimitiveTypeWrapper.DOUBLE.MakeArrayType(1);
+ LongArrayType = PrimitiveTypeWrapper.LONG.MakeArrayType(1);
+ java_lang_ThreadDeath = ClassLoaderWrapper.LoadClassCritical("java.lang.ThreadDeath");
+ }
+
+ internal MethodAnalyzer(TypeWrapper host, TypeWrapper wrapper, MethodWrapper mw, ClassFile classFile, ClassFile.Method method, ClassLoaderWrapper classLoader)
+ {
+ if (method.VerifyError != null)
+ {
+ throw new VerifyError(method.VerifyError);
+ }
+
+ this.host = host;
+ this.wrapper = wrapper;
+ this.mw = mw;
+ this.classFile = classFile;
+ this.method = method;
+ this.classLoader = classLoader;
+ state = new InstructionState[method.Instructions.Length];
+
+ try
+ {
+ // ensure that exception blocks and handlers start and end at instruction boundaries
+ for (int i = 0; i < method.ExceptionTable.Length; i++)
+ {
+ int start = method.ExceptionTable[i].startIndex;
+ int end = method.ExceptionTable[i].endIndex;
+ int handler = method.ExceptionTable[i].handlerIndex;
+ if (start >= end || start == -1 || end == -1 || handler <= 0)
+ {
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ catch (IndexOutOfRangeException)
+ {
+ // TODO figure out if we should throw this during class loading
+ throw new ClassFormatError(string.Format("Illegal exception table (class: {0}, method: {1}, signature: {2}", classFile.Name, method.Name, method.Signature));
+ }
+
+ // start by computing the initial state, the stack is empty and the locals contain the arguments
+ state[0] = new InstructionState(method.MaxLocals, method.MaxStack);
+ int firstNonArgLocalIndex = 0;
+ if (!method.IsStatic)
+ {
+ thisType = VerifierTypeWrapper.MakeThis(wrapper);
+ // this reference. If we're a constructor, the this reference is uninitialized.
+ if (method.IsConstructor)
+ {
+ state[0].SetLocalType(firstNonArgLocalIndex++, VerifierTypeWrapper.UninitializedThis, -1);
+ state[0].SetUnitializedThis(true);
+ }
+ else
+ {
+ state[0].SetLocalType(firstNonArgLocalIndex++, thisType, -1);
+ }
+ }
+ else
+ {
+ thisType = null;
+ }
+ // mw can be null when we're invoked from IsSideEffectFreeStaticInitializer
+ TypeWrapper[] argTypeWrappers = mw == null ? TypeWrapper.EmptyArray : mw.GetParameters();
+ for (int i = 0; i < argTypeWrappers.Length; i++)
+ {
+ TypeWrapper type = argTypeWrappers[i];
+ if (type.IsIntOnStackPrimitive)
+ {
+ type = PrimitiveTypeWrapper.INT;
+ }
+ state[0].SetLocalType(firstNonArgLocalIndex++, type, -1);
+ if (type.IsWidePrimitive)
+ {
+ firstNonArgLocalIndex++;
+ }
+ }
+ AnalyzeTypeFlow();
+ VerifyPassTwo();
+ PatchLoadConstants();
+ }
+
+ private void PatchLoadConstants()
+ {
+ ClassFile.Method.Instruction[] code = method.Instructions;
+ for (int i = 0; i < code.Length; i++)
+ {
+ if (state[i] != null)
+ {
+ switch (code[i].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__ldc:
+ switch (GetConstantPoolConstantType(code[i].Arg1))
+ {
+ case ClassFile.ConstantType.Double:
+ case ClassFile.ConstantType.Float:
+ case ClassFile.ConstantType.Integer:
+ case ClassFile.ConstantType.Long:
+ case ClassFile.ConstantType.String:
+ case ClassFile.ConstantType.LiveObject:
+ code[i].PatchOpCode(NormalizedByteCode.__ldc_nothrow);
+ break;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ internal CodeInfo GetCodeInfoAndErrors(UntangledExceptionTable exceptions, out List errors)
+ {
+ CodeInfo codeInfo = new CodeInfo(state);
+ OptimizationPass(codeInfo, classFile, method, exceptions, wrapper, classLoader);
+ PatchHardErrorsAndDynamicMemberAccess(wrapper, mw);
+ errors = errorMessages;
+ if (AnalyzePotentialFaultBlocks(codeInfo, method, exceptions))
+ {
+ AnalyzeTypeFlow();
+ }
+ ConvertFinallyBlocks(codeInfo, method, exceptions);
+ return codeInfo;
+ }
+
+ private void AnalyzeTypeFlow()
+ {
+ InstructionState s = new InstructionState(method.MaxLocals, method.MaxStack);
+ bool done = false;
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ while (!done)
+ {
+ done = true;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if (state[i] != null && state[i].changed)
+ {
+ try
+ {
+ //Console.WriteLine(method.Instructions[i].PC + ": " + method.Instructions[i].OpCode.ToString());
+ done = false;
+ state[i].changed = false;
+ // mark the exception handlers reachable from this instruction
+ for (int j = 0; j < method.ExceptionTable.Length; j++)
+ {
+ if (method.ExceptionTable[j].startIndex <= i && i < method.ExceptionTable[j].endIndex)
+ {
+ MergeExceptionHandler(j, state[i]);
+ }
+ }
+ state[i].CopyTo(s);
+ ClassFile.Method.Instruction instr = instructions[i];
+ switch (instr.NormalizedOpCode)
+ {
+ case NormalizedByteCode.__aload:
+ {
+ TypeWrapper type = s.GetLocalType(instr.NormalizedArg1);
+ if (type == VerifierTypeWrapper.Invalid || type.IsPrimitive)
+ {
+ throw new VerifyError("Object reference expected");
+ }
+ s.PushType(type);
+ break;
+ }
+ case NormalizedByteCode.__astore:
+ {
+ if (VerifierTypeWrapper.IsFaultBlockException(s.PeekType()))
+ {
+ s.SetLocalType(instr.NormalizedArg1, s.PopFaultBlockException(), i);
+ break;
+ }
+ // NOTE since the reference can be uninitialized, we cannot use PopObjectType
+ TypeWrapper type = s.PopType();
+ if (type.IsPrimitive)
+ {
+ throw new VerifyError("Object reference expected");
+ }
+ s.SetLocalType(instr.NormalizedArg1, type, i);
+ break;
+ }
+ case NormalizedByteCode.__aconst_null:
+ s.PushType(VerifierTypeWrapper.Null);
+ break;
+ case NormalizedByteCode.__aaload:
+ {
+ s.PopInt();
+ TypeWrapper type = s.PopArrayType();
+ if (type == VerifierTypeWrapper.Null)
+ {
+ // if the array is null, we have use null as the element type, because
+ // otherwise the rest of the code will not verify correctly
+ s.PushType(VerifierTypeWrapper.Null);
+ }
+ else if (type.IsUnloadable)
+ {
+ s.PushType(VerifierTypeWrapper.Unloadable);
+ }
+ else
+ {
+ type = type.ElementTypeWrapper;
+ if (type.IsPrimitive)
+ {
+ throw new VerifyError("Object array expected");
+ }
+ s.PushType(type);
+ }
+ break;
+ }
+ case NormalizedByteCode.__aastore:
+ s.PopObjectType();
+ s.PopInt();
+ s.PopArrayType();
+ // TODO check that elem is assignable to the array
+ break;
+ case NormalizedByteCode.__baload:
+ {
+ s.PopInt();
+ TypeWrapper type = s.PopArrayType();
+ if (!VerifierTypeWrapper.IsNullOrUnloadable(type) &&
+ type != ByteArrayType &&
+ type != BooleanArrayType)
+ {
+ throw new VerifyError();
+ }
+ s.PushInt();
+ break;
+ }
+ case NormalizedByteCode.__bastore:
+ {
+ s.PopInt();
+ s.PopInt();
+ TypeWrapper type = s.PopArrayType();
+ if (!VerifierTypeWrapper.IsNullOrUnloadable(type) &&
+ type != ByteArrayType &&
+ type != BooleanArrayType)
+ {
+ throw new VerifyError();
+ }
+ break;
+ }
+ case NormalizedByteCode.__caload:
+ s.PopInt();
+ s.PopObjectType(CharArrayType);
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__castore:
+ s.PopInt();
+ s.PopInt();
+ s.PopObjectType(CharArrayType);
+ break;
+ case NormalizedByteCode.__saload:
+ s.PopInt();
+ s.PopObjectType(ShortArrayType);
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__sastore:
+ s.PopInt();
+ s.PopInt();
+ s.PopObjectType(ShortArrayType);
+ break;
+ case NormalizedByteCode.__iaload:
+ s.PopInt();
+ s.PopObjectType(IntArrayType);
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__iastore:
+ s.PopInt();
+ s.PopInt();
+ s.PopObjectType(IntArrayType);
+ break;
+ case NormalizedByteCode.__laload:
+ s.PopInt();
+ s.PopObjectType(LongArrayType);
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__lastore:
+ s.PopLong();
+ s.PopInt();
+ s.PopObjectType(LongArrayType);
+ break;
+ case NormalizedByteCode.__daload:
+ s.PopInt();
+ s.PopObjectType(DoubleArrayType);
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__dastore:
+ s.PopDouble();
+ s.PopInt();
+ s.PopObjectType(DoubleArrayType);
+ break;
+ case NormalizedByteCode.__faload:
+ s.PopInt();
+ s.PopObjectType(FloatArrayType);
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__fastore:
+ s.PopFloat();
+ s.PopInt();
+ s.PopObjectType(FloatArrayType);
+ break;
+ case NormalizedByteCode.__arraylength:
+ s.PopArrayType();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__iconst:
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__if_icmpeq:
+ case NormalizedByteCode.__if_icmpne:
+ case NormalizedByteCode.__if_icmplt:
+ case NormalizedByteCode.__if_icmpge:
+ case NormalizedByteCode.__if_icmpgt:
+ case NormalizedByteCode.__if_icmple:
+ s.PopInt();
+ s.PopInt();
+ break;
+ case NormalizedByteCode.__ifeq:
+ case NormalizedByteCode.__ifge:
+ case NormalizedByteCode.__ifgt:
+ case NormalizedByteCode.__ifle:
+ case NormalizedByteCode.__iflt:
+ case NormalizedByteCode.__ifne:
+ s.PopInt();
+ break;
+ case NormalizedByteCode.__ifnonnull:
+ case NormalizedByteCode.__ifnull:
+ // TODO it might be legal to use an unitialized ref here
+ s.PopObjectType();
+ break;
+ case NormalizedByteCode.__if_acmpeq:
+ case NormalizedByteCode.__if_acmpne:
+ // TODO it might be legal to use an unitialized ref here
+ s.PopObjectType();
+ s.PopObjectType();
+ break;
+ case NormalizedByteCode.__getstatic:
+ case NormalizedByteCode.__dynamic_getstatic:
+ // special support for when we're being called from IsSideEffectFreeStaticInitializer
+ if (mw == null)
+ {
+ switch (GetFieldref(instr.Arg1).Signature[0])
+ {
+ case 'B':
+ case 'Z':
+ case 'C':
+ case 'S':
+ case 'I':
+ s.PushInt();
+ break;
+ case 'F':
+ s.PushFloat();
+ break;
+ case 'D':
+ s.PushDouble();
+ break;
+ case 'J':
+ s.PushLong();
+ break;
+ case 'L':
+ case '[':
+ throw new VerifyError();
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ else
+ {
+ ClassFile.ConstantPoolItemFieldref cpi = GetFieldref(instr.Arg1);
+ if (cpi.GetField() != null && cpi.GetField().FieldTypeWrapper.IsUnloadable)
+ {
+ s.PushType(cpi.GetField().FieldTypeWrapper);
+ }
+ else
+ {
+ s.PushType(cpi.GetFieldType());
+ }
+ }
+ break;
+ case NormalizedByteCode.__putstatic:
+ case NormalizedByteCode.__dynamic_putstatic:
+ // special support for when we're being called from IsSideEffectFreeStaticInitializer
+ if (mw == null)
+ {
+ switch (GetFieldref(instr.Arg1).Signature[0])
+ {
+ case 'B':
+ case 'Z':
+ case 'C':
+ case 'S':
+ case 'I':
+ s.PopInt();
+ break;
+ case 'F':
+ s.PopFloat();
+ break;
+ case 'D':
+ s.PopDouble();
+ break;
+ case 'J':
+ s.PopLong();
+ break;
+ case 'L':
+ case '[':
+ if (s.PopAnyType() != VerifierTypeWrapper.Null)
+ {
+ throw new VerifyError();
+ }
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ else
+ {
+ s.PopType(GetFieldref(instr.Arg1).GetFieldType());
+ }
+ break;
+ case NormalizedByteCode.__getfield:
+ case NormalizedByteCode.__dynamic_getfield:
+ {
+ s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
+ ClassFile.ConstantPoolItemFieldref cpi = GetFieldref(instr.Arg1);
+ if (cpi.GetField() != null && cpi.GetField().FieldTypeWrapper.IsUnloadable)
+ {
+ s.PushType(cpi.GetField().FieldTypeWrapper);
+ }
+ else
+ {
+ s.PushType(cpi.GetFieldType());
+ }
+ break;
+ }
+ case NormalizedByteCode.__putfield:
+ case NormalizedByteCode.__dynamic_putfield:
+ s.PopType(GetFieldref(instr.Arg1).GetFieldType());
+ // putfield is allowed to access the uninitialized this
+ if (s.PeekType() == VerifierTypeWrapper.UninitializedThis
+ && wrapper.IsAssignableTo(GetFieldref(instr.Arg1).GetClassType()))
+ {
+ s.PopType();
+ }
+ else
+ {
+ s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
+ }
+ break;
+ case NormalizedByteCode.__ldc_nothrow:
+ case NormalizedByteCode.__ldc:
+ {
+ switch (GetConstantPoolConstantType(instr.Arg1))
+ {
+ case ClassFile.ConstantType.Double:
+ s.PushDouble();
+ break;
+ case ClassFile.ConstantType.Float:
+ s.PushFloat();
+ break;
+ case ClassFile.ConstantType.Integer:
+ s.PushInt();
+ break;
+ case ClassFile.ConstantType.Long:
+ s.PushLong();
+ break;
+ case ClassFile.ConstantType.String:
+ s.PushType(CoreClasses.java.lang.String.Wrapper);
+ break;
+ case ClassFile.ConstantType.LiveObject:
+ s.PushType(CoreClasses.java.lang.Object.Wrapper);
+ break;
+ case ClassFile.ConstantType.Class:
+ if (classFile.MajorVersion < 49)
+ {
+ throw new VerifyError("Illegal type in constant pool");
+ }
+ s.PushType(CoreClasses.java.lang.Class.Wrapper);
+ break;
+ case ClassFile.ConstantType.MethodHandle:
+ s.PushType(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
+ break;
+ case ClassFile.ConstantType.MethodType:
+ s.PushType(CoreClasses.java.lang.invoke.MethodType.Wrapper);
+ break;
+ default:
+ // NOTE this is not a VerifyError, because it cannot happen (unless we have
+ // a bug in ClassFile.GetConstantPoolConstantType)
+ throw new InvalidOperationException();
+ }
+ break;
+ }
+ case NormalizedByteCode.__clone_array:
+ case NormalizedByteCode.__invokevirtual:
+ case NormalizedByteCode.__invokespecial:
+ case NormalizedByteCode.__invokeinterface:
+ case NormalizedByteCode.__invokestatic:
+ case NormalizedByteCode.__dynamic_invokevirtual:
+ case NormalizedByteCode.__dynamic_invokespecial:
+ case NormalizedByteCode.__dynamic_invokeinterface:
+ case NormalizedByteCode.__dynamic_invokestatic:
+ case NormalizedByteCode.__privileged_invokevirtual:
+ case NormalizedByteCode.__privileged_invokespecial:
+ case NormalizedByteCode.__privileged_invokestatic:
+ case NormalizedByteCode.__methodhandle_invoke:
+ case NormalizedByteCode.__methodhandle_link:
+ {
+ ClassFile.ConstantPoolItemMI cpi = GetMethodref(instr.Arg1);
+ TypeWrapper retType = cpi.GetRetType();
+ // HACK to allow the result of Unsafe.getObjectVolatile() (on an array)
+ // to be used with Unsafe.putObject() we need to propagate the
+ // element type here as the return type (instead of object)
+ if (cpi.GetMethod() != null
+ && cpi.GetMethod().IsIntrinsic
+ && cpi.Class == "sun.misc.Unsafe"
+ && cpi.Name == "getObjectVolatile"
+ && Intrinsics.IsSupportedArrayTypeForUnsafeOperation(s.GetStackSlot(1)))
+ {
+ retType = s.GetStackSlot(1).ElementTypeWrapper;
+ }
+ s.MultiPopAnyType(cpi.GetArgTypes().Length);
+ if (instr.NormalizedOpCode != NormalizedByteCode.__invokestatic
+ && instr.NormalizedOpCode != NormalizedByteCode.__dynamic_invokestatic)
+ {
+ TypeWrapper type = s.PopType();
+ if (ReferenceEquals(cpi.Name, StringConstants.INIT))
+ {
+ // after we've invoked the constructor, the uninitialized references
+ // are now initialized
+ if (type == VerifierTypeWrapper.UninitializedThis)
+ {
+ if (s.GetLocalTypeEx(0) == type)
+ {
+ s.SetLocalType(0, thisType, i);
+ }
+ s.MarkInitialized(type, wrapper, i);
+ s.SetUnitializedThis(false);
+ }
+ else if (VerifierTypeWrapper.IsNew(type))
+ {
+ s.MarkInitialized(type, ((VerifierTypeWrapper)type).UnderlyingType, i);
+ }
+ else
+ {
+ // This is a VerifyError, but it will be caught by our second pass
+ }
+ }
+ }
+ if (retType != PrimitiveTypeWrapper.VOID)
+ {
+ if (cpi.GetMethod() != null && cpi.GetMethod().ReturnType.IsUnloadable)
+ {
+ s.PushType(cpi.GetMethod().ReturnType);
+ }
+ else if (retType == PrimitiveTypeWrapper.DOUBLE)
+ {
+ s.PushExtendedDouble();
+ }
+ else if (retType == PrimitiveTypeWrapper.FLOAT)
+ {
+ s.PushExtendedFloat();
+ }
+ else
+ {
+ s.PushType(retType);
+ }
+ }
+ break;
+ }
+ case NormalizedByteCode.__invokedynamic:
+ {
+ ClassFile.ConstantPoolItemInvokeDynamic cpi = GetInvokeDynamic(instr.Arg1);
+ s.MultiPopAnyType(cpi.GetArgTypes().Length);
+ TypeWrapper retType = cpi.GetRetType();
+ if (retType != PrimitiveTypeWrapper.VOID)
+ {
+ if (retType == PrimitiveTypeWrapper.DOUBLE)
+ {
+ s.PushExtendedDouble();
+ }
+ else if (retType == PrimitiveTypeWrapper.FLOAT)
+ {
+ s.PushExtendedFloat();
+ }
+ else
+ {
+ s.PushType(retType);
+ }
+ }
+ break;
+ }
+ case NormalizedByteCode.__goto:
+ break;
+ case NormalizedByteCode.__istore:
+ s.PopInt();
+ s.SetLocalInt(instr.NormalizedArg1, i);
+ break;
+ case NormalizedByteCode.__iload:
+ s.GetLocalInt(instr.NormalizedArg1);
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__ineg:
+ s.PopInt();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__iadd:
+ case NormalizedByteCode.__isub:
+ case NormalizedByteCode.__imul:
+ case NormalizedByteCode.__idiv:
+ case NormalizedByteCode.__irem:
+ case NormalizedByteCode.__iand:
+ case NormalizedByteCode.__ior:
+ case NormalizedByteCode.__ixor:
+ case NormalizedByteCode.__ishl:
+ case NormalizedByteCode.__ishr:
+ case NormalizedByteCode.__iushr:
+ s.PopInt();
+ s.PopInt();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__lneg:
+ s.PopLong();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__ladd:
+ case NormalizedByteCode.__lsub:
+ case NormalizedByteCode.__lmul:
+ case NormalizedByteCode.__ldiv:
+ case NormalizedByteCode.__lrem:
+ case NormalizedByteCode.__land:
+ case NormalizedByteCode.__lor:
+ case NormalizedByteCode.__lxor:
+ s.PopLong();
+ s.PopLong();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__lshl:
+ case NormalizedByteCode.__lshr:
+ case NormalizedByteCode.__lushr:
+ s.PopInt();
+ s.PopLong();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__fneg:
+ if (s.PopFloat())
+ {
+ s.PushExtendedFloat();
+ }
+ else
+ {
+ s.PushFloat();
+ }
+ break;
+ case NormalizedByteCode.__fadd:
+ case NormalizedByteCode.__fsub:
+ case NormalizedByteCode.__fmul:
+ case NormalizedByteCode.__fdiv:
+ case NormalizedByteCode.__frem:
+ s.PopFloat();
+ s.PopFloat();
+ s.PushExtendedFloat();
+ break;
+ case NormalizedByteCode.__dneg:
+ if (s.PopDouble())
+ {
+ s.PushExtendedDouble();
+ }
+ else
+ {
+ s.PushDouble();
+ }
+ break;
+ case NormalizedByteCode.__dadd:
+ case NormalizedByteCode.__dsub:
+ case NormalizedByteCode.__dmul:
+ case NormalizedByteCode.__ddiv:
+ case NormalizedByteCode.__drem:
+ s.PopDouble();
+ s.PopDouble();
+ s.PushExtendedDouble();
+ break;
+ case NormalizedByteCode.__new:
+ {
+ // mark the type, so that we can ascertain that it is a "new object"
+ TypeWrapper type;
+ if (!newTypes.TryGetValue(i, out type))
+ {
+ type = GetConstantPoolClassType(instr.Arg1);
+ if (type.IsArray)
+ {
+ throw new VerifyError("Illegal use of array type");
+ }
+ type = VerifierTypeWrapper.MakeNew(type, i);
+ newTypes[i] = type;
+ }
+ s.PushType(type);
+ break;
+ }
+ case NormalizedByteCode.__multianewarray:
+ {
+ if (instr.Arg2 < 1)
+ {
+ throw new VerifyError("Illegal dimension argument");
+ }
+ for (int j = 0; j < instr.Arg2; j++)
+ {
+ s.PopInt();
+ }
+ TypeWrapper type = GetConstantPoolClassType(instr.Arg1);
+ if (type.ArrayRank < instr.Arg2)
+ {
+ throw new VerifyError("Illegal dimension argument");
+ }
+ s.PushType(type);
+ break;
+ }
+ case NormalizedByteCode.__anewarray:
+ {
+ s.PopInt();
+ TypeWrapper type = GetConstantPoolClassType(instr.Arg1);
+ if (type.IsUnloadable)
+ {
+ s.PushType(new UnloadableTypeWrapper("[" + type.SigName));
+ }
+ else
+ {
+ s.PushType(type.MakeArrayType(1));
+ }
+ break;
+ }
+ case NormalizedByteCode.__newarray:
+ s.PopInt();
+ switch (instr.Arg1)
+ {
+ case 4:
+ s.PushType(BooleanArrayType);
+ break;
+ case 5:
+ s.PushType(CharArrayType);
+ break;
+ case 6:
+ s.PushType(FloatArrayType);
+ break;
+ case 7:
+ s.PushType(DoubleArrayType);
+ break;
+ case 8:
+ s.PushType(ByteArrayType);
+ break;
+ case 9:
+ s.PushType(ShortArrayType);
+ break;
+ case 10:
+ s.PushType(IntArrayType);
+ break;
+ case 11:
+ s.PushType(LongArrayType);
+ break;
+ default:
+ throw new VerifyError("Bad type");
+ }
+ break;
+ case NormalizedByteCode.__swap:
+ {
+ TypeWrapper t1 = s.PopType();
+ TypeWrapper t2 = s.PopType();
+ s.PushType(t1);
+ s.PushType(t2);
+ break;
+ }
+ case NormalizedByteCode.__dup:
+ {
+ TypeWrapper t = s.PopType();
+ s.PushType(t);
+ s.PushType(t);
+ break;
+ }
+ case NormalizedByteCode.__dup2:
+ {
+ TypeWrapper t = s.PopAnyType();
+ if (t.IsWidePrimitive || t == VerifierTypeWrapper.ExtendedDouble)
+ {
+ s.PushType(t);
+ s.PushType(t);
+ }
+ else
+ {
+ TypeWrapper t2 = s.PopType();
+ s.PushType(t2);
+ s.PushType(t);
+ s.PushType(t2);
+ s.PushType(t);
+ }
+ break;
+ }
+ case NormalizedByteCode.__dup_x1:
+ {
+ TypeWrapper value1 = s.PopType();
+ TypeWrapper value2 = s.PopType();
+ s.PushType(value1);
+ s.PushType(value2);
+ s.PushType(value1);
+ break;
+ }
+ case NormalizedByteCode.__dup2_x1:
+ {
+ TypeWrapper value1 = s.PopAnyType();
+ if (value1.IsWidePrimitive || value1 == VerifierTypeWrapper.ExtendedDouble)
+ {
+ TypeWrapper value2 = s.PopType();
+ s.PushType(value1);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ else
+ {
+ TypeWrapper value2 = s.PopType();
+ TypeWrapper value3 = s.PopType();
+ s.PushType(value2);
+ s.PushType(value1);
+ s.PushType(value3);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ break;
+ }
+ case NormalizedByteCode.__dup_x2:
+ {
+ TypeWrapper value1 = s.PopType();
+ TypeWrapper value2 = s.PopAnyType();
+ if (value2.IsWidePrimitive || value2 == VerifierTypeWrapper.ExtendedDouble)
+ {
+ s.PushType(value1);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ else
+ {
+ TypeWrapper value3 = s.PopType();
+ s.PushType(value1);
+ s.PushType(value3);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ break;
+ }
+ case NormalizedByteCode.__dup2_x2:
+ {
+ TypeWrapper value1 = s.PopAnyType();
+ if (value1.IsWidePrimitive || value1 == VerifierTypeWrapper.ExtendedDouble)
+ {
+ TypeWrapper value2 = s.PopAnyType();
+ if (value2.IsWidePrimitive || value2 == VerifierTypeWrapper.ExtendedDouble)
+ {
+ // Form 4
+ s.PushType(value1);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ else
+ {
+ // Form 2
+ TypeWrapper value3 = s.PopType();
+ s.PushType(value1);
+ s.PushType(value3);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ }
+ else
+ {
+ TypeWrapper value2 = s.PopType();
+ TypeWrapper value3 = s.PopAnyType();
+ if (value3.IsWidePrimitive || value3 == VerifierTypeWrapper.ExtendedDouble)
+ {
+ // Form 3
+ s.PushType(value2);
+ s.PushType(value1);
+ s.PushType(value3);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ else
+ {
+ // Form 4
+ TypeWrapper value4 = s.PopType();
+ s.PushType(value2);
+ s.PushType(value1);
+ s.PushType(value4);
+ s.PushType(value3);
+ s.PushType(value2);
+ s.PushType(value1);
+ }
+ }
+ break;
+ }
+ case NormalizedByteCode.__pop:
+ s.PopType();
+ break;
+ case NormalizedByteCode.__pop2:
+ {
+ TypeWrapper type = s.PopAnyType();
+ if (!type.IsWidePrimitive && type != VerifierTypeWrapper.ExtendedDouble)
+ {
+ s.PopType();
+ }
+ break;
+ }
+ case NormalizedByteCode.__monitorenter:
+ case NormalizedByteCode.__monitorexit:
+ // TODO these bytecodes are allowed on an uninitialized object, but
+ // we don't support that at the moment...
+ s.PopObjectType();
+ break;
+ case NormalizedByteCode.__return:
+ // mw is null if we're called from IsSideEffectFreeStaticInitializer
+ if (mw != null)
+ {
+ if (mw.ReturnType != PrimitiveTypeWrapper.VOID)
+ {
+ throw new VerifyError("Wrong return type in function");
+ }
+ // if we're a constructor, make sure we called the base class constructor
+ s.CheckUninitializedThis();
+ }
+ break;
+ case NormalizedByteCode.__areturn:
+ s.PopObjectType(mw.ReturnType);
+ break;
+ case NormalizedByteCode.__ireturn:
+ {
+ s.PopInt();
+ if (!mw.ReturnType.IsIntOnStackPrimitive)
+ {
+ throw new VerifyError("Wrong return type in function");
+ }
+ break;
+ }
+ case NormalizedByteCode.__lreturn:
+ s.PopLong();
+ if (mw.ReturnType != PrimitiveTypeWrapper.LONG)
+ {
+ throw new VerifyError("Wrong return type in function");
+ }
+ break;
+ case NormalizedByteCode.__freturn:
+ s.PopFloat();
+ if (mw.ReturnType != PrimitiveTypeWrapper.FLOAT)
+ {
+ throw new VerifyError("Wrong return type in function");
+ }
+ break;
+ case NormalizedByteCode.__dreturn:
+ s.PopDouble();
+ if (mw.ReturnType != PrimitiveTypeWrapper.DOUBLE)
+ {
+ throw new VerifyError("Wrong return type in function");
+ }
+ break;
+ case NormalizedByteCode.__fload:
+ s.GetLocalFloat(instr.NormalizedArg1);
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__fstore:
+ s.PopFloat();
+ s.SetLocalFloat(instr.NormalizedArg1, i);
+ break;
+ case NormalizedByteCode.__dload:
+ s.GetLocalDouble(instr.NormalizedArg1);
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__dstore:
+ s.PopDouble();
+ s.SetLocalDouble(instr.NormalizedArg1, i);
+ break;
+ case NormalizedByteCode.__lload:
+ s.GetLocalLong(instr.NormalizedArg1);
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__lstore:
+ s.PopLong();
+ s.SetLocalLong(instr.NormalizedArg1, i);
+ break;
+ case NormalizedByteCode.__lconst_0:
+ case NormalizedByteCode.__lconst_1:
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__fconst_0:
+ case NormalizedByteCode.__fconst_1:
+ case NormalizedByteCode.__fconst_2:
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__dconst_0:
+ case NormalizedByteCode.__dconst_1:
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__lcmp:
+ s.PopLong();
+ s.PopLong();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__fcmpl:
+ case NormalizedByteCode.__fcmpg:
+ s.PopFloat();
+ s.PopFloat();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__dcmpl:
+ case NormalizedByteCode.__dcmpg:
+ s.PopDouble();
+ s.PopDouble();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__checkcast:
+ s.PopObjectType();
+ s.PushType(GetConstantPoolClassType(instr.Arg1));
+ break;
+ case NormalizedByteCode.__instanceof:
+ s.PopObjectType();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__iinc:
+ s.GetLocalInt(instr.Arg1);
+ break;
+ case NormalizedByteCode.__athrow:
+ if (VerifierTypeWrapper.IsFaultBlockException(s.PeekType()))
+ {
+ s.PopFaultBlockException();
+ }
+ else
+ {
+ s.PopObjectType(CoreClasses.java.lang.Throwable.Wrapper);
+ }
+ break;
+ case NormalizedByteCode.__tableswitch:
+ case NormalizedByteCode.__lookupswitch:
+ s.PopInt();
+ break;
+ case NormalizedByteCode.__i2b:
+ s.PopInt();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__i2c:
+ s.PopInt();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__i2s:
+ s.PopInt();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__i2l:
+ s.PopInt();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__i2f:
+ s.PopInt();
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__i2d:
+ s.PopInt();
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__l2i:
+ s.PopLong();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__l2f:
+ s.PopLong();
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__l2d:
+ s.PopLong();
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__f2i:
+ s.PopFloat();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__f2l:
+ s.PopFloat();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__f2d:
+ s.PopFloat();
+ s.PushDouble();
+ break;
+ case NormalizedByteCode.__d2i:
+ s.PopDouble();
+ s.PushInt();
+ break;
+ case NormalizedByteCode.__d2f:
+ s.PopDouble();
+ s.PushFloat();
+ break;
+ case NormalizedByteCode.__d2l:
+ s.PopDouble();
+ s.PushLong();
+ break;
+ case NormalizedByteCode.__nop:
+ if (i + 1 == instructions.Length)
+ {
+ throw new VerifyError("Falling off the end of the code");
+ }
+ break;
+ case NormalizedByteCode.__static_error:
+ break;
+ case NormalizedByteCode.__jsr:
+ case NormalizedByteCode.__ret:
+ throw new VerifyError("Bad instruction");
+ default:
+ throw new NotImplementedException(instr.NormalizedOpCode.ToString());
+ }
+ if (s.GetStackHeight() > method.MaxStack)
+ {
+ throw new VerifyError("Stack size too large");
+ }
+ for (int j = 0; j < method.ExceptionTable.Length; j++)
+ {
+ if (method.ExceptionTable[j].endIndex == i + 1)
+ {
+ MergeExceptionHandler(j, s);
+ }
+ }
+ try
+ {
+ switch (ByteCodeMetaData.GetFlowControl(instr.NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Switch:
+ for (int j = 0; j < instr.SwitchEntryCount; j++)
+ {
+ state[instr.GetSwitchTargetIndex(j)] += s;
+ }
+ state[instr.DefaultTarget] += s;
+ break;
+ case ByteCodeFlowControl.CondBranch:
+ state[i + 1] += s;
+ state[instr.TargetIndex] += s;
+ break;
+ case ByteCodeFlowControl.Branch:
+ state[instr.TargetIndex] += s;
+ break;
+ case ByteCodeFlowControl.Return:
+ case ByteCodeFlowControl.Throw:
+ break;
+ case ByteCodeFlowControl.Next:
+ state[i + 1] += s;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ catch (IndexOutOfRangeException)
+ {
+ // we're going to assume that this always means that we have an invalid branch target
+ // NOTE because PcIndexMap returns -1 for illegal PCs (in the middle of an instruction) and
+ // we always use that value as an index into the state array, any invalid PC will result
+ // in an IndexOutOfRangeException
+ throw new VerifyError("Illegal target of jump or branch");
+ }
+ }
+ catch (VerifyError x)
+ {
+ string opcode = instructions[i].NormalizedOpCode.ToString();
+ if (opcode.StartsWith("__"))
+ {
+ opcode = opcode.Substring(2);
+ }
+ throw new VerifyError(string.Format("{5} (class: {0}, method: {1}, signature: {2}, offset: {3}, instruction: {4})",
+ classFile.Name, method.Name, method.Signature, instructions[i].PC, opcode, x.Message), x);
+ }
+ }
+ }
+ }
+ }
+
+ private void MergeExceptionHandler(int exceptionIndex, InstructionState curr)
+ {
+ int idx = method.ExceptionTable[exceptionIndex].handlerIndex;
+ InstructionState ex = curr.CopyLocals();
+ int catch_type = method.ExceptionTable[exceptionIndex].catch_type;
+ if (catch_type == 0)
+ {
+ TypeWrapper tw;
+ if (!faultTypes.TryGetValue(idx, out tw))
+ {
+ tw = VerifierTypeWrapper.MakeFaultBlockException(this, idx);
+ faultTypes.Add(idx, tw);
+ }
+ ex.PushType(tw);
+ }
+ else
+ {
+ // TODO if the exception type is unloadable we should consider pushing
+ // Throwable as the type and recording a loader constraint
+ ex.PushType(GetConstantPoolClassType(catch_type));
+ }
+ state[idx] += ex;
+ }
+
+ // this verification pass must run on the unmodified bytecode stream
+ private void VerifyPassTwo()
+ {
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if (state[i] != null)
+ {
+ try
+ {
+ switch (instructions[i].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__invokeinterface:
+ case NormalizedByteCode.__invokespecial:
+ case NormalizedByteCode.__invokestatic:
+ case NormalizedByteCode.__invokevirtual:
+ VerifyInvokePassTwo(i);
+ break;
+ case NormalizedByteCode.__invokedynamic:
+ VerifyInvokeDynamic(i);
+ break;
+ }
+ }
+ catch (VerifyError x)
+ {
+ string opcode = instructions[i].NormalizedOpCode.ToString();
+ if (opcode.StartsWith("__"))
+ {
+ opcode = opcode.Substring(2);
+ }
+ throw new VerifyError(string.Format("{5} (class: {0}, method: {1}, signature: {2}, offset: {3}, instruction: {4})",
+ classFile.Name, method.Name, method.Signature, instructions[i].PC, opcode, x.Message), x);
+ }
+ }
+ }
+ }
+
+ private void VerifyInvokePassTwo(int index)
+ {
+ StackState stack = new StackState(state[index]);
+ NormalizedByteCode invoke = method.Instructions[index].NormalizedOpCode;
+ ClassFile.ConstantPoolItemMI cpi = GetMethodref(method.Instructions[index].Arg1);
+ if ((invoke == NormalizedByteCode.__invokestatic || invoke == NormalizedByteCode.__invokespecial) && classFile.MajorVersion >= 52)
+ {
+ // invokestatic and invokespecial may be used to invoke interface methods in Java 8
+ // but invokespecial can only invoke methods in the current interface or a directly implemented interface
+ if (invoke == NormalizedByteCode.__invokespecial && cpi is ClassFile.ConstantPoolItemInterfaceMethodref)
+ {
+ if (cpi.GetClassType() == host)
+ {
+ // ok
+ }
+ else if (cpi.GetClassType() != wrapper && Array.IndexOf(wrapper.Interfaces, cpi.GetClassType()) == -1)
+ {
+ throw new VerifyError("Bad invokespecial instruction: interface method reference is in an indirect superinterface.");
+ }
+ }
+ }
+ else if ((cpi is ClassFile.ConstantPoolItemInterfaceMethodref) != (invoke == NormalizedByteCode.__invokeinterface))
+ {
+ throw new VerifyError("Illegal constant pool index");
+ }
+ if (invoke != NormalizedByteCode.__invokespecial && ReferenceEquals(cpi.Name, StringConstants.INIT))
+ {
+ throw new VerifyError("Must call initializers using invokespecial");
+ }
+ if (ReferenceEquals(cpi.Name, StringConstants.CLINIT))
+ {
+ throw new VerifyError("Illegal call to internal method");
+ }
+ TypeWrapper[] args = cpi.GetArgTypes();
+ for (int j = args.Length - 1; j >= 0; j--)
+ {
+ stack.PopType(args[j]);
+ }
+ if (invoke == NormalizedByteCode.__invokeinterface)
+ {
+ int argcount = args.Length + 1;
+ for (int j = 0; j < args.Length; j++)
+ {
+ if (args[j].IsWidePrimitive)
+ {
+ argcount++;
+ }
+ }
+ if (method.Instructions[index].Arg2 != argcount)
+ {
+ throw new VerifyError("Inconsistent args size");
+ }
+ }
+ bool isnew = false;
+ TypeWrapper thisType;
+ if (invoke == NormalizedByteCode.__invokestatic)
+ {
+ thisType = null;
+ }
+ else
+ {
+ thisType = SigTypeToClassName(stack.PeekType(), cpi.GetClassType(), wrapper);
+ if (ReferenceEquals(cpi.Name, StringConstants.INIT))
+ {
+ TypeWrapper type = stack.PopType();
+ isnew = VerifierTypeWrapper.IsNew(type);
+ if ((isnew && ((VerifierTypeWrapper)type).UnderlyingType != cpi.GetClassType()) ||
+ (type == VerifierTypeWrapper.UninitializedThis && cpi.GetClassType() != wrapper.BaseTypeWrapper && cpi.GetClassType() != wrapper) ||
+ (!isnew && type != VerifierTypeWrapper.UninitializedThis))
+ {
+ // TODO oddly enough, Java fails verification for the class without
+ // even running the constructor, so maybe constructors are always
+ // verified...
+ // NOTE when a constructor isn't verifiable, the static initializer
+ // doesn't run either
+ throw new VerifyError("Call to wrong initialization method");
+ }
+ }
+ else
+ {
+ if (invoke != NormalizedByteCode.__invokeinterface)
+ {
+ TypeWrapper refType = stack.PopObjectType();
+ TypeWrapper targetType = cpi.GetClassType();
+ if (!VerifierTypeWrapper.IsNullOrUnloadable(refType) &&
+ !targetType.IsUnloadable &&
+ !refType.IsAssignableTo(targetType))
+ {
+ throw new VerifyError("Incompatible object argument for function call");
+ }
+ // for invokespecial we also need to make sure we're calling ourself or a base class
+ if (invoke == NormalizedByteCode.__invokespecial)
+ {
+ if (VerifierTypeWrapper.IsNullOrUnloadable(refType))
+ {
+ // ok
+ }
+ else if (refType.IsSubTypeOf(wrapper))
+ {
+ // ok
+ }
+ else if (host != null && refType.IsSubTypeOf(host))
+ {
+ // ok
+ }
+ else
+ {
+ throw new VerifyError("Incompatible target object for invokespecial");
+ }
+ if (targetType.IsUnloadable)
+ {
+ // ok
+ }
+ else if (wrapper.IsSubTypeOf(targetType))
+ {
+ // ok
+ }
+ else if (host != null && host.IsSubTypeOf(targetType))
+ {
+ // ok
+ }
+ else
+ {
+ throw new VerifyError("Invokespecial cannot call subclass methods");
+ }
+ }
+ }
+ else /* __invokeinterface */
+ {
+ // NOTE unlike in the above case, we also allow *any* interface target type
+ // regardless of whether it is compatible or not, because if it is not compatible
+ // we want an IncompatibleClassChangeError at runtime
+ TypeWrapper refType = stack.PopObjectType();
+ TypeWrapper targetType = cpi.GetClassType();
+ if (!VerifierTypeWrapper.IsNullOrUnloadable(refType)
+ && !targetType.IsUnloadable
+ && !refType.IsAssignableTo(targetType)
+ && !targetType.IsInterface)
+ {
+ throw new VerifyError("Incompatible object argument for function call");
+ }
+ }
+ }
+ }
+ }
+
+ private void VerifyInvokeDynamic(int index)
+ {
+ StackState stack = new StackState(state[index]);
+ ClassFile.ConstantPoolItemInvokeDynamic cpi = GetInvokeDynamic(method.Instructions[index].Arg1);
+ TypeWrapper[] args = cpi.GetArgTypes();
+ for (int j = args.Length - 1; j >= 0; j--)
+ {
+ stack.PopType(args[j]);
+ }
+ }
+
+ private static void OptimizationPass(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, TypeWrapper wrapper, ClassLoaderWrapper classLoader)
+ {
+ // Optimization pass
+ if (classLoader.RemoveAsserts)
+ {
+ // While the optimization is general, in practice it never happens that a getstatic is used on a final field,
+ // so we only look for this if assert initialization has been optimized out.
+ if (classFile.HasAssertions)
+ {
+ // compute branch targets
+ InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(codeInfo, method.Instructions, exceptions, 0, false);
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if (instructions[i].NormalizedOpCode == NormalizedByteCode.__getstatic
+ && instructions[i + 1].NormalizedOpCode == NormalizedByteCode.__ifne
+ && instructions[i + 1].TargetIndex > i
+ && (flags[i + 1] & InstructionFlags.BranchTarget) == 0)
+ {
+ var field = classFile.GetFieldref(instructions[i].Arg1).GetField() as ConstantFieldWrapper;
+ if (field != null && field.FieldTypeWrapper == PrimitiveTypeWrapper.BOOLEAN && (bool)field.GetConstantValue())
+ {
+ // We know the branch will always be taken, so we replace the getstatic/ifne by a goto.
+ instructions[i].PatchOpCode(NormalizedByteCode.__goto, instructions[i + 1].TargetIndex);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void PatchHardErrorsAndDynamicMemberAccess(TypeWrapper wrapper, MethodWrapper mw)
+ {
+ // Now we do another pass to find "hard error" instructions
+ if (true)
+ {
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if (state[i] != null)
+ {
+ StackState stack = new StackState(state[i]);
+ switch (instructions[i].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__invokeinterface:
+ case NormalizedByteCode.__invokespecial:
+ case NormalizedByteCode.__invokestatic:
+ case NormalizedByteCode.__invokevirtual:
+ PatchInvoke(wrapper, ref instructions[i], stack);
+ break;
+ case NormalizedByteCode.__getfield:
+ case NormalizedByteCode.__putfield:
+ case NormalizedByteCode.__getstatic:
+ case NormalizedByteCode.__putstatic:
+ PatchFieldAccess(wrapper, mw, ref instructions[i], stack);
+ break;
+ case NormalizedByteCode.__ldc:
+ switch (classFile.GetConstantPoolConstantType(instructions[i].Arg1))
+ {
+ case ClassFile.ConstantType.Class:
+ {
+ TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ break;
+ }
+ case ClassFile.ConstantType.MethodType:
+ {
+ ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(instructions[i].Arg1);
+ TypeWrapper[] args = cpi.GetArgTypes();
+ TypeWrapper tw = cpi.GetRetType();
+ for (int j = 0; !tw.IsUnloadable && j < args.Length; j++)
+ {
+ tw = args[j];
+ }
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ break;
+ }
+ case ClassFile.ConstantType.MethodHandle:
+ PatchLdcMethodHandle(ref instructions[i]);
+ break;
+ }
+ break;
+ case NormalizedByteCode.__new:
+ {
+ TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ else if (!tw.IsAccessibleFrom(wrapper))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
+ }
+ else if (tw.IsAbstract)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.InstantiationError, "{0}", tw.Name);
+ }
+ break;
+ }
+ case NormalizedByteCode.__multianewarray:
+ case NormalizedByteCode.__anewarray:
+ {
+ TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ else if (!tw.IsAccessibleFrom(wrapper))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
+ }
+ break;
+ }
+ case NormalizedByteCode.__checkcast:
+ case NormalizedByteCode.__instanceof:
+ {
+ TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
+ if (tw.IsUnloadable)
+ {
+ // If the type is unloadable, we always generate the dynamic code
+ // (regardless of ClassLoaderWrapper.DisableDynamicBinding), because at runtime,
+ // null references should always pass thru without attempting
+ // to load the type (for Sun compatibility).
+ }
+ else if (!tw.IsAccessibleFrom(wrapper))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
+ }
+ break;
+ }
+ case NormalizedByteCode.__aaload:
+ {
+ stack.PopInt();
+ TypeWrapper tw = stack.PopArrayType();
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ break;
+ }
+ case NormalizedByteCode.__aastore:
+ {
+ stack.PopObjectType();
+ stack.PopInt();
+ TypeWrapper tw = stack.PopArrayType();
+ if (tw.IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void PatchLdcMethodHandle(ref ClassFile.Method.Instruction instr)
+ {
+ ClassFile.ConstantPoolItemMethodHandle cpi = classFile.GetConstantPoolConstantMethodHandle(instr.Arg1);
+ if (cpi.GetClassType().IsUnloadable)
+ {
+ ConditionalPatchNoClassDefFoundError(ref instr, cpi.GetClassType());
+ }
+ else if (!cpi.GetClassType().IsAccessibleFrom(wrapper))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access class {0} from class {1}", cpi.Class, wrapper.Name);
+ }
+ else if (cpi.Kind == ReferenceKind.InvokeVirtual
+ && cpi.GetClassType() == CoreClasses.java.lang.invoke.MethodHandle.Wrapper
+ && (cpi.Name == "invoke" || cpi.Name == "invokeExact"))
+ {
+ // it's allowed to use ldc to create a MethodHandle invoker
+ }
+ else if (cpi.Member == null || cpi.Member.IsStatic != (cpi.Kind == ReferenceKind.GetStatic || cpi.Kind == ReferenceKind.PutStatic || cpi.Kind == ReferenceKind.InvokeStatic))
+ {
+ HardError err;
+ string msg;
+ switch (cpi.Kind)
+ {
+ case ReferenceKind.GetField:
+ case ReferenceKind.GetStatic:
+ case ReferenceKind.PutField:
+ case ReferenceKind.PutStatic:
+ err = HardError.NoSuchFieldError;
+ msg = cpi.Name;
+ break;
+ default:
+ err = HardError.NoSuchMethodError;
+ msg = cpi.Class + "." + cpi.Name + cpi.Signature;
+ break;
+ }
+ SetHardError(wrapper.GetClassLoader(), ref instr, err, msg, cpi.Class, cpi.Name, SigToString(cpi.Signature));
+ }
+ else if (!cpi.Member.IsAccessibleFrom(cpi.GetClassType(), wrapper, cpi.GetClassType()))
+ {
+ if (cpi.Member.IsProtected && wrapper.IsSubTypeOf(cpi.Member.DeclaringType))
+ {
+ // this is allowed, the receiver will be narrowed to current type
+ }
+ else
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}/{3}, from {4}", cpi.Class, cpi.Name, SigToString(cpi.Signature), cpi.Kind, wrapper.Name);
+ }
+ }
+ }
+
+ private static string SigToString(string sig)
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ string sep = "";
+ int dims = 0;
+ for (int i = 0; i < sig.Length; i++)
+ {
+ if (sig[i] == '(' || sig[i] == ')')
+ {
+ sb.Append(sig[i]);
+ sep = "";
+ continue;
+ }
+ else if (sig[i] == '[')
+ {
+ dims++;
+ continue;
+ }
+ sb.Append(sep);
+ sep = ",";
+ switch (sig[i])
+ {
+ case 'V':
+ sb.Append("void");
+ break;
+ case 'B':
+ sb.Append("byte");
+ break;
+ case 'Z':
+ sb.Append("boolean");
+ break;
+ case 'S':
+ sb.Append("short");
+ break;
+ case 'C':
+ sb.Append("char");
+ break;
+ case 'I':
+ sb.Append("int");
+ break;
+ case 'J':
+ sb.Append("long");
+ break;
+ case 'F':
+ sb.Append("float");
+ break;
+ case 'D':
+ sb.Append("double");
+ break;
+ case 'L':
+ sb.Append(sig, i + 1, sig.IndexOf(';', i + 1) - (i + 1));
+ i = sig.IndexOf(';', i + 1);
+ break;
+ }
+ for (; dims != 0; dims--)
+ {
+ sb.Append("[]");
+ }
+ }
+ return sb.ToString();
+ }
+
+ internal static InstructionFlags[] ComputePartialReachability(CodeInfo codeInfo, ClassFile.Method.Instruction[] instructions, UntangledExceptionTable exceptions, int initialInstructionIndex, bool skipFaultBlocks)
+ {
+ InstructionFlags[] flags = new InstructionFlags[instructions.Length];
+ flags[initialInstructionIndex] |= InstructionFlags.Reachable;
+ UpdatePartialReachability(flags, codeInfo, instructions, exceptions, skipFaultBlocks);
+ return flags;
+ }
+
+ private static void UpdatePartialReachability(InstructionFlags[] flags, CodeInfo codeInfo, ClassFile.Method.Instruction[] instructions, UntangledExceptionTable exceptions, bool skipFaultBlocks)
+ {
+ bool done = false;
+ while (!done)
+ {
+ done = true;
+ for (int i = 0; i < instructions.Length; i++)
+ {
+ if ((flags[i] & (InstructionFlags.Reachable | InstructionFlags.Processed)) == InstructionFlags.Reachable)
+ {
+ done = false;
+ flags[i] |= InstructionFlags.Processed;
+ // mark the exception handlers reachable from this instruction
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
+ {
+ int idx = exceptions[j].handlerIndex;
+ if (!skipFaultBlocks || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(idx, 0)))
+ {
+ flags[idx] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
+ }
+ }
+ }
+ MarkSuccessors(instructions, flags, i);
+ }
+ }
+ }
+ }
+
+ private static void MarkSuccessors(ClassFile.Method.Instruction[] code, InstructionFlags[] flags, int index)
+ {
+ switch (ByteCodeMetaData.GetFlowControl(code[index].NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Switch:
+ {
+ for (int i = 0; i < code[index].SwitchEntryCount; i++)
+ {
+ flags[code[index].GetSwitchTargetIndex(i)] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
+ }
+ flags[code[index].DefaultTarget] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
+ break;
+ }
+ case ByteCodeFlowControl.Branch:
+ flags[code[index].TargetIndex] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
+ break;
+ case ByteCodeFlowControl.CondBranch:
+ flags[code[index].TargetIndex] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
+ flags[index + 1] |= InstructionFlags.Reachable;
+ break;
+ case ByteCodeFlowControl.Return:
+ case ByteCodeFlowControl.Throw:
+ break;
+ case ByteCodeFlowControl.Next:
+ flags[index + 1] |= InstructionFlags.Reachable;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+
+ internal static UntangledExceptionTable UntangleExceptionBlocks(ClassFile classFile, ClassFile.Method method)
+ {
+ ClassFile.Method.Instruction[] instructions = method.Instructions;
+ ExceptionTableEntry[] exceptionTable = method.ExceptionTable;
+ List ar = new List(exceptionTable);
+
+ // This optimization removes the recursive exception handlers that Java compiler place around
+ // the exit of a synchronization block to be "safe" in the face of asynchronous exceptions.
+ // (see http://weblog.ikvm.net/PermaLink.aspx?guid=3af9548e-4905-4557-8809-65a205ce2cd6)
+ // We can safely remove them since the code we generate for this construct isn't async safe anyway,
+ // but there is another reason why this optimization may be slightly controversial. In some
+ // pathological cases it can cause observable differences, where the Sun JVM would spin in an
+ // infinite loop, but we will throw an exception. However, the perf benefit is large enough to
+ // warrant this "incompatibility".
+ // Note that there is also code in the exception handler handling code that detects these bytecode
+ // sequences to try to compile them into a fault block, instead of an exception handler.
+ for (int i = 0; i < ar.Count; i++)
+ {
+ ExceptionTableEntry ei = ar[i];
+ if (ei.startIndex == ei.handlerIndex && ei.catch_type == 0)
+ {
+ int index = ei.startIndex;
+ if (index + 2 < instructions.Length
+ && ei.endIndex == index + 2
+ && instructions[index].NormalizedOpCode == NormalizedByteCode.__aload
+ && instructions[index + 1].NormalizedOpCode == NormalizedByteCode.__monitorexit
+ && instructions[index + 2].NormalizedOpCode == NormalizedByteCode.__athrow)
+ {
+ // this is the async exception guard that Jikes and the Eclipse Java Compiler produce
+ ar.RemoveAt(i);
+ i--;
+ }
+ else if (index + 4 < instructions.Length
+ && ei.endIndex == index + 3
+ && instructions[index].NormalizedOpCode == NormalizedByteCode.__astore
+ && instructions[index + 1].NormalizedOpCode == NormalizedByteCode.__aload
+ && instructions[index + 2].NormalizedOpCode == NormalizedByteCode.__monitorexit
+ && instructions[index + 3].NormalizedOpCode == NormalizedByteCode.__aload
+ && instructions[index + 4].NormalizedOpCode == NormalizedByteCode.__athrow
+ && instructions[index].NormalizedArg1 == instructions[index + 3].NormalizedArg1)
+ {
+ // this is the async exception guard that javac produces
+ ar.RemoveAt(i);
+ i--;
+ }
+ else if (index + 1 < instructions.Length
+ && ei.endIndex == index + 1
+ && instructions[index].NormalizedOpCode == NormalizedByteCode.__astore)
+ {
+ // this is the finally guard that javac produces
+ ar.RemoveAt(i);
+ i--;
+ }
+ }
+ }
+
+ // Modern versions of javac split try blocks when the try block contains a return statement.
+ // Here we merge these exception blocks again, because it allows us to generate more efficient code.
+ for (int i = 0; i < ar.Count - 1; i++)
+ {
+ if (ar[i].endIndex + 1 == ar[i + 1].startIndex
+ && ar[i].handlerIndex == ar[i + 1].handlerIndex
+ && ar[i].catch_type == ar[i + 1].catch_type
+ && IsReturn(instructions[ar[i].endIndex].NormalizedOpCode))
+ {
+ ar[i] = new ExceptionTableEntry(ar[i].startIndex, ar[i + 1].endIndex, ar[i].handlerIndex, ar[i].catch_type, ar[i].ordinal);
+ ar.RemoveAt(i + 1);
+ i--;
+ }
+ }
+
+ restart:
+ for (int i = 0; i < ar.Count; i++)
+ {
+ ExceptionTableEntry ei = ar[i];
+ for (int j = 0; j < ar.Count; j++)
+ {
+ ExceptionTableEntry ej = ar[j];
+ if (ei.startIndex <= ej.startIndex && ej.startIndex < ei.endIndex)
+ {
+ // 0006/test.j
+ if (ej.endIndex > ei.endIndex)
+ {
+ ExceptionTableEntry emi = new ExceptionTableEntry(ej.startIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ExceptionTableEntry emj = new ExceptionTableEntry(ej.startIndex, ei.endIndex, ej.handlerIndex, ej.catch_type, ej.ordinal);
+ ei = new ExceptionTableEntry(ei.startIndex, emi.startIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ej = new ExceptionTableEntry(emj.endIndex, ej.endIndex, ej.handlerIndex, ej.catch_type, ej.ordinal);
+ ar[i] = ei;
+ ar[j] = ej;
+ ar.Insert(j, emj);
+ ar.Insert(i + 1, emi);
+ goto restart;
+ }
+ // 0007/test.j
+ else if (j > i && ej.endIndex < ei.endIndex)
+ {
+ ExceptionTableEntry emi = new ExceptionTableEntry(ej.startIndex, ej.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ExceptionTableEntry eei = new ExceptionTableEntry(ej.endIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ei = new ExceptionTableEntry(ei.startIndex, emi.startIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ar[i] = ei;
+ ar.Insert(i + 1, eei);
+ ar.Insert(i + 1, emi);
+ goto restart;
+ }
+ }
+ }
+ }
+ // Split try blocks at branch targets (branches from outside the try block)
+ restart_split:
+ for (int i = 0; i < ar.Count; i++)
+ {
+ ExceptionTableEntry ei = ar[i];
+ int start = ei.startIndex;
+ int end = ei.endIndex;
+ for (int j = 0; j < instructions.Length; j++)
+ {
+ if (j < start || j >= end)
+ {
+ switch (instructions[j].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__tableswitch:
+ case NormalizedByteCode.__lookupswitch:
+ // start at -1 to have an opportunity to handle the default offset
+ for (int k = -1; k < instructions[j].SwitchEntryCount; k++)
+ {
+ int targetIndex = (k == -1 ? instructions[j].DefaultTarget : instructions[j].GetSwitchTargetIndex(k));
+ if (ei.startIndex < targetIndex && targetIndex < ei.endIndex)
+ {
+ ExceptionTableEntry en = new ExceptionTableEntry(targetIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ei = new ExceptionTableEntry(ei.startIndex, targetIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ar[i] = ei;
+ ar.Insert(i + 1, en);
+ goto restart_split;
+ }
+ }
+ break;
+ case NormalizedByteCode.__ifeq:
+ case NormalizedByteCode.__ifne:
+ case NormalizedByteCode.__iflt:
+ case NormalizedByteCode.__ifge:
+ case NormalizedByteCode.__ifgt:
+ case NormalizedByteCode.__ifle:
+ case NormalizedByteCode.__if_icmpeq:
+ case NormalizedByteCode.__if_icmpne:
+ case NormalizedByteCode.__if_icmplt:
+ case NormalizedByteCode.__if_icmpge:
+ case NormalizedByteCode.__if_icmpgt:
+ case NormalizedByteCode.__if_icmple:
+ case NormalizedByteCode.__if_acmpeq:
+ case NormalizedByteCode.__if_acmpne:
+ case NormalizedByteCode.__ifnull:
+ case NormalizedByteCode.__ifnonnull:
+ case NormalizedByteCode.__goto:
+ {
+ int targetIndex = instructions[j].Arg1;
+ if (ei.startIndex < targetIndex && targetIndex < ei.endIndex)
+ {
+ ExceptionTableEntry en = new ExceptionTableEntry(targetIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ei = new ExceptionTableEntry(ei.startIndex, targetIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ar[i] = ei;
+ ar.Insert(i + 1, en);
+ goto restart_split;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ // exception handlers are also a kind of jump, so we need to split try blocks around handlers as well
+ for (int i = 0; i < ar.Count; i++)
+ {
+ ExceptionTableEntry ei = ar[i];
+ for (int j = 0; j < ar.Count; j++)
+ {
+ ExceptionTableEntry ej = ar[j];
+ if (ei.startIndex < ej.handlerIndex && ej.handlerIndex < ei.endIndex)
+ {
+ ExceptionTableEntry en = new ExceptionTableEntry(ej.handlerIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ei = new ExceptionTableEntry(ei.startIndex, ej.handlerIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
+ ar[i] = ei;
+ ar.Insert(i + 1, en);
+ goto restart_split;
+ }
+ }
+ }
+ // filter out zero length try blocks
+ for (int i = 0; i < ar.Count; i++)
+ {
+ ExceptionTableEntry ei = ar[i];
+ if (ei.startIndex == ei.endIndex)
+ {
+ ar.RemoveAt(i);
+ i--;
+ }
+ else
+ {
+ // exception blocks that only contain harmless instructions (i.e. instructions that will *never* throw an exception)
+ // are also filtered out (to improve the quality of the generated code)
+ TypeWrapper exceptionType = ei.catch_type == 0 ? CoreClasses.java.lang.Throwable.Wrapper : classFile.GetConstantPoolClassType(ei.catch_type);
+ if (exceptionType.IsUnloadable)
+ {
+ // we can't remove handlers for unloadable types
+ }
+ else if (java_lang_ThreadDeath.IsAssignableTo(exceptionType))
+ {
+ // We only remove exception handlers that could catch ThreadDeath in limited cases, because it can be thrown
+ // asynchronously (and thus appear on any instruction). This is particularly important to ensure that
+ // we run finally blocks when a thread is killed.
+ // Note that even so, we aren't remotely async exception safe.
+ int start = ei.startIndex;
+ int end = ei.endIndex;
+ for (int j = start; j < end; j++)
+ {
+ switch (instructions[j].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__aload:
+ case NormalizedByteCode.__iload:
+ case NormalizedByteCode.__lload:
+ case NormalizedByteCode.__fload:
+ case NormalizedByteCode.__dload:
+ case NormalizedByteCode.__astore:
+ case NormalizedByteCode.__istore:
+ case NormalizedByteCode.__lstore:
+ case NormalizedByteCode.__fstore:
+ case NormalizedByteCode.__dstore:
+ break;
+ case NormalizedByteCode.__dup:
+ case NormalizedByteCode.__dup_x1:
+ case NormalizedByteCode.__dup_x2:
+ case NormalizedByteCode.__dup2:
+ case NormalizedByteCode.__dup2_x1:
+ case NormalizedByteCode.__dup2_x2:
+ case NormalizedByteCode.__pop:
+ case NormalizedByteCode.__pop2:
+ break;
+ case NormalizedByteCode.__return:
+ case NormalizedByteCode.__areturn:
+ case NormalizedByteCode.__ireturn:
+ case NormalizedByteCode.__lreturn:
+ case NormalizedByteCode.__freturn:
+ case NormalizedByteCode.__dreturn:
+ break;
+ case NormalizedByteCode.__goto:
+ // if there is a branch that stays inside the block, we should keep the block
+ if (start <= instructions[j].TargetIndex && instructions[j].TargetIndex < end)
+ goto next;
+ break;
+ default:
+ goto next;
+ }
+ }
+ ar.RemoveAt(i);
+ i--;
+ }
+ else
+ {
+ int start = ei.startIndex;
+ int end = ei.endIndex;
+ for (int j = start; j < end; j++)
+ {
+ if (ByteCodeMetaData.CanThrowException(instructions[j].NormalizedOpCode))
+ {
+ goto next;
+ }
+ }
+ ar.RemoveAt(i);
+ i--;
+ }
+ }
+ next:;
+ }
+
+ ExceptionTableEntry[] exceptions = ar.ToArray();
+ Array.Sort(exceptions, new ExceptionSorter());
+
+ return new UntangledExceptionTable(exceptions);
+ }
+
+ private static bool IsReturn(NormalizedByteCode bc)
+ {
+ return bc == NormalizedByteCode.__return
+ || bc == NormalizedByteCode.__areturn
+ || bc == NormalizedByteCode.__dreturn
+ || bc == NormalizedByteCode.__ireturn
+ || bc == NormalizedByteCode.__freturn
+ || bc == NormalizedByteCode.__lreturn;
+ }
+
+ private static bool AnalyzePotentialFaultBlocks(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
+ {
+ ClassFile.Method.Instruction[] code = method.Instructions;
+ bool changed = false;
+ bool done = false;
+ while (!done)
+ {
+ done = true;
+ Stack stack = new Stack();
+ ExceptionTableEntry current = new ExceptionTableEntry(0, code.Length, -1, ushort.MaxValue, -1);
+ stack.Push(current);
+ for (int i = 0; i < exceptions.Length; i++)
+ {
+ while (exceptions[i].startIndex >= current.endIndex)
+ {
+ current = stack.Pop();
+ }
+ Debug.Assert(exceptions[i].startIndex >= current.startIndex && exceptions[i].endIndex <= current.endIndex);
+ if (exceptions[i].catch_type == 0
+ && codeInfo.HasState(exceptions[i].handlerIndex)
+ && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0)))
+ {
+ InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(codeInfo, method.Instructions, exceptions, exceptions[i].handlerIndex, true);
+ for (int j = 0; j < code.Length; j++)
+ {
+ if ((flags[j] & InstructionFlags.Reachable) != 0)
+ {
+ switch (code[j].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__return:
+ case NormalizedByteCode.__areturn:
+ case NormalizedByteCode.__ireturn:
+ case NormalizedByteCode.__lreturn:
+ case NormalizedByteCode.__freturn:
+ case NormalizedByteCode.__dreturn:
+ goto not_fault_block;
+ case NormalizedByteCode.__athrow:
+ for (int k = i + 1; k < exceptions.Length; k++)
+ {
+ if (exceptions[k].startIndex <= j && j < exceptions[k].endIndex)
+ {
+ goto not_fault_block;
+ }
+ }
+ if (VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
+ && codeInfo.GetRawStackTypeWrapper(j, 0) != codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0))
+ {
+ goto not_fault_block;
+ }
+ break;
+ }
+ if (j < current.startIndex || j >= current.endIndex)
+ {
+ goto not_fault_block;
+ }
+ else if (exceptions[i].startIndex <= j && j < exceptions[i].endIndex)
+ {
+ goto not_fault_block;
+ }
+ else
+ {
+ continue;
+ }
+ not_fault_block:
+ VerifierTypeWrapper.ClearFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0));
+ done = false;
+ changed = true;
+ break;
+ }
+ }
+ }
+ stack.Push(current);
+ current = exceptions[i];
+ }
+ }
+ return changed;
+ }
+
+ private static void ConvertFinallyBlocks(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
+ {
+ ClassFile.Method.Instruction[] code = method.Instructions;
+ InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, 0, false);
+ for (int i = 0; i < exceptions.Length; i++)
+ {
+ if (exceptions[i].catch_type == 0
+ && codeInfo.HasState(exceptions[i].handlerIndex)
+ && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0)))
+ {
+ int exit;
+ if (IsSynchronizedBlockHandler(code, exceptions[i].handlerIndex)
+ && exceptions[i].endIndex - 2 >= exceptions[i].startIndex
+ && TryFindSingleTryBlockExit(code, flags, exceptions, new ExceptionTableEntry(exceptions[i].startIndex, exceptions[i].endIndex - 2, exceptions[i].handlerIndex, 0, exceptions[i].ordinal), i, out exit)
+ && exit == exceptions[i].endIndex - 2
+ && (flags[exit + 1] & InstructionFlags.BranchTarget) == 0
+ && MatchInstructions(code, exit, exceptions[i].handlerIndex + 1)
+ && MatchInstructions(code, exit + 1, exceptions[i].handlerIndex + 2)
+ && MatchExceptionCoverage(exceptions, i, exceptions[i].handlerIndex + 1, exceptions[i].handlerIndex + 3, exit, exit + 2)
+ && exceptions[i].handlerIndex <= ushort.MaxValue)
+ {
+ code[exit].PatchOpCode(NormalizedByteCode.__goto_finally, exceptions[i].endIndex, (short)exceptions[i].handlerIndex);
+ exceptions.SetFinally(i);
+ }
+ else if (TryFindSingleTryBlockExit(code, flags, exceptions, exceptions[i], i, out exit)
+ // the stack must be empty
+ && codeInfo.GetStackHeight(exit) == 0
+ // the exit code must not be reachable (except from within the try-block),
+ // because we're going to patch it to jump around the exit code
+ && !IsReachableFromOutsideTryBlock(codeInfo, code, exceptions, exceptions[i], exit))
+ {
+ int exitHandlerEnd;
+ int faultHandlerEnd;
+ if (MatchFinallyBlock(codeInfo, code, exceptions, exceptions[i].handlerIndex, exit, out exitHandlerEnd, out faultHandlerEnd))
+ {
+ if (exit != exitHandlerEnd
+ && codeInfo.GetStackHeight(exitHandlerEnd) == 0
+ && MatchExceptionCoverage(exceptions, -1, exceptions[i].handlerIndex, faultHandlerEnd, exit, exitHandlerEnd))
+ {
+ // We use Arg2 (which is a short) to store the handler in the __goto_finally pseudo-opcode,
+ // so we can only do that if handlerIndex fits in a short (note that we can use the sign bit too).
+ if (exceptions[i].handlerIndex <= ushort.MaxValue)
+ {
+ code[exit].PatchOpCode(NormalizedByteCode.__goto_finally, exitHandlerEnd, (short)exceptions[i].handlerIndex);
+ exceptions.SetFinally(i);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static bool IsSynchronizedBlockHandler(ClassFile.Method.Instruction[] code, int index)
+ {
+ return code[index].NormalizedOpCode == NormalizedByteCode.__astore
+ && code[index + 1].NormalizedOpCode == NormalizedByteCode.__aload
+ && code[index + 2].NormalizedOpCode == NormalizedByteCode.__monitorexit
+ && code[index + 3].NormalizedOpCode == NormalizedByteCode.__aload && code[index + 3].Arg1 == code[index].Arg1
+ && code[index + 4].NormalizedOpCode == NormalizedByteCode.__athrow;
+ }
+
+ private static bool MatchExceptionCoverage(UntangledExceptionTable exceptions, int skipException, int startFault, int endFault, int startExit, int endExit)
+ {
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (j != skipException && ExceptionCovers(exceptions[j], startFault, endFault) != ExceptionCovers(exceptions[j], startExit, endExit))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static bool ExceptionCovers(ExceptionTableEntry exception, int start, int end)
+ {
+ return exception.startIndex < end && exception.endIndex > start;
+ }
+
+ private static bool MatchFinallyBlock(CodeInfo codeInfo, ClassFile.Method.Instruction[] code, UntangledExceptionTable exceptions, int faultHandler, int exitHandler, out int exitHandlerEnd, out int faultHandlerEnd)
+ {
+ exitHandlerEnd = -1;
+ faultHandlerEnd = -1;
+ if (code[faultHandler].NormalizedOpCode != NormalizedByteCode.__astore)
+ {
+ return false;
+ }
+ int startFault = faultHandler;
+ int faultLocal = code[faultHandler++].NormalizedArg1;
+ for (; ; )
+ {
+ if (code[faultHandler].NormalizedOpCode == NormalizedByteCode.__aload
+ && code[faultHandler].NormalizedArg1 == faultLocal
+ && code[faultHandler + 1].NormalizedOpCode == NormalizedByteCode.__athrow)
+ {
+ // make sure that instructions that we haven't covered aren't reachable
+ InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, startFault, false);
+ for (int i = 0; i < flags.Length; i++)
+ {
+ if ((i < startFault || i > faultHandler + 1) && (flags[i] & InstructionFlags.Reachable) != 0)
+ {
+ return false;
+ }
+ }
+ exitHandlerEnd = exitHandler;
+ faultHandlerEnd = faultHandler;
+ return true;
+ }
+ if (!MatchInstructions(code, faultHandler, exitHandler))
+ {
+ return false;
+ }
+ faultHandler++;
+ exitHandler++;
+ }
+ }
+
+ private static bool MatchInstructions(ClassFile.Method.Instruction[] code, int i, int j)
+ {
+ if (code[i].NormalizedOpCode != code[j].NormalizedOpCode)
+ {
+ return false;
+ }
+ switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Branch:
+ case ByteCodeFlowControl.CondBranch:
+ if (code[i].Arg1 - i != code[j].Arg1 - j)
+ {
+ return false;
+ }
+ break;
+ case ByteCodeFlowControl.Switch:
+ if (code[i].SwitchEntryCount != code[j].SwitchEntryCount)
+ {
+ return false;
+ }
+ for (int k = 0; k < code[i].SwitchEntryCount; k++)
+ {
+ if (code[i].GetSwitchTargetIndex(k) != code[j].GetSwitchTargetIndex(k))
+ {
+ return false;
+ }
+ }
+ if (code[i].DefaultTarget != code[j].DefaultTarget)
+ {
+ return false;
+ }
+ break;
+ default:
+ if (code[i].Arg1 != code[j].Arg1)
+ {
+ return false;
+ }
+ if (code[i].Arg2 != code[j].Arg2)
+ {
+ return false;
+ }
+ break;
+ }
+ return true;
+ }
+
+ private static bool IsReachableFromOutsideTryBlock(CodeInfo codeInfo, ClassFile.Method.Instruction[] code, UntangledExceptionTable exceptions, ExceptionTableEntry tryBlock, int instructionIndex)
+ {
+ InstructionFlags[] flags = new InstructionFlags[code.Length];
+ flags[0] |= InstructionFlags.Reachable;
+ // We mark the first instruction of the try-block as already processed, so that UpdatePartialReachability will skip the try-block.
+ // Note that we can do this, because it is not possible to jump into the middle of a try-block (after the exceptions have been untangled).
+ flags[tryBlock.startIndex] = InstructionFlags.Processed;
+ // We mark the successor instructions of the instruction we're examinining as reachable,
+ // to figure out if the code following the handler somehow branches back to it.
+ MarkSuccessors(code, flags, instructionIndex);
+ UpdatePartialReachability(flags, codeInfo, code, exceptions, false);
+ return (flags[instructionIndex] & InstructionFlags.Reachable) != 0;
+ }
+
+ private static bool TryFindSingleTryBlockExit(ClassFile.Method.Instruction[] code, InstructionFlags[] flags, UntangledExceptionTable exceptions, ExceptionTableEntry exception, int exceptionIndex, out int exit)
+ {
+ exit = -1;
+ bool fail = false;
+ bool nextIsReachable = false;
+ for (int i = exception.startIndex; !fail && i < exception.endIndex; i++)
+ {
+ if ((flags[i] & InstructionFlags.Reachable) != 0)
+ {
+ nextIsReachable = false;
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (j != exceptionIndex && exceptions[j].startIndex >= exception.startIndex && exception.endIndex <= exceptions[j].endIndex)
+ {
+ UpdateTryBlockExit(exception, exceptions[j].handlerIndex, ref exit, ref fail);
+ }
+ }
+ switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Switch:
+ {
+ for (int j = 0; j < code[i].SwitchEntryCount; j++)
+ {
+ UpdateTryBlockExit(exception, code[i].GetSwitchTargetIndex(j), ref exit, ref fail);
+ }
+ UpdateTryBlockExit(exception, code[i].DefaultTarget, ref exit, ref fail);
+ break;
+ }
+ case ByteCodeFlowControl.Branch:
+ UpdateTryBlockExit(exception, code[i].TargetIndex, ref exit, ref fail);
+ break;
+ case ByteCodeFlowControl.CondBranch:
+ UpdateTryBlockExit(exception, code[i].TargetIndex, ref exit, ref fail);
+ nextIsReachable = true;
+ break;
+ case ByteCodeFlowControl.Return:
+ fail = true;
+ break;
+ case ByteCodeFlowControl.Throw:
+ break;
+ case ByteCodeFlowControl.Next:
+ nextIsReachable = true;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+ if (nextIsReachable)
+ {
+ UpdateTryBlockExit(exception, exception.endIndex, ref exit, ref fail);
+ }
+ return !fail && exit != -1;
+ }
+
+ private static void UpdateTryBlockExit(ExceptionTableEntry exception, int targetIndex, ref int exitIndex, ref bool fail)
+ {
+ if (exception.startIndex <= targetIndex && targetIndex < exception.endIndex)
+ {
+ // branch stays inside try block
+ }
+ else if (exitIndex == -1)
+ {
+ exitIndex = targetIndex;
+ }
+ else if (exitIndex != targetIndex)
+ {
+ fail = true;
+ }
+ }
+
+ private void ConditionalPatchNoClassDefFoundError(ref ClassFile.Method.Instruction instruction, TypeWrapper tw)
+ {
+ ClassLoaderWrapper loader = wrapper.GetClassLoader();
+ if (loader.DisableDynamicBinding)
+ {
+ SetHardError(loader, ref instruction, HardError.NoClassDefFoundError, "{0}", tw.Name);
+ }
+ }
+
+ private void SetHardError(ClassLoaderWrapper classLoader, ref ClassFile.Method.Instruction instruction, HardError hardError, string message, params object[] args)
+ {
+ string text = string.Format(message, args);
+#if IMPORTER
+ Message msg;
+ switch (hardError)
+ {
+ case HardError.NoClassDefFoundError:
+ msg = Message.EmittedNoClassDefFoundError;
+ break;
+ case HardError.IllegalAccessError:
+ msg = Message.EmittedIllegalAccessError;
+ break;
+ case HardError.InstantiationError:
+ msg = Message.EmittedIllegalAccessError;
+ break;
+ case HardError.IncompatibleClassChangeError:
+ case HardError.IllegalAccessException:
+ msg = Message.EmittedIncompatibleClassChangeError;
+ break;
+ case HardError.NoSuchFieldError:
+ msg = Message.EmittedNoSuchFieldError;
+ break;
+ case HardError.AbstractMethodError:
+ msg = Message.EmittedAbstractMethodError;
+ break;
+ case HardError.NoSuchMethodError:
+ msg = Message.EmittedNoSuchMethodError;
+ break;
+ case HardError.LinkageError:
+ msg = Message.EmittedLinkageError;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ classLoader.IssueMessage(msg, classFile.Name + "." + method.Name + method.Signature, text);
+#endif
+ instruction.SetHardError(hardError, AllocErrorMessage(text));
+ }
+
+ private void PatchInvoke(TypeWrapper wrapper, ref ClassFile.Method.Instruction instr, StackState stack)
+ {
+ ClassFile.ConstantPoolItemMI cpi = GetMethodref(instr.Arg1);
+ NormalizedByteCode invoke = instr.NormalizedOpCode;
+ bool isnew = false;
+ TypeWrapper thisType;
+ if (invoke == NormalizedByteCode.__invokevirtual
+ && cpi.Class == "java.lang.invoke.MethodHandle"
+ && (cpi.Name == "invoke" || cpi.Name == "invokeExact" || cpi.Name == "invokeBasic"))
+ {
+ if (cpi.GetArgTypes().Length > 127 && MethodHandleUtil.SlotCount(cpi.GetArgTypes()) > 254)
+ {
+ instr.SetHardError(HardError.LinkageError, AllocErrorMessage("bad parameter count"));
+ return;
+ }
+ instr.PatchOpCode(NormalizedByteCode.__methodhandle_invoke);
+ return;
+ }
+ else if (invoke == NormalizedByteCode.__invokestatic
+ && cpi.Class == "java.lang.invoke.MethodHandle"
+ && (cpi.Name == "linkToVirtual" || cpi.Name == "linkToStatic" || cpi.Name == "linkToSpecial" || cpi.Name == "linkToInterface")
+ && CoreClasses.java.lang.invoke.MethodHandle.Wrapper.IsPackageAccessibleFrom(wrapper))
+ {
+ instr.PatchOpCode(NormalizedByteCode.__methodhandle_link);
+ return;
+ }
+ else if (invoke == NormalizedByteCode.__invokestatic)
+ {
+ thisType = null;
+ }
+ else
+ {
+ TypeWrapper[] args = cpi.GetArgTypes();
+ for (int j = args.Length - 1; j >= 0; j--)
+ {
+ stack.PopType(args[j]);
+ }
+ thisType = SigTypeToClassName(stack.PeekType(), cpi.GetClassType(), wrapper);
+ if (ReferenceEquals(cpi.Name, StringConstants.INIT))
+ {
+ TypeWrapper type = stack.PopType();
+ isnew = VerifierTypeWrapper.IsNew(type);
+ }
+ }
+
+ if (cpi.GetClassType().IsUnloadable)
+ {
+ if (wrapper.GetClassLoader().DisableDynamicBinding)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name);
+ }
+ else
+ {
+ switch (invoke)
+ {
+ case NormalizedByteCode.__invokeinterface:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_invokeinterface);
+ break;
+ case NormalizedByteCode.__invokestatic:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_invokestatic);
+ break;
+ case NormalizedByteCode.__invokevirtual:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_invokevirtual);
+ break;
+ case NormalizedByteCode.__invokespecial:
+ if (isnew)
+ {
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_invokespecial);
+ }
+ else
+ {
+ throw new VerifyError("Invokespecial cannot call subclass methods");
+ }
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+ else if (invoke == NormalizedByteCode.__invokeinterface && !cpi.GetClassType().IsInterface)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "invokeinterface on non-interface");
+ }
+ else if (cpi.GetClassType().IsInterface && invoke != NormalizedByteCode.__invokeinterface && ((invoke != NormalizedByteCode.__invokestatic && invoke != NormalizedByteCode.__invokespecial) || classFile.MajorVersion < 52))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError,
+ classFile.MajorVersion < 52
+ ? "interface method must be invoked using invokeinterface"
+ : "interface method must be invoked using invokeinterface, invokespecial or invokestatic");
+ }
+ else
+ {
+ MethodWrapper targetMethod = invoke == NormalizedByteCode.__invokespecial ? cpi.GetMethodForInvokespecial() : cpi.GetMethod();
+ if (targetMethod != null)
+ {
+ string errmsg = CheckLoaderConstraints(cpi, targetMethod);
+ if (errmsg != null)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "{0}", errmsg);
+ }
+ else if (targetMethod.IsStatic == (invoke == NormalizedByteCode.__invokestatic))
+ {
+ if (targetMethod.IsAbstract && invoke == NormalizedByteCode.__invokespecial && (targetMethod.GetMethod() == null || targetMethod.GetMethod().IsAbstract))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.AbstractMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
+ }
+ else if (invoke == NormalizedByteCode.__invokeinterface && targetMethod.IsPrivate)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "private interface method requires invokespecial, not invokeinterface: method {0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
+ }
+ else if (targetMethod.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType))
+ {
+ return;
+ }
+ else if (host != null && targetMethod.IsAccessibleFrom(cpi.GetClassType(), host, thisType))
+ {
+ switch (invoke)
+ {
+ case NormalizedByteCode.__invokespecial:
+ instr.PatchOpCode(NormalizedByteCode.__privileged_invokespecial);
+ break;
+ case NormalizedByteCode.__invokestatic:
+ instr.PatchOpCode(NormalizedByteCode.__privileged_invokestatic);
+ break;
+ case NormalizedByteCode.__invokevirtual:
+ instr.PatchOpCode(NormalizedByteCode.__privileged_invokevirtual);
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ return;
+ }
+ else
+ {
+ // NOTE special case for incorrect invocation of Object.clone(), because this could mean
+ // we're calling clone() on an array
+ // (bug in javac, see http://developer.java.sun.com/developer/bugParade/bugs/4329886.html)
+ if (cpi.GetClassType() == CoreClasses.java.lang.Object.Wrapper
+ && thisType.IsArray
+ && ReferenceEquals(cpi.Name, StringConstants.CLONE))
+ {
+ // Patch the instruction, so that the compiler doesn't need to do this test again.
+ instr.PatchOpCode(NormalizedByteCode.__clone_array);
+ return;
+ }
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access method {0}.{1}{2} from class {3}", ToSlash(targetMethod.DeclaringType.Name), cpi.Name, ToSlash(cpi.Signature), ToSlash(wrapper.Name));
+ }
+ }
+ else
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "static call to non-static method (or v.v.)");
+ }
+ }
+ else
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
+ }
+ }
+ }
+
+ private static string ToSlash(string str)
+ {
+ return str.Replace('.', '/');
+ }
+
+ private void PatchFieldAccess(TypeWrapper wrapper, MethodWrapper mw, ref ClassFile.Method.Instruction instr, StackState stack)
+ {
+ ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1);
+ bool isStatic;
+ bool write;
+ TypeWrapper thisType;
+ switch (instr.NormalizedOpCode)
+ {
+ case NormalizedByteCode.__getfield:
+ isStatic = false;
+ write = false;
+ thisType = SigTypeToClassName(stack.PopObjectType(GetFieldref(instr.Arg1).GetClassType()), cpi.GetClassType(), wrapper);
+ break;
+ case NormalizedByteCode.__putfield:
+ stack.PopType(GetFieldref(instr.Arg1).GetFieldType());
+ isStatic = false;
+ write = true;
+ // putfield is allowed to access the unintialized this
+ if (stack.PeekType() == VerifierTypeWrapper.UninitializedThis
+ && wrapper.IsAssignableTo(GetFieldref(instr.Arg1).GetClassType()))
+ {
+ thisType = wrapper;
+ }
+ else
+ {
+ thisType = SigTypeToClassName(stack.PopObjectType(GetFieldref(instr.Arg1).GetClassType()), cpi.GetClassType(), wrapper);
+ }
+ break;
+ case NormalizedByteCode.__getstatic:
+ isStatic = true;
+ write = false;
+ thisType = null;
+ break;
+ case NormalizedByteCode.__putstatic:
+ // special support for when we're being called from IsSideEffectFreeStaticInitializer
+ if (mw == null)
+ {
+ switch (GetFieldref(instr.Arg1).Signature[0])
+ {
+ case 'B':
+ case 'Z':
+ case 'C':
+ case 'S':
+ case 'I':
+ stack.PopInt();
+ break;
+ case 'F':
+ stack.PopFloat();
+ break;
+ case 'D':
+ stack.PopDouble();
+ break;
+ case 'J':
+ stack.PopLong();
+ break;
+ case 'L':
+ case '[':
+ if (stack.PopAnyType() != VerifierTypeWrapper.Null)
+ {
+ throw new VerifyError();
+ }
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ else
+ {
+ stack.PopType(GetFieldref(instr.Arg1).GetFieldType());
+ }
+ isStatic = true;
+ write = true;
+ thisType = null;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ if (mw == null)
+ {
+ // We're being called from IsSideEffectFreeStaticInitializer,
+ // no further checks are possible (nor needed).
+ }
+ else if (cpi.GetClassType().IsUnloadable)
+ {
+ if (wrapper.GetClassLoader().DisableDynamicBinding)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name);
+ }
+ else
+ {
+ switch (instr.NormalizedOpCode)
+ {
+ case NormalizedByteCode.__getstatic:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_getstatic);
+ break;
+ case NormalizedByteCode.__putstatic:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_putstatic);
+ break;
+ case NormalizedByteCode.__getfield:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_getfield);
+ break;
+ case NormalizedByteCode.__putfield:
+ instr.PatchOpCode(NormalizedByteCode.__dynamic_putfield);
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ return;
+ }
+ else
+ {
+ FieldWrapper field = cpi.GetField();
+ if (field == null)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchFieldError, "{0}.{1}", cpi.Class, cpi.Name);
+ return;
+ }
+ if (false && cpi.GetFieldType() != field.FieldTypeWrapper && !cpi.GetFieldType().IsUnloadable & !field.FieldTypeWrapper.IsUnloadable)
+ {
+#if IMPORTER
+ StaticCompiler.LinkageError("Field \"{2}.{3}\" is of type \"{0}\" instead of type \"{1}\" as expected by \"{4}\"", field.FieldTypeWrapper, cpi.GetFieldType(), cpi.GetClassType().Name, cpi.Name, wrapper.Name);
+#endif
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "Loader constraints violated: {0}.{1}", field.DeclaringType.Name, field.Name);
+ return;
+ }
+ if (field.IsStatic != isStatic)
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "Static field access to non-static field (or v.v.)");
+ return;
+ }
+ if (!field.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Try to access field {0}.{1} from class {2}", field.DeclaringType.Name, field.Name, wrapper.Name);
+ return;
+ }
+ // are we trying to mutate a final field? (they are read-only from outside of the defining class)
+ if (write && field.IsFinal
+ && ((isStatic ? wrapper != cpi.GetClassType() : wrapper != thisType) || (wrapper.GetClassLoader().StrictFinalFieldSemantics && (isStatic ? (mw != null && mw.Name != "") : (mw == null || mw.Name != "")))))
+ {
+ SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Field {0}.{1} is final", field.DeclaringType.Name, field.Name);
+ return;
+ }
+ }
+ }
+
+ // TODO this method should have a better name
+ private TypeWrapper SigTypeToClassName(TypeWrapper type, TypeWrapper nullType, TypeWrapper wrapper)
+ {
+ if (type == VerifierTypeWrapper.UninitializedThis)
+ {
+ return wrapper;
+ }
+ else if (VerifierTypeWrapper.IsNew(type))
+ {
+ return ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ else if (type == VerifierTypeWrapper.Null)
+ {
+ return nullType;
+ }
+ else
+ {
+ return type;
+ }
+ }
+
+ private int AllocErrorMessage(string message)
+ {
+ if (errorMessages == null)
+ {
+ errorMessages = new List();
+ }
+ int index = errorMessages.Count;
+ errorMessages.Add(message);
+ return index;
+ }
+
+ private string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, MethodWrapper mw)
+ {
+#if NETFRAMEWORK
+ if (cpi.GetRetType() != mw.ReturnType && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable)
+#else
+ if (cpi.GetRetType() != mw.ReturnType && cpi.GetRetType().Name != mw.ReturnType.Name && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable)
+#endif
+ {
+#if IMPORTER
+ StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", mw.ReturnType, cpi.GetRetType(), cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name);
+#endif
+ return "Loader constraints violated (return type): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature;
+ }
+ TypeWrapper[] here = cpi.GetArgTypes();
+ TypeWrapper[] there = mw.GetParameters();
+ for (int i = 0; i < here.Length; i++)
+ {
+#if NETFRAMEWORK
+ if (here[i] != there[i] && !here[i].IsUnloadable && !there[i].IsUnloadable)
+#else
+ if (here[i] != there[i] && here[i].Name != there[i].Name && !here[i].IsUnloadable && !there[i].IsUnloadable)
+#endif
+ {
+#if IMPORTER
+ StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a argument type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", there[i], here[i], cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name);
+#endif
+ return "Loader constraints violated (arg " + i + "): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature;
+ }
+ }
+ return null;
+ }
+
+ private ClassFile.ConstantPoolItemInvokeDynamic GetInvokeDynamic(int index)
+ {
+ try
+ {
+ ClassFile.ConstantPoolItemInvokeDynamic item = classFile.GetInvokeDynamic(index);
+ if (item != null)
+ {
+ return item;
+ }
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (IndexOutOfRangeException)
+ {
+ }
+ throw new VerifyError("Illegal constant pool index");
+ }
+
+ private ClassFile.ConstantPoolItemMI GetMethodref(int index)
+ {
+ try
+ {
+ ClassFile.ConstantPoolItemMI item = classFile.GetMethodref(index);
+ if (item != null)
+ {
+ return item;
+ }
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (IndexOutOfRangeException)
+ {
+ }
+ throw new VerifyError("Illegal constant pool index");
+ }
+
+ private ClassFile.ConstantPoolItemFieldref GetFieldref(int index)
+ {
+ try
+ {
+ ClassFile.ConstantPoolItemFieldref item = classFile.GetFieldref(index);
+ if (item != null)
+ {
+ return item;
+ }
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (IndexOutOfRangeException)
+ {
+ }
+ throw new VerifyError("Illegal constant pool index");
+ }
+
+ private ClassFile.ConstantType GetConstantPoolConstantType(int index)
+ {
+ try
+ {
+ return classFile.GetConstantPoolConstantType(index);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ // constant pool index out of range
+ }
+ catch (InvalidOperationException)
+ {
+ // specified constant pool entry doesn't contain a constant
+ }
+ catch (NullReferenceException)
+ {
+ // specified constant pool entry is empty (entry 0 or the filler following a wide entry)
+ }
+ throw new VerifyError("Illegal constant pool index");
+ }
+
+ private TypeWrapper GetConstantPoolClassType(int index)
+ {
+ try
+ {
+ return classFile.GetConstantPoolClassType(index);
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (IndexOutOfRangeException)
+ {
+ }
+ catch (NullReferenceException)
+ {
+ }
+ throw new VerifyError("Illegal constant pool index");
+ }
+
+ internal void ClearFaultBlockException(int instructionIndex)
+ {
+ Debug.Assert(state[instructionIndex].GetStackHeight() == 1);
+ state[instructionIndex].ClearFaultBlockException();
+ }
+
+ private static void DumpMethod(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
+ {
+ ClassFile.Method.Instruction[] code = method.Instructions;
+ InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, 0, false);
+ for (int i = 0; i < code.Length; i++)
+ {
+ bool label = (flags[i] & InstructionFlags.BranchTarget) != 0;
+ if (!label)
+ {
+ for (int j = 0; j < exceptions.Length; j++)
+ {
+ if (exceptions[j].startIndex == i
+ || exceptions[j].endIndex == i
+ || exceptions[j].handlerIndex == i)
+ {
+ label = true;
+ break;
+ }
+ }
+ }
+ if (label)
+ {
+ Console.WriteLine("label{0}:", i);
+ }
+ if ((flags[i] & InstructionFlags.Reachable) != 0)
+ {
+ Console.Write(" {1}", i, code[i].NormalizedOpCode.ToString().Substring(2));
+ switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
+ {
+ case ByteCodeFlowControl.Branch:
+ case ByteCodeFlowControl.CondBranch:
+ Console.Write(" label{0}", code[i].Arg1);
+ break;
+ }
+ switch (code[i].NormalizedOpCode)
+ {
+ case NormalizedByteCode.__iload:
+ case NormalizedByteCode.__lload:
+ case NormalizedByteCode.__fload:
+ case NormalizedByteCode.__dload:
+ case NormalizedByteCode.__aload:
+ case NormalizedByteCode.__istore:
+ case NormalizedByteCode.__lstore:
+ case NormalizedByteCode.__fstore:
+ case NormalizedByteCode.__dstore:
+ case NormalizedByteCode.__astore:
+ case NormalizedByteCode.__iconst:
+ Console.Write(" {0}", code[i].Arg1);
+ break;
+ case NormalizedByteCode.__ldc:
+ case NormalizedByteCode.__ldc_nothrow:
+ case NormalizedByteCode.__getfield:
+ case NormalizedByteCode.__getstatic:
+ case NormalizedByteCode.__putfield:
+ case NormalizedByteCode.__putstatic:
+ case NormalizedByteCode.__invokeinterface:
+ case NormalizedByteCode.__invokespecial:
+ case NormalizedByteCode.__invokestatic:
+ case NormalizedByteCode.__invokevirtual:
+ case NormalizedByteCode.__new:
+ Console.Write(" #{0}", code[i].Arg1);
+ break;
+ }
+ Console.WriteLine();
+ }
+ }
+ for (int i = 0; i < exceptions.Length; i++)
+ {
+ Console.WriteLine(".catch #{0} from label{1} to label{2} using label{3}", exceptions[i].catch_type, exceptions[i].startIndex, exceptions[i].endIndex, exceptions[i].handlerIndex);
+ }
+ }
+ }
+
+}
diff --git a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs
index 0545289ae7..09046e0321 100644
--- a/src/IKVM.Runtime/MethodHandleUtil.compiler.cs
+++ b/src/IKVM.Runtime/MethodHandleUtil.compiler.cs
@@ -3,101 +3,104 @@
#if IMPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+
using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
using System.Reflection.Emit;
#endif
-using IKVM.Internal;
-
-static partial class MethodHandleUtil
+namespace IKVM.Runtime
{
- internal static void EmitCallDelegateInvokeMethod(CodeEmitter ilgen, Type delegateType)
+ static partial class MethodHandleUtil
{
- if (delegateType.IsGenericType)
+
+ internal static void EmitCallDelegateInvokeMethod(CodeEmitter ilgen, Type delegateType)
{
- // MONOBUG we don't look at the invoke method directly here, because Mono doesn't support GetParameters() on a builder instantiation
- Type[] typeArgs = delegateType.GetGenericArguments();
- if (IsPackedArgsContainer(typeArgs[typeArgs.Length - 1]))
- {
- WrapArgs(ilgen, typeArgs[typeArgs.Length - 1]);
- }
- else if (typeArgs.Length > 2 && IsPackedArgsContainer(typeArgs[typeArgs.Length - 2]))
+ if (delegateType.IsGenericType)
{
- WrapArgs(ilgen, typeArgs[typeArgs.Length - 2]);
+ // MONOBUG we don't look at the invoke method directly here, because Mono doesn't support GetParameters() on a builder instantiation
+ Type[] typeArgs = delegateType.GetGenericArguments();
+ if (IsPackedArgsContainer(typeArgs[typeArgs.Length - 1]))
+ {
+ WrapArgs(ilgen, typeArgs[typeArgs.Length - 1]);
+ }
+ else if (typeArgs.Length > 2 && IsPackedArgsContainer(typeArgs[typeArgs.Length - 2]))
+ {
+ WrapArgs(ilgen, typeArgs[typeArgs.Length - 2]);
+ }
}
+ ilgen.Emit(OpCodes.Callvirt, GetDelegateInvokeMethod(delegateType));
}
- ilgen.Emit(OpCodes.Callvirt, GetDelegateInvokeMethod(delegateType));
- }
- private static void WrapArgs(CodeEmitter ilgen, Type type)
- {
- Type last = type.GetGenericArguments()[MaxArity - 1];
- if (IsPackedArgsContainer(last))
+ private static void WrapArgs(CodeEmitter ilgen, Type type)
{
- WrapArgs(ilgen, last);
+ Type last = type.GetGenericArguments()[MaxArity - 1];
+ if (IsPackedArgsContainer(last))
+ {
+ WrapArgs(ilgen, last);
+ }
+ ilgen.Emit(OpCodes.Newobj, GetDelegateOrPackedArgsConstructor(type));
}
- ilgen.Emit(OpCodes.Newobj, GetDelegateOrPackedArgsConstructor(type));
- }
- internal static MethodInfo GetDelegateInvokeMethod(Type delegateType)
- {
- if (ReflectUtil.ContainsTypeBuilder(delegateType))
- {
- return TypeBuilder.GetMethod(delegateType, delegateType.GetGenericTypeDefinition().GetMethod("Invoke"));
- }
- else
+ internal static MethodInfo GetDelegateInvokeMethod(Type delegateType)
{
- return delegateType.GetMethod("Invoke");
+ if (ReflectUtil.ContainsTypeBuilder(delegateType))
+ {
+ return TypeBuilder.GetMethod(delegateType, delegateType.GetGenericTypeDefinition().GetMethod("Invoke"));
+ }
+ else
+ {
+ return delegateType.GetMethod("Invoke");
+ }
}
- }
- internal static ConstructorInfo GetDelegateConstructor(Type delegateType)
- {
- return GetDelegateOrPackedArgsConstructor(delegateType);
- }
-
- private static ConstructorInfo GetDelegateOrPackedArgsConstructor(Type type)
- {
- if (ReflectUtil.ContainsTypeBuilder(type))
+ internal static ConstructorInfo GetDelegateConstructor(Type delegateType)
{
- return TypeBuilder.GetConstructor(type, type.GetGenericTypeDefinition().GetConstructors()[0]);
+ return GetDelegateOrPackedArgsConstructor(delegateType);
}
- else
- {
- return type.GetConstructors()[0];
- }
- }
- // for delegate types used for "ldc " we don't want ghost arrays to be erased
- internal static Type CreateDelegateTypeForLoadConstant(TypeWrapper[] args, TypeWrapper ret)
- {
- Type[] typeArgs = new Type[args.Length];
- for (int i = 0; i < args.Length; i++)
+ private static ConstructorInfo GetDelegateOrPackedArgsConstructor(Type type)
{
- typeArgs[i] = TypeWrapperToTypeForLoadConstant(args[i]);
+ if (ReflectUtil.ContainsTypeBuilder(type))
+ {
+ return TypeBuilder.GetConstructor(type, type.GetGenericTypeDefinition().GetConstructors()[0]);
+ }
+ else
+ {
+ return type.GetConstructors()[0];
+ }
}
- return CreateDelegateType(typeArgs, TypeWrapperToTypeForLoadConstant(ret));
- }
- private static Type TypeWrapperToTypeForLoadConstant(TypeWrapper tw)
- {
- if (tw.IsGhostArray)
+ // for delegate types used for "ldc " we don't want ghost arrays to be erased
+ internal static Type CreateDelegateTypeForLoadConstant(TypeWrapper[] args, TypeWrapper ret)
{
- int dims = tw.ArrayRank;
- while (tw.IsArray)
+ Type[] typeArgs = new Type[args.Length];
+ for (int i = 0; i < args.Length; i++)
{
- tw = tw.ElementTypeWrapper;
+ typeArgs[i] = TypeWrapperToTypeForLoadConstant(args[i]);
}
- return ArrayTypeWrapper.MakeArrayType(tw.TypeAsSignatureType, dims);
+ return CreateDelegateType(typeArgs, TypeWrapperToTypeForLoadConstant(ret));
}
- else
+
+ private static Type TypeWrapperToTypeForLoadConstant(TypeWrapper tw)
{
- return tw.TypeAsSignatureType;
+ if (tw.IsGhostArray)
+ {
+ int dims = tw.ArrayRank;
+ while (tw.IsArray)
+ {
+ tw = tw.ElementTypeWrapper;
+ }
+ return ArrayTypeWrapper.MakeArrayType(tw.TypeAsSignatureType, dims);
+ }
+ else
+ {
+ return tw.TypeAsSignatureType;
+ }
}
+
}
}
-
diff --git a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs
index ac172202e3..8eb6f88f29 100644
--- a/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs
+++ b/src/IKVM.Runtime/MethodHandleUtil.jniexport.cs
@@ -21,320 +21,321 @@ Jeroen Frijters
jeroen@frijters.net
*/
-#if !IMPORTER
+#if IMPORTER == false
using System;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
-using IKVM.Internal;
-using IKVM.Runtime;
-
-static partial class MethodHandleUtil
+namespace IKVM.Runtime
{
- internal static Type GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType type)
+ static partial class MethodHandleUtil
{
+
+ internal static Type GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType type)
+ {
#if FIRST_PASS
- return null;
+ throw new NotImplementedException();
#else
- return GetDelegateTypeForInvokeExact(type.basicType());
+ return GetDelegateTypeForInvokeExact(type.basicType());
#endif
- }
-
-#if !FIRST_PASS
- private static Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type)
- {
- TypeWrapper[] args = new TypeWrapper[type.parameterCount()];
- for (int i = 0; i < args.Length; i++)
- {
- args[i] = TypeWrapper.FromClass(type.parameterType(i));
- args[i].Finish();
- }
- TypeWrapper ret = TypeWrapper.FromClass(type.returnType());
- ret.Finish();
- return CreateMethodHandleDelegateType(args, ret);
- }
-
- private static Type[] GetParameterTypes(MethodBase mb)
- {
- ParameterInfo[] pi = mb.GetParameters();
- Type[] args = new Type[pi.Length];
- for (int i = 0; i < args.Length; i++)
- {
- args[i] = pi[i].ParameterType;
}
- return args;
- }
- internal static Type[] GetParameterTypes(Type thisType, MethodBase mb)
- {
- ParameterInfo[] pi = mb.GetParameters();
- Type[] args = new Type[pi.Length + 1];
- args[0] = thisType;
- for (int i = 1; i < args.Length; i++)
- {
- args[i] = pi[i - 1].ParameterType;
- }
- return args;
- }
+#if FIRST_PASS == false
- internal static java.lang.invoke.MethodType GetDelegateMethodType(Type type)
- {
- java.lang.Class[] types;
- MethodInfo mi = GetDelegateInvokeMethod(type);
- ParameterInfo[] pi = mi.GetParameters();
- if (pi.Length > 0 && IsPackedArgsContainer(pi[pi.Length - 1].ParameterType))
+ private static Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type)
{
- System.Collections.Generic.List list = new System.Collections.Generic.List();
- for (int i = 0; i < pi.Length - 1; i++)
- {
- list.Add(ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject);
- }
- Type[] args = pi[pi.Length - 1].ParameterType.GetGenericArguments();
- while (IsPackedArgsContainer(args[args.Length - 1]))
- {
- for (int i = 0; i < args.Length - 1; i++)
- {
- list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
- }
- args = args[args.Length - 1].GetGenericArguments();
- }
+ TypeWrapper[] args = new TypeWrapper[type.parameterCount()];
for (int i = 0; i < args.Length; i++)
{
- list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
+ args[i] = TypeWrapper.FromClass(type.parameterType(i));
+ args[i].Finish();
}
- types = list.ToArray();
+ TypeWrapper ret = TypeWrapper.FromClass(type.returnType());
+ ret.Finish();
+ return CreateMethodHandleDelegateType(args, ret);
}
- else
+
+ private static Type[] GetParameterTypes(MethodBase mb)
{
- types = new java.lang.Class[pi.Length];
- for (int i = 0; i < types.Length; i++)
+ ParameterInfo[] pi = mb.GetParameters();
+ Type[] args = new Type[pi.Length];
+ for (int i = 0; i < args.Length; i++)
{
- types[i] = ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject;
+ args[i] = pi[i].ParameterType;
}
+ return args;
}
- return java.lang.invoke.MethodType.methodType(ClassLoaderWrapper.GetWrapperFromType(mi.ReturnType).ClassObject, types);
- }
- internal sealed class DynamicMethodBuilder
- {
- private readonly java.lang.invoke.MethodType type;
- private readonly int firstArg;
- private readonly Type delegateType;
- private readonly object firstBoundValue;
- private readonly object secondBoundValue;
- private readonly Type container;
- private readonly DynamicMethod dm;
- private readonly CodeEmitter ilgen;
- private readonly Type packedArgType;
- private readonly int packedArgPos;
-
- sealed class Container
+ internal static Type[] GetParameterTypes(Type thisType, MethodBase mb)
{
- public T1 target;
- public T2 value;
-
- public Container(T1 target, T2 value)
+ ParameterInfo[] pi = mb.GetParameters();
+ Type[] args = new Type[pi.Length + 1];
+ args[0] = thisType;
+ for (int i = 1; i < args.Length; i++)
{
- this.target = target;
- this.value = value;
+ args[i] = pi[i - 1].ParameterType;
}
+ return args;
}
- private DynamicMethodBuilder(string name, java.lang.invoke.MethodType type, Type container, object target, object value, Type owner, bool useBasicTypes)
+ internal static java.lang.invoke.MethodType GetDelegateMethodType(Type type)
{
- this.type = type;
- this.delegateType = useBasicTypes ? GetMemberWrapperDelegateType(type) : GetDelegateTypeForInvokeExact(type);
- this.firstBoundValue = target;
- this.secondBoundValue = value;
- this.container = container;
- MethodInfo mi = GetDelegateInvokeMethod(delegateType);
- Type[] paramTypes;
- if (container != null)
- {
- this.firstArg = 1;
- paramTypes = GetParameterTypes(container, mi);
- }
- else if (target != null)
- {
- this.firstArg = 1;
- paramTypes = GetParameterTypes(target.GetType(), mi);
- }
- else
- {
- paramTypes = GetParameterTypes(mi);
- }
- if (!ReflectUtil.CanOwnDynamicMethod(owner))
- {
- owner = typeof(DynamicMethodBuilder);
- }
- this.dm = new DynamicMethod(name, mi.ReturnType, paramTypes, owner, true);
- this.ilgen = CodeEmitter.Create(dm);
-
- if (type.parameterCount() > MaxArity)
+ java.lang.Class[] types;
+ MethodInfo mi = GetDelegateInvokeMethod(type);
+ ParameterInfo[] pi = mi.GetParameters();
+ if (pi.Length > 0 && IsPackedArgsContainer(pi[pi.Length - 1].ParameterType))
{
- ParameterInfo[] pi = mi.GetParameters();
- this.packedArgType = pi[pi.Length - 1].ParameterType;
- this.packedArgPos = pi.Length - 1 + firstArg;
+ System.Collections.Generic.List list = new System.Collections.Generic.List();
+ for (int i = 0; i < pi.Length - 1; i++)
+ {
+ list.Add(ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject);
+ }
+ Type[] args = pi[pi.Length - 1].ParameterType.GetGenericArguments();
+ while (IsPackedArgsContainer(args[args.Length - 1]))
+ {
+ for (int i = 0; i < args.Length - 1; i++)
+ {
+ list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
+ }
+ args = args[args.Length - 1].GetGenericArguments();
+ }
+ for (int i = 0; i < args.Length; i++)
+ {
+ list.Add(ClassLoaderWrapper.GetWrapperFromType(args[i]).ClassObject);
+ }
+ types = list.ToArray();
}
else
{
- this.packedArgPos = Int32.MaxValue;
+ types = new java.lang.Class[pi.Length];
+ for (int i = 0; i < types.Length; i++)
+ {
+ types[i] = ClassLoaderWrapper.GetWrapperFromType(pi[i].ParameterType).ClassObject;
+ }
}
+ return java.lang.invoke.MethodType.methodType(ClassLoaderWrapper.GetWrapperFromType(mi.ReturnType).ClassObject, types);
}
- internal static Delegate CreateVoidAdapter(global::java.lang.invoke.MethodType type)
+ internal sealed class DynamicMethodBuilder
{
- DynamicMethodBuilder dm = new DynamicMethodBuilder("VoidAdapter", type.changeReturnType(global::java.lang.Void.TYPE), null, null, null, null, true);
- Type targetDelegateType = GetMemberWrapperDelegateType(type);
- dm.Ldarg(0);
- dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
- for (int i = 0; i < type.parameterCount(); i++)
- {
- dm.Ldarg(i);
- }
- dm.CallDelegate(targetDelegateType);
- dm.ilgen.Emit(OpCodes.Pop);
- dm.Ret();
- return dm.CreateDelegate();
- }
+ private readonly java.lang.invoke.MethodType type;
+ private readonly int firstArg;
+ private readonly Type delegateType;
+ private readonly object firstBoundValue;
+ private readonly object secondBoundValue;
+ private readonly Type container;
+ private readonly DynamicMethod dm;
+ private readonly CodeEmitter ilgen;
+ private readonly Type packedArgType;
+ private readonly int packedArgPos;
- internal static DynamicMethod CreateInvokeExact(global::java.lang.invoke.MethodType type)
- {
- FinishTypes(type);
- DynamicMethodBuilder dm = new DynamicMethodBuilder("InvokeExact", type, typeof(java.lang.invoke.MethodHandle), null, null, null, false);
- Type targetDelegateType = GetMemberWrapperDelegateType(type.insertParameterTypes(0, CoreClasses.java.lang.invoke.MethodHandle.Wrapper.ClassObject));
- dm.ilgen.Emit(OpCodes.Ldarg_0);
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic));
- if (type.returnType() == java.lang.Void.TYPE)
- {
- dm.ilgen.Emit(OpCodes.Call, typeof(MethodHandleUtil).GetMethod("GetVoidAdapter", BindingFlags.Static | BindingFlags.NonPublic));
- }
- else
+ sealed class Container
{
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
+ public T1 target;
+ public T2 value;
+
+ public Container(T1 target, T2 value)
+ {
+ this.target = target;
+ this.value = value;
+ }
}
- dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
- dm.ilgen.Emit(OpCodes.Ldarg_0);
- for (int i = 0; i < type.parameterCount(); i++)
+
+ private DynamicMethodBuilder(string name, java.lang.invoke.MethodType type, Type container, object target, object value, Type owner, bool useBasicTypes)
{
- dm.Ldarg(i);
- TypeWrapper tw = TypeWrapper.FromClass(type.parameterType(i));
- if (tw.IsNonPrimitiveValueType)
+ this.type = type;
+ this.delegateType = useBasicTypes ? GetMemberWrapperDelegateType(type) : GetDelegateTypeForInvokeExact(type);
+ this.firstBoundValue = target;
+ this.secondBoundValue = value;
+ this.container = container;
+ MethodInfo mi = GetDelegateInvokeMethod(delegateType);
+ Type[] paramTypes;
+ if (container != null)
{
- tw.EmitBox(dm.ilgen);
+ this.firstArg = 1;
+ paramTypes = GetParameterTypes(container, mi);
}
- else if (tw.IsGhost)
+ else if (target != null)
{
- tw.EmitConvSignatureTypeToStackType(dm.ilgen);
+ this.firstArg = 1;
+ paramTypes = GetParameterTypes(target.GetType(), mi);
}
- else if (tw == PrimitiveTypeWrapper.BYTE)
+ else
{
- dm.ilgen.Emit(OpCodes.Conv_I1);
+ paramTypes = GetParameterTypes(mi);
+ }
+ if (!ReflectUtil.CanOwnDynamicMethod(owner))
+ {
+ owner = typeof(DynamicMethodBuilder);
+ }
+ this.dm = new DynamicMethod(name, mi.ReturnType, paramTypes, owner, true);
+ this.ilgen = CodeEmitter.Create(dm);
+
+ if (type.parameterCount() > MaxArity)
+ {
+ ParameterInfo[] pi = mi.GetParameters();
+ this.packedArgType = pi[pi.Length - 1].ParameterType;
+ this.packedArgPos = pi.Length - 1 + firstArg;
+ }
+ else
+ {
+ this.packedArgPos = Int32.MaxValue;
}
}
- dm.CallDelegate(targetDelegateType);
- TypeWrapper retType = TypeWrapper.FromClass(type.returnType());
- if (retType.IsNonPrimitiveValueType)
- {
- retType.EmitUnbox(dm.ilgen);
- }
- else if (retType.IsGhost)
+
+ internal static Delegate CreateVoidAdapter(global::java.lang.invoke.MethodType type)
{
- retType.EmitConvStackTypeToSignatureType(dm.ilgen, null);
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("VoidAdapter", type.changeReturnType(global::java.lang.Void.TYPE), null, null, null, null, true);
+ Type targetDelegateType = GetMemberWrapperDelegateType(type);
+ dm.Ldarg(0);
+ dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
+ for (int i = 0; i < type.parameterCount(); i++)
+ {
+ dm.Ldarg(i);
+ }
+ dm.CallDelegate(targetDelegateType);
+ dm.ilgen.Emit(OpCodes.Pop);
+ dm.Ret();
+ return dm.CreateDelegate();
}
- else if (!retType.IsPrimitive && retType != CoreClasses.java.lang.Object.Wrapper)
+
+ internal static DynamicMethod CreateInvokeExact(global::java.lang.invoke.MethodType type)
{
- dm.EmitCheckcast(retType);
+ FinishTypes(type);
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("InvokeExact", type, typeof(java.lang.invoke.MethodHandle), null, null, null, false);
+ Type targetDelegateType = GetMemberWrapperDelegateType(type.insertParameterTypes(0, CoreClasses.java.lang.invoke.MethodHandle.Wrapper.ClassObject));
+ dm.ilgen.Emit(OpCodes.Ldarg_0);
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic));
+ if (type.returnType() == java.lang.Void.TYPE)
+ {
+ dm.ilgen.Emit(OpCodes.Call, typeof(MethodHandleUtil).GetMethod("GetVoidAdapter", BindingFlags.Static | BindingFlags.NonPublic));
+ }
+ else
+ {
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
+ }
+ dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
+ dm.ilgen.Emit(OpCodes.Ldarg_0);
+ for (int i = 0; i < type.parameterCount(); i++)
+ {
+ dm.Ldarg(i);
+ TypeWrapper tw = TypeWrapper.FromClass(type.parameterType(i));
+ if (tw.IsNonPrimitiveValueType)
+ {
+ tw.EmitBox(dm.ilgen);
+ }
+ else if (tw.IsGhost)
+ {
+ tw.EmitConvSignatureTypeToStackType(dm.ilgen);
+ }
+ else if (tw == PrimitiveTypeWrapper.BYTE)
+ {
+ dm.ilgen.Emit(OpCodes.Conv_I1);
+ }
+ }
+ dm.CallDelegate(targetDelegateType);
+ TypeWrapper retType = TypeWrapper.FromClass(type.returnType());
+ if (retType.IsNonPrimitiveValueType)
+ {
+ retType.EmitUnbox(dm.ilgen);
+ }
+ else if (retType.IsGhost)
+ {
+ retType.EmitConvStackTypeToSignatureType(dm.ilgen, null);
+ }
+ else if (!retType.IsPrimitive && retType != CoreClasses.java.lang.Object.Wrapper)
+ {
+ dm.EmitCheckcast(retType);
+ }
+ dm.Ret();
+ dm.ilgen.DoEmit();
+ return dm.dm;
}
- dm.Ret();
- dm.ilgen.DoEmit();
- return dm.dm;
- }
- internal static Delegate CreateMethodHandleLinkTo(java.lang.invoke.MemberName mn)
- {
- java.lang.invoke.MethodType type = mn.getMethodType();
- Type delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type.dropParameterTypes(type.parameterCount() - 1, type.parameterCount()));
- DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type, null, null, null, null, true);
- dm.Ldarg(type.parameterCount() - 1);
- dm.ilgen.EmitCastclass(typeof(java.lang.invoke.MemberName));
- dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.ilgen.Emit(OpCodes.Castclass, delegateType);
- for (int i = 0, count = type.parameterCount() - 1; i < count; i++)
- {
- dm.Ldarg(i);
- }
- dm.CallDelegate(delegateType);
- dm.Ret();
- return dm.CreateDelegate();
- }
-
- internal static Delegate CreateMethodHandleInvoke(java.lang.invoke.MemberName mn)
- {
- java.lang.invoke.MethodType type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass());
- Type targetDelegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type);
- DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type,
- typeof(Container<,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache<>).MakeGenericType(targetDelegateType)), null, null, null, true);
- dm.Ldarg(0);
- dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
- switch (mn.getName())
- {
- case "invokeExact":
- dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
- break;
- case "invoke":
- dm.LoadValueAddress();
- dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
- break;
- case "invokeBasic":
- dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(targetDelegateType));
- break;
- default:
- throw new InvalidOperationException();
- }
- dm.Ldarg(0);
- for (int i = 1, count = type.parameterCount(); i < count; i++)
+ internal static Delegate CreateMethodHandleLinkTo(java.lang.invoke.MemberName mn)
{
- dm.Ldarg(i);
+ java.lang.invoke.MethodType type = mn.getMethodType();
+ Type delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type.dropParameterTypes(type.parameterCount() - 1, type.parameterCount()));
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type, null, null, null, null, true);
+ dm.Ldarg(type.parameterCount() - 1);
+ dm.ilgen.EmitCastclass(typeof(java.lang.invoke.MemberName));
+ dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.ilgen.Emit(OpCodes.Castclass, delegateType);
+ for (int i = 0, count = type.parameterCount() - 1; i < count; i++)
+ {
+ dm.Ldarg(i);
+ }
+ dm.CallDelegate(delegateType);
+ dm.Ret();
+ return dm.CreateDelegate();
}
- dm.CallDelegate(targetDelegateType);
- dm.Ret();
- return dm.CreateDelegate();
- }
- internal static Delegate CreateDynamicOnly(MethodWrapper mw, java.lang.invoke.MethodType type)
- {
- FinishTypes(type);
- DynamicMethodBuilder dm = new DynamicMethodBuilder("CustomInvoke:" + mw.Name, type, null, mw, null, null, true);
- dm.ilgen.Emit(OpCodes.Ldarg_0);
- if (mw.IsStatic)
+ internal static Delegate CreateMethodHandleInvoke(java.lang.invoke.MemberName mn)
{
- dm.LoadNull();
- dm.BoxArgs(0);
+ java.lang.invoke.MethodType type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass());
+ Type targetDelegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type);
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type,
+ typeof(Container<,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache<>).MakeGenericType(targetDelegateType)), null, null, null, true);
+ dm.Ldarg(0);
+ dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
+ switch (mn.getName())
+ {
+ case "invokeExact":
+ dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
+ break;
+ case "invoke":
+ dm.LoadValueAddress();
+ dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
+ break;
+ case "invokeBasic":
+ dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(targetDelegateType));
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ dm.Ldarg(0);
+ for (int i = 1, count = type.parameterCount(); i < count; i++)
+ {
+ dm.Ldarg(i);
+ }
+ dm.CallDelegate(targetDelegateType);
+ dm.Ret();
+ return dm.CreateDelegate();
}
- else
+
+ internal static Delegate CreateDynamicOnly(MethodWrapper mw, java.lang.invoke.MethodType type)
{
- dm.Ldarg(0);
- dm.BoxArgs(1);
+ FinishTypes(type);
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("CustomInvoke:" + mw.Name, type, null, mw, null, null, true);
+ dm.ilgen.Emit(OpCodes.Ldarg_0);
+ if (mw.IsStatic)
+ {
+ dm.LoadNull();
+ dm.BoxArgs(0);
+ }
+ else
+ {
+ dm.Ldarg(0);
+ dm.BoxArgs(1);
+ }
+ dm.Callvirt(typeof(MethodWrapper).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic));
+ dm.UnboxReturnValue();
+ dm.Ret();
+ return dm.CreateDelegate();
}
- dm.Callvirt(typeof(MethodWrapper).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic));
- dm.UnboxReturnValue();
- dm.Ret();
- return dm.CreateDelegate();
- }
- internal static Delegate CreateMemberName(MethodWrapper mw, global::java.lang.invoke.MethodType type, bool doDispatch)
- {
- FinishTypes(type);
- TypeWrapper tw = mw.DeclaringType;
- Type owner = tw.TypeAsBaseType;
+ internal static Delegate CreateMemberName(MethodWrapper mw, global::java.lang.invoke.MethodType type, bool doDispatch)
+ {
+ FinishTypes(type);
+ TypeWrapper tw = mw.DeclaringType;
+ Type owner = tw.TypeAsBaseType;
#if NET_4_0
if (!doDispatch && !mw.IsStatic)
{
@@ -345,360 +346,362 @@ internal static Delegate CreateMemberName(MethodWrapper mw, global::java.lang.in
owner = typeof(object);
}
#endif
- DynamicMethodBuilder dm = new DynamicMethodBuilder("MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null,
- mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true);
- for (int i = 0, count = type.parameterCount(); i < count; i++)
- {
- if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType || tw.IsRemapped) && (!mw.IsConstructor || tw != CoreClasses.java.lang.String.Wrapper))
+ DynamicMethodBuilder dm = new DynamicMethodBuilder("MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null,
+ mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true);
+ for (int i = 0, count = type.parameterCount(); i < count; i++)
{
- if (tw.IsGhost || tw.IsNonPrimitiveValueType)
+ if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType || tw.IsRemapped) && (!mw.IsConstructor || tw != CoreClasses.java.lang.String.Wrapper))
{
- dm.LoadFirstArgAddress(tw);
+ if (tw.IsGhost || tw.IsNonPrimitiveValueType)
+ {
+ dm.LoadFirstArgAddress(tw);
+ }
+ else
+ {
+ Debug.Assert(tw.IsRemapped);
+ // TODO this must be checked
+ dm.Ldarg(0);
+ if (mw.IsConstructor)
+ {
+ dm.EmitCastclass(tw.TypeAsBaseType);
+ }
+ else if (tw != CoreClasses.cli.System.Object.Wrapper)
+ {
+ dm.EmitCheckcast(tw);
+ }
+ }
}
else
{
- Debug.Assert(tw.IsRemapped);
- // TODO this must be checked
- dm.Ldarg(0);
- if (mw.IsConstructor)
+ dm.Ldarg(i);
+ TypeWrapper argType = TypeWrapper.FromClass(type.parameterType(i));
+ if (!argType.IsPrimitive)
{
- dm.EmitCastclass(tw.TypeAsBaseType);
- }
- else if (tw != CoreClasses.cli.System.Object.Wrapper)
- {
- dm.EmitCheckcast(tw);
+ if (argType.IsUnloadable)
+ {
+ }
+ else if (argType.IsNonPrimitiveValueType)
+ {
+ dm.Unbox(argType);
+ }
+ else if (argType.IsGhost)
+ {
+ dm.UnboxGhost(argType);
+ }
+ else
+ {
+ dm.EmitCheckcast(argType);
+ }
}
}
}
- else
+ if (mw.HasCallerID)
{
- dm.Ldarg(i);
- TypeWrapper argType = TypeWrapper.FromClass(type.parameterType(i));
- if (!argType.IsPrimitive)
+ dm.LoadCallerID();
+ }
+ // special case for Object.clone() and Object.finalize()
+ if (mw.IsFinalizeOrClone)
+ {
+ if (doDispatch)
{
- if (argType.IsUnloadable)
- {
- }
- else if (argType.IsNonPrimitiveValueType)
- {
- dm.Unbox(argType);
- }
- else if (argType.IsGhost)
- {
- dm.UnboxGhost(argType);
- }
- else
- {
- dm.EmitCheckcast(argType);
- }
+ mw.EmitCallvirtReflect(dm.ilgen);
+ }
+ else
+ {
+ // we can re-use the implementations from cli.System.Object (even though the object may not in-fact extend cli.System.Object)
+ CoreClasses.cli.System.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCall(dm.ilgen);
}
}
- }
- if (mw.HasCallerID)
- {
- dm.LoadCallerID();
- }
- // special case for Object.clone() and Object.finalize()
- if (mw.IsFinalizeOrClone)
- {
- if (doDispatch)
+ else if (doDispatch && !mw.IsStatic)
{
- mw.EmitCallvirtReflect(dm.ilgen);
+ dm.Callvirt(mw);
}
else
{
- // we can re-use the implementations from cli.System.Object (even though the object may not in-fact extend cli.System.Object)
- CoreClasses.cli.System.Object.Wrapper.GetMethodWrapper(mw.Name, mw.Signature, false).EmitCall(dm.ilgen);
+ dm.Call(mw);
}
+ TypeWrapper retType = TypeWrapper.FromClass(type.returnType());
+ if (retType.IsUnloadable)
+ {
+ }
+ else if (retType.IsNonPrimitiveValueType)
+ {
+ dm.Box(retType);
+ }
+ else if (retType.IsGhost)
+ {
+ dm.BoxGhost(retType);
+ }
+ else if (retType == PrimitiveTypeWrapper.BYTE)
+ {
+ dm.CastByte();
+ }
+ dm.Ret();
+ return dm.CreateDelegate();
}
- else if (doDispatch && !mw.IsStatic)
+
+ internal void Call(MethodInfo method)
{
- dm.Callvirt(mw);
+ ilgen.Emit(OpCodes.Call, method);
}
- else
+
+ internal void Callvirt(MethodInfo method)
{
- dm.Call(mw);
+ ilgen.Emit(OpCodes.Callvirt, method);
}
- TypeWrapper retType = TypeWrapper.FromClass(type.returnType());
- if (retType.IsUnloadable)
+
+ internal void Call(MethodWrapper mw)
{
+ mw.EmitCall(ilgen);
}
- else if (retType.IsNonPrimitiveValueType)
+
+ internal void Callvirt(MethodWrapper mw)
{
- dm.Box(retType);
+ mw.EmitCallvirt(ilgen);
}
- else if (retType.IsGhost)
+
+ internal void CallDelegate(Type delegateType)
{
- dm.BoxGhost(retType);
+ EmitCallDelegateInvokeMethod(ilgen, delegateType);
}
- else if (retType == PrimitiveTypeWrapper.BYTE)
+
+ internal void LoadFirstArgAddress(TypeWrapper tw)
{
- dm.CastByte();
+ ilgen.EmitLdarg(0);
+ if (tw.IsGhost)
+ {
+ tw.EmitConvStackTypeToSignatureType(ilgen, null);
+ CodeEmitterLocal local = ilgen.DeclareLocal(tw.TypeAsSignatureType);
+ ilgen.Emit(OpCodes.Stloc, local);
+ ilgen.Emit(OpCodes.Ldloca, local);
+ }
+ else if (tw.IsNonPrimitiveValueType)
+ {
+ ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
}
- dm.Ret();
- return dm.CreateDelegate();
- }
-
- internal void Call(MethodInfo method)
- {
- ilgen.Emit(OpCodes.Call, method);
- }
-
- internal void Callvirt(MethodInfo method)
- {
- ilgen.Emit(OpCodes.Callvirt, method);
- }
-
- internal void Call(MethodWrapper mw)
- {
- mw.EmitCall(ilgen);
- }
-
- internal void Callvirt(MethodWrapper mw)
- {
- mw.EmitCallvirt(ilgen);
- }
-
- internal void CallDelegate(Type delegateType)
- {
- EmitCallDelegateInvokeMethod(ilgen, delegateType);
- }
- internal void LoadFirstArgAddress(TypeWrapper tw)
- {
- ilgen.EmitLdarg(0);
- if (tw.IsGhost)
+ internal void Ldarg(int i)
{
- tw.EmitConvStackTypeToSignatureType(ilgen, null);
- CodeEmitterLocal local = ilgen.DeclareLocal(tw.TypeAsSignatureType);
- ilgen.Emit(OpCodes.Stloc, local);
- ilgen.Emit(OpCodes.Ldloca, local);
+ LoadPackedArg(ilgen, i, firstArg, packedArgPos, packedArgType);
}
- else if (tw.IsNonPrimitiveValueType)
+
+ internal void LoadCallerID()
{
- ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
+ ilgen.Emit(OpCodes.Ldarg_0);
+ ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCallerID);
}
- else
+
+ internal void LoadValueAddress()
{
- throw new InvalidOperationException();
+ ilgen.Emit(OpCodes.Ldarg_0);
+ ilgen.Emit(OpCodes.Ldflda, container.GetField("value"));
}
- }
-
- internal void Ldarg(int i)
- {
- LoadPackedArg(ilgen, i, firstArg, packedArgPos, packedArgType);
- }
-
- internal void LoadCallerID()
- {
- ilgen.Emit(OpCodes.Ldarg_0);
- ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicCallerID);
- }
-
- internal void LoadValueAddress()
- {
- ilgen.Emit(OpCodes.Ldarg_0);
- ilgen.Emit(OpCodes.Ldflda, container.GetField("value"));
- }
- internal void Ret()
- {
- ilgen.Emit(OpCodes.Ret);
- }
+ internal void Ret()
+ {
+ ilgen.Emit(OpCodes.Ret);
+ }
- internal Delegate CreateDelegate()
- {
- //Console.WriteLine(delegateType);
- //ilgen.DumpMethod();
- ilgen.DoEmit();
- return ValidateDelegate(firstArg == 0
- ? dm.CreateDelegate(delegateType)
- : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue)));
- }
+ internal Delegate CreateDelegate()
+ {
+ //Console.WriteLine(delegateType);
+ //ilgen.DumpMethod();
+ ilgen.DoEmit();
+ return ValidateDelegate(firstArg == 0
+ ? dm.CreateDelegate(delegateType)
+ : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue)));
+ }
- internal void BoxArgs(int start)
- {
- int paramCount = type.parameterCount();
- ilgen.EmitLdc_I4(paramCount - start);
- ilgen.Emit(OpCodes.Newarr, Types.Object);
- for (int i = start; i < paramCount; i++)
+ internal void BoxArgs(int start)
{
- ilgen.Emit(OpCodes.Dup);
- ilgen.EmitLdc_I4(i - start);
- Ldarg(i);
- TypeWrapper tw = TypeWrapper.FromClass(type.parameterType(i));
- if (tw.IsPrimitive)
+ int paramCount = type.parameterCount();
+ ilgen.EmitLdc_I4(paramCount - start);
+ ilgen.Emit(OpCodes.Newarr, Types.Object);
+ for (int i = start; i < paramCount; i++)
{
- ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType);
+ ilgen.Emit(OpCodes.Dup);
+ ilgen.EmitLdc_I4(i - start);
+ Ldarg(i);
+ TypeWrapper tw = TypeWrapper.FromClass(type.parameterType(i));
+ if (tw.IsPrimitive)
+ {
+ ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType);
+ }
+ ilgen.Emit(OpCodes.Stelem_Ref);
}
- ilgen.Emit(OpCodes.Stelem_Ref);
}
- }
- internal void UnboxReturnValue()
- {
- TypeWrapper tw = TypeWrapper.FromClass(type.returnType());
- if (tw == PrimitiveTypeWrapper.VOID)
+ internal void UnboxReturnValue()
{
- ilgen.Emit(OpCodes.Pop);
+ TypeWrapper tw = TypeWrapper.FromClass(type.returnType());
+ if (tw == PrimitiveTypeWrapper.VOID)
+ {
+ ilgen.Emit(OpCodes.Pop);
+ }
+ else if (tw.IsPrimitive)
+ {
+ ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
+ ilgen.Emit(OpCodes.Ldobj, tw.TypeAsSignatureType);
+ }
}
- else if (tw.IsPrimitive)
+
+ internal void LoadNull()
{
- ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
- ilgen.Emit(OpCodes.Ldobj, tw.TypeAsSignatureType);
+ ilgen.Emit(OpCodes.Ldnull);
}
- }
- internal void LoadNull()
- {
- ilgen.Emit(OpCodes.Ldnull);
- }
-
- internal void Unbox(TypeWrapper tw)
- {
- tw.EmitUnbox(ilgen);
- }
+ internal void Unbox(TypeWrapper tw)
+ {
+ tw.EmitUnbox(ilgen);
+ }
- internal void Box(TypeWrapper tw)
- {
- tw.EmitBox(ilgen);
- }
+ internal void Box(TypeWrapper tw)
+ {
+ tw.EmitBox(ilgen);
+ }
- internal void UnboxGhost(TypeWrapper tw)
- {
- tw.EmitConvStackTypeToSignatureType(ilgen, null);
- }
+ internal void UnboxGhost(TypeWrapper tw)
+ {
+ tw.EmitConvStackTypeToSignatureType(ilgen, null);
+ }
- internal void BoxGhost(TypeWrapper tw)
- {
- tw.EmitConvSignatureTypeToStackType(ilgen);
- }
+ internal void BoxGhost(TypeWrapper tw)
+ {
+ tw.EmitConvSignatureTypeToStackType(ilgen);
+ }
- internal void EmitCheckcast(TypeWrapper tw)
- {
- tw.EmitCheckcast(ilgen);
- }
+ internal void EmitCheckcast(TypeWrapper tw)
+ {
+ tw.EmitCheckcast(ilgen);
+ }
- internal void EmitCastclass(Type type)
- {
- ilgen.EmitCastclass(type);
- }
+ internal void EmitCastclass(Type type)
+ {
+ ilgen.EmitCastclass(type);
+ }
- internal void EmitWriteLine()
- {
- ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }));
- }
+ internal void EmitWriteLine()
+ {
+ ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }));
+ }
- internal void CastByte()
- {
- ilgen.Emit(OpCodes.Conv_I1);
- }
+ internal void CastByte()
+ {
+ ilgen.Emit(OpCodes.Conv_I1);
+ }
- internal void DumpMethod()
- {
- Console.WriteLine(dm.Name + ", type = " + delegateType);
- ilgen.DumpMethod();
- }
+ internal void DumpMethod()
+ {
+ Console.WriteLine(dm.Name + ", type = " + delegateType);
+ ilgen.DumpMethod();
+ }
- private static void FinishTypes(global::java.lang.invoke.MethodType type)
- {
- // FXBUG(?) DynamicILGenerator doesn't like SymbolType (e.g. an array of a TypeBuilder)
- // so we have to finish the signature types
- TypeWrapper.FromClass(type.returnType()).Finish();
- for (int i = 0; i < type.parameterCount(); i++)
+ private static void FinishTypes(global::java.lang.invoke.MethodType type)
{
- TypeWrapper.FromClass(type.parameterType(i)).Finish();
+ // FXBUG(?) DynamicILGenerator doesn't like SymbolType (e.g. an array of a TypeBuilder)
+ // so we have to finish the signature types
+ TypeWrapper.FromClass(type.returnType()).Finish();
+ for (int i = 0; i < type.parameterCount(); i++)
+ {
+ TypeWrapper.FromClass(type.parameterType(i)).Finish();
+ }
}
}
- }
#if DEBUG
- [System.Security.SecuritySafeCritical]
+ [System.Security.SecuritySafeCritical]
#endif
- private static Delegate ValidateDelegate(Delegate d)
- {
-#if DEBUG
- try
+ private static Delegate ValidateDelegate(Delegate d)
{
- System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(d);
- }
- catch (Exception x)
- {
- throw new InternalException("Delegate failed to JIT", x);
- }
+#if DEBUG
+ try
+ {
+ System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(d);
+ }
+ catch (Exception x)
+ {
+ throw new InternalException("Delegate failed to JIT", x);
+ }
#endif
- return d;
- }
-
- internal static Type GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type)
- {
- if (type._invokeExactDelegateType == null)
- {
- type._invokeExactDelegateType = CreateMethodHandleDelegateType(type);
+ return d;
}
- return type._invokeExactDelegateType;
- }
- internal static T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh)
- where T : class
- {
- global::java.lang.invoke.MethodType type = mh.type();
- if (mh._invokeExactDelegate == null)
+ internal static Type GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type)
{
- if (type._invokeExactDynamicMethod == null)
- {
- type._invokeExactDynamicMethod = DynamicMethodBuilder.CreateInvokeExact(type);
- }
- mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type), mh);
- T del = mh._invokeExactDelegate as T;
- if (del != null)
+ if (type._invokeExactDelegateType == null)
{
- return del;
+ type._invokeExactDelegateType = CreateMethodHandleDelegateType(type);
}
+ return type._invokeExactDelegateType;
}
- throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type);
- }
- // called from InvokeExact DynamicMethod and ByteCodeHelper.GetDelegateForInvokeBasic()
- internal static object GetVoidAdapter(java.lang.invoke.MemberName mn)
- {
- global::java.lang.invoke.MethodType type = mn.getMethodType();
- if (type.voidAdapter == null)
+ internal static T GetDelegateForInvokeExact(global::java.lang.invoke.MethodHandle mh)
+ where T : class
{
- if (type.returnType() == global::java.lang.Void.TYPE)
+ global::java.lang.invoke.MethodType type = mh.type();
+ if (mh._invokeExactDelegate == null)
{
- return mn.vmtarget;
+ if (type._invokeExactDynamicMethod == null)
+ {
+ type._invokeExactDynamicMethod = DynamicMethodBuilder.CreateInvokeExact(type);
+ }
+ mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type), mh);
+ T del = mh._invokeExactDelegate as T;
+ if (del != null)
+ {
+ return del;
+ }
}
- type.voidAdapter = DynamicMethodBuilder.CreateVoidAdapter(type);
+ throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type);
}
- return type.voidAdapter;
- }
- internal static void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType)
- {
- index += firstArg;
- if (index >= packedArgPos)
+ // called from InvokeExact DynamicMethod and ByteCodeHelper.GetDelegateForInvokeBasic()
+ internal static object GetVoidAdapter(java.lang.invoke.MemberName mn)
{
- ilgen.EmitLdarga(packedArgPos);
- int fieldPos = index - packedArgPos;
- Type type = packedArgType;
- while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
+ global::java.lang.invoke.MethodType type = mn.getMethodType();
+ if (type.voidAdapter == null)
{
- FieldInfo field = type.GetField("t8");
- type = field.FieldType;
- ilgen.Emit(OpCodes.Ldflda, field);
- fieldPos -= MaxArity - 1;
+ if (type.returnType() == global::java.lang.Void.TYPE)
+ {
+ return mn.vmtarget;
+ }
+ type.voidAdapter = DynamicMethodBuilder.CreateVoidAdapter(type);
}
- ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
+ return type.voidAdapter;
}
- else
+
+ internal static void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType)
{
- ilgen.EmitLdarg(index);
+ index += firstArg;
+ if (index >= packedArgPos)
+ {
+ ilgen.EmitLdarga(packedArgPos);
+ int fieldPos = index - packedArgPos;
+ Type type = packedArgType;
+ while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
+ {
+ FieldInfo field = type.GetField("t8");
+ type = field.FieldType;
+ ilgen.Emit(OpCodes.Ldflda, field);
+ fieldPos -= MaxArity - 1;
+ }
+ ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
+ }
+ else
+ {
+ ilgen.EmitLdarg(index);
+ }
}
- }
#endif
+ }
+
}
#endif
diff --git a/src/IKVM.Runtime/MethodHandleUtil.root.cs b/src/IKVM.Runtime/MethodHandleUtil.root.cs
index 5a66a1c6e7..325baf3805 100644
--- a/src/IKVM.Runtime/MethodHandleUtil.root.cs
+++ b/src/IKVM.Runtime/MethodHandleUtil.root.cs
@@ -23,11 +23,7 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
-
#if IMPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
using IKVM.Tools.Importer;
using Type = IKVM.Reflection.Type;
@@ -36,17 +32,20 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-static partial class MethodHandleUtil
+namespace IKVM.Runtime
{
- internal const int MaxArity = 8;
+ static partial class MethodHandleUtil
+ {
- static readonly Type typeofMHA;
- static readonly Type[] typeofMHV;
- static readonly Type[] typeofMH;
+ internal const int MaxArity = 8;
- static MethodHandleUtil()
- {
+ static readonly Type typeofMHA;
+ static readonly Type[] typeofMHV;
+ static readonly Type[] typeofMH;
+
+ static MethodHandleUtil()
+ {
#if IMPORTER
typeofMHA = StaticCompiler.GetRuntimeType("IKVM.Runtime.MHA`8");
typeofMHV = new Type[] {
@@ -73,8 +72,8 @@ static MethodHandleUtil()
StaticCompiler.GetRuntimeType("IKVM.Runtime.MH`9"),
};
#else
- typeofMHA = typeof(IKVM.Runtime.MHA<,,,,,,,>);
- typeofMHV = new Type[] {
+ typeofMHA = typeof(IKVM.Runtime.MHA<,,,,,,,>);
+ typeofMHV = new Type[] {
typeof(IKVM.Runtime.MHV),
typeof(IKVM.Runtime.MHV<>),
typeof(IKVM.Runtime.MHV<,>),
@@ -85,7 +84,7 @@ static MethodHandleUtil()
typeof(IKVM.Runtime.MHV<,,,,,,>),
typeof(IKVM.Runtime.MHV<,,,,,,,>),
};
- typeofMH = new Type[] {
+ typeofMH = new Type[] {
null,
typeof(IKVM.Runtime.MH<>),
typeof(IKVM.Runtime.MH<,>),
@@ -98,117 +97,119 @@ static MethodHandleUtil()
typeof(IKVM.Runtime.MH<,,,,,,,,>),
};
#endif
- }
-
- internal static bool IsPackedArgsContainer(Type type)
- {
- return type.IsGenericType && type.GetGenericTypeDefinition() == typeofMHA;
- }
+ }
- internal static Type CreateMethodHandleDelegateType(TypeWrapper[] args, TypeWrapper ret)
- {
- Type[] typeArgs = new Type[args.Length];
- for (int i = 0; i < args.Length; i++)
+ internal static bool IsPackedArgsContainer(Type type)
{
- typeArgs[i] = args[i].TypeAsSignatureType;
+ return type.IsGenericType && type.GetGenericTypeDefinition() == typeofMHA;
}
- return CreateDelegateType(typeArgs, ret.TypeAsSignatureType);
- }
- internal static Type CreateMemberWrapperDelegateType(TypeWrapper[] args, TypeWrapper ret)
- {
- Type[] typeArgs = new Type[args.Length];
- for (int i = 0; i < args.Length; i++)
+ internal static Type CreateMethodHandleDelegateType(TypeWrapper[] args, TypeWrapper ret)
{
- typeArgs[i] = AsBasicType(args[i]);
+ Type[] typeArgs = new Type[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ {
+ typeArgs[i] = args[i].TypeAsSignatureType;
+ }
+ return CreateDelegateType(typeArgs, ret.TypeAsSignatureType);
}
- return CreateDelegateType(typeArgs, AsBasicType(ret));
- }
- static Type CreateDelegateType(Type[] types, Type retType)
- {
- if (types.Length == 0 && retType == Types.Void)
+ internal static Type CreateMemberWrapperDelegateType(TypeWrapper[] args, TypeWrapper ret)
{
- return typeofMHV[0];
+ Type[] typeArgs = new Type[args.Length];
+ for (int i = 0; i < args.Length; i++)
+ {
+ typeArgs[i] = AsBasicType(args[i]);
+ }
+ return CreateDelegateType(typeArgs, AsBasicType(ret));
}
- else if (types.Length > MaxArity)
+
+ static Type CreateDelegateType(Type[] types, Type retType)
{
- int arity = types.Length;
- int remainder = (arity - 8) % 7;
- int count = (arity - 8) / 7;
- if (remainder == 0)
+ if (types.Length == 0 && retType == Types.Void)
{
- remainder = 7;
- count--;
+ return typeofMHV[0];
}
-
- var last = typeofMHA.MakeGenericType(SubArray(types, types.Length - 8, 8));
- for (int i = 0; i < count; i++)
+ else if (types.Length > MaxArity)
{
- var temp = SubArray(types, types.Length - 8 - 7 * (i + 1), 8);
- temp[7] = last;
- last = typeofMHA.MakeGenericType(temp);
+ int arity = types.Length;
+ int remainder = (arity - 8) % 7;
+ int count = (arity - 8) / 7;
+ if (remainder == 0)
+ {
+ remainder = 7;
+ count--;
+ }
+
+ var last = typeofMHA.MakeGenericType(SubArray(types, types.Length - 8, 8));
+ for (int i = 0; i < count; i++)
+ {
+ var temp = SubArray(types, types.Length - 8 - 7 * (i + 1), 8);
+ temp[7] = last;
+ last = typeofMHA.MakeGenericType(temp);
+ }
+
+ types = SubArray(types, 0, remainder + 1);
+ types[remainder] = last;
}
- types = SubArray(types, 0, remainder + 1);
- types[remainder] = last;
+ if (retType == Types.Void)
+ {
+ return typeofMHV[types.Length].MakeGenericType(types);
+ }
+ else
+ {
+ types = ArrayUtil.Concat(types, retType);
+ return typeofMH[types.Length].MakeGenericType(types);
+ }
}
- if (retType == Types.Void)
+ static Type[] SubArray(Type[] inArray, int start, int length)
{
- return typeofMHV[types.Length].MakeGenericType(types);
+ var outArray = new Type[length];
+ Array.Copy(inArray, start, outArray, 0, length);
+ return outArray;
}
- else
+
+ internal static Type AsBasicType(TypeWrapper tw)
{
- types = ArrayUtil.Concat(types, retType);
- return typeofMH[types.Length].MakeGenericType(types);
+ if (tw == PrimitiveTypeWrapper.BOOLEAN || tw == PrimitiveTypeWrapper.BYTE || tw == PrimitiveTypeWrapper.CHAR || tw == PrimitiveTypeWrapper.SHORT || tw == PrimitiveTypeWrapper.INT)
+ return Types.Int32;
+ else if (tw == PrimitiveTypeWrapper.LONG || tw == PrimitiveTypeWrapper.FLOAT || tw == PrimitiveTypeWrapper.DOUBLE || tw == PrimitiveTypeWrapper.VOID)
+ return tw.TypeAsSignatureType;
+ else
+ return Types.Object;
}
- }
- static Type[] SubArray(Type[] inArray, int start, int length)
- {
- var outArray = new Type[length];
- Array.Copy(inArray, start, outArray, 0, length);
- return outArray;
- }
-
- internal static Type AsBasicType(TypeWrapper tw)
- {
- if (tw == PrimitiveTypeWrapper.BOOLEAN || tw == PrimitiveTypeWrapper.BYTE || tw == PrimitiveTypeWrapper.CHAR || tw == PrimitiveTypeWrapper.SHORT || tw == PrimitiveTypeWrapper.INT)
- return Types.Int32;
- else if (tw == PrimitiveTypeWrapper.LONG || tw == PrimitiveTypeWrapper.FLOAT || tw == PrimitiveTypeWrapper.DOUBLE || tw == PrimitiveTypeWrapper.VOID)
- return tw.TypeAsSignatureType;
- else
- return Types.Object;
- }
-
- internal static bool HasOnlyBasicTypes(TypeWrapper[] args, TypeWrapper ret)
- {
- foreach (var tw in args)
- if (!IsBasicType(tw))
- return false;
+ internal static bool HasOnlyBasicTypes(TypeWrapper[] args, TypeWrapper ret)
+ {
+ foreach (var tw in args)
+ if (!IsBasicType(tw))
+ return false;
- return IsBasicType(ret);
- }
+ return IsBasicType(ret);
+ }
- static bool IsBasicType(TypeWrapper tw)
- {
- return tw == PrimitiveTypeWrapper.INT
- || tw == PrimitiveTypeWrapper.LONG
- || tw == PrimitiveTypeWrapper.FLOAT
- || tw == PrimitiveTypeWrapper.DOUBLE
- || tw == PrimitiveTypeWrapper.VOID
- || tw == CoreClasses.java.lang.Object.Wrapper;
- }
+ static bool IsBasicType(TypeWrapper tw)
+ {
+ return tw == PrimitiveTypeWrapper.INT
+ || tw == PrimitiveTypeWrapper.LONG
+ || tw == PrimitiveTypeWrapper.FLOAT
+ || tw == PrimitiveTypeWrapper.DOUBLE
+ || tw == PrimitiveTypeWrapper.VOID
+ || tw == CoreClasses.java.lang.Object.Wrapper;
+ }
- internal static int SlotCount(TypeWrapper[] parameters)
- {
- int count = 0;
- for (int i = 0; i < parameters.Length; i++)
+ internal static int SlotCount(TypeWrapper[] parameters)
{
- count += parameters[i].IsWidePrimitive ? 2 : 1;
+ int count = 0;
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ count += parameters[i].IsWidePrimitive ? 2 : 1;
+ }
+ return count;
}
- return count;
+
}
}
diff --git a/src/IKVM.Runtime/MethodParametersEntry.cs b/src/IKVM.Runtime/MethodParametersEntry.cs
index b365da095b..96ad7ec0f9 100644
--- a/src/IKVM.Runtime/MethodParametersEntry.cs
+++ b/src/IKVM.Runtime/MethodParametersEntry.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using IKVM.ByteCode;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
struct MethodParametersEntry
diff --git a/src/IKVM.Runtime/MethodWrapper.cs b/src/IKVM.Runtime/MethodWrapper.cs
index fffca5da43..e5ef007597 100644
--- a/src/IKVM.Runtime/MethodWrapper.cs
+++ b/src/IKVM.Runtime/MethodWrapper.cs
@@ -25,8 +25,8 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
+
using System.Linq;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -38,11 +38,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
abstract class MethodWrapper : MemberWrapper
diff --git a/src/IKVM.Runtime/MirandaMethodWrapper.cs b/src/IKVM.Runtime/MirandaMethodWrapper.cs
index 1da17b02ab..b96e036332 100644
--- a/src/IKVM.Runtime/MirandaMethodWrapper.cs
+++ b/src/IKVM.Runtime/MirandaMethodWrapper.cs
@@ -24,20 +24,14 @@ Jeroen Frijters
using IKVM.Attributes;
#if IMPORTER || EXPORTER
-using IKVM.Reflection;
using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
abstract class MirandaMethodWrapper : SmartMethodWrapper
{
diff --git a/src/IKVM.Runtime/NamePrefix.cs b/src/IKVM.Runtime/NamePrefix.cs
index 2c9089c1b0..5d1352d0e0 100644
--- a/src/IKVM.Runtime/NamePrefix.cs
+++ b/src/IKVM.Runtime/NamePrefix.cs
@@ -22,8 +22,9 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class NamePrefix
{
diff --git a/src/IKVM.Runtime/NestedTypeName.cs b/src/IKVM.Runtime/NestedTypeName.cs
index 7adabfc099..722066eaa8 100644
--- a/src/IKVM.Runtime/NestedTypeName.cs
+++ b/src/IKVM.Runtime/NestedTypeName.cs
@@ -22,8 +22,9 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class NestedTypeName
{
diff --git a/src/IKVM.Runtime/NormalizedByteCode.cs b/src/IKVM.Runtime/NormalizedByteCode.cs
index 9e4f0b854f..04ce524341 100644
--- a/src/IKVM.Runtime/NormalizedByteCode.cs
+++ b/src/IKVM.Runtime/NormalizedByteCode.cs
@@ -21,175 +21,183 @@ Jeroen Frijters
jeroen@frijters.net
*/
-enum NormalizedByteCode : byte
+
+namespace IKVM.Runtime
{
- __nop = 0,
- __aconst_null = 1,
- __lconst_0 = 9,
- __lconst_1 = 10,
- __fconst_0 = 11,
- __fconst_1 = 12,
- __fconst_2 = 13,
- __dconst_0 = 14,
- __dconst_1 = 15,
- __ldc = 18,
- __iload = 21,
- __lload = 22,
- __fload = 23,
- __dload = 24,
- __aload = 25,
- __iaload = 46,
- __laload = 47,
- __faload = 48,
- __daload = 49,
- __aaload = 50,
- __baload = 51,
- __caload = 52,
- __saload = 53,
- __istore = 54,
- __lstore = 55,
- __fstore = 56,
- __dstore = 57,
- __astore = 58,
- __iastore = 79,
- __lastore = 80,
- __fastore = 81,
- __dastore = 82,
- __aastore = 83,
- __bastore = 84,
- __castore = 85,
- __sastore = 86,
- __pop = 87,
- __pop2 = 88,
- __dup = 89,
- __dup_x1 = 90,
- __dup_x2 = 91,
- __dup2 = 92,
- __dup2_x1 = 93,
- __dup2_x2 = 94,
- __swap = 95,
- __iadd = 96,
- __ladd = 97,
- __fadd = 98,
- __dadd = 99,
- __isub = 100,
- __lsub = 101,
- __fsub = 102,
- __dsub = 103,
- __imul = 104,
- __lmul = 105,
- __fmul = 106,
- __dmul = 107,
- __idiv = 108,
- __ldiv = 109,
- __fdiv = 110,
- __ddiv = 111,
- __irem = 112,
- __lrem = 113,
- __frem = 114,
- __drem = 115,
- __ineg = 116,
- __lneg = 117,
- __fneg = 118,
- __dneg = 119,
- __ishl = 120,
- __lshl = 121,
- __ishr = 122,
- __lshr = 123,
- __iushr = 124,
- __lushr = 125,
- __iand = 126,
- __land = 127,
- __ior = 128,
- __lor = 129,
- __ixor = 130,
- __lxor = 131,
- __iinc = 132,
- __i2l = 133,
- __i2f = 134,
- __i2d = 135,
- __l2i = 136,
- __l2f = 137,
- __l2d = 138,
- __f2i = 139,
- __f2l = 140,
- __f2d = 141,
- __d2i = 142,
- __d2l = 143,
- __d2f = 144,
- __i2b = 145,
- __i2c = 146,
- __i2s = 147,
- __lcmp = 148,
- __fcmpl = 149,
- __fcmpg = 150,
- __dcmpl = 151,
- __dcmpg = 152,
- __ifeq = 153,
- __ifne = 154,
- __iflt = 155,
- __ifge = 156,
- __ifgt = 157,
- __ifle = 158,
- __if_icmpeq = 159,
- __if_icmpne = 160,
- __if_icmplt = 161,
- __if_icmpge = 162,
- __if_icmpgt = 163,
- __if_icmple = 164,
- __if_acmpeq = 165,
- __if_acmpne = 166,
- __goto = 167,
- __jsr = 168,
- __ret = 169,
- __tableswitch = 170,
- __lookupswitch = 171,
- __ireturn = 172,
- __lreturn = 173,
- __freturn = 174,
- __dreturn = 175,
- __areturn = 176,
- __return = 177,
- __getstatic = 178,
- __putstatic = 179,
- __getfield = 180,
- __putfield = 181,
- __invokevirtual = 182,
- __invokespecial = 183,
- __invokestatic = 184,
- __invokeinterface = 185,
- __invokedynamic = 186,
- __new = 187,
- __newarray = 188,
- __anewarray = 189,
- __arraylength = 190,
- __athrow = 191,
- __checkcast = 192,
- __instanceof = 193,
- __monitorenter = 194,
- __monitorexit = 195,
- __multianewarray = 197,
- __ifnull = 198,
- __ifnonnull = 199,
- // This is where the pseudo-bytecodes start
- __privileged_invokestatic = 235, // the privileged bytecodes are used for accessing host class members
- __privileged_invokevirtual = 237,
- __privileged_invokespecial = 238,
- __ldc_nothrow = 239,
- __methodhandle_invoke = 240,
- __methodhandle_link = 241,
- __goto_finally = 242,
- __intrinsic_gettype = 243,
- __athrow_no_unmap = 244,
- __dynamic_getstatic = 245,
- __dynamic_putstatic = 246,
- __dynamic_getfield = 247,
- __dynamic_putfield = 248,
- __dynamic_invokeinterface = 249,
- __dynamic_invokestatic = 250,
- __dynamic_invokevirtual = 251,
- __dynamic_invokespecial = 252,
- __clone_array = 253,
- __static_error = 254, // not a real instruction, this signals an instruction that is compiled as an exception
- __iconst = 255
-}
+
+ enum NormalizedByteCode : byte
+ {
+
+ __nop = 0,
+ __aconst_null = 1,
+ __lconst_0 = 9,
+ __lconst_1 = 10,
+ __fconst_0 = 11,
+ __fconst_1 = 12,
+ __fconst_2 = 13,
+ __dconst_0 = 14,
+ __dconst_1 = 15,
+ __ldc = 18,
+ __iload = 21,
+ __lload = 22,
+ __fload = 23,
+ __dload = 24,
+ __aload = 25,
+ __iaload = 46,
+ __laload = 47,
+ __faload = 48,
+ __daload = 49,
+ __aaload = 50,
+ __baload = 51,
+ __caload = 52,
+ __saload = 53,
+ __istore = 54,
+ __lstore = 55,
+ __fstore = 56,
+ __dstore = 57,
+ __astore = 58,
+ __iastore = 79,
+ __lastore = 80,
+ __fastore = 81,
+ __dastore = 82,
+ __aastore = 83,
+ __bastore = 84,
+ __castore = 85,
+ __sastore = 86,
+ __pop = 87,
+ __pop2 = 88,
+ __dup = 89,
+ __dup_x1 = 90,
+ __dup_x2 = 91,
+ __dup2 = 92,
+ __dup2_x1 = 93,
+ __dup2_x2 = 94,
+ __swap = 95,
+ __iadd = 96,
+ __ladd = 97,
+ __fadd = 98,
+ __dadd = 99,
+ __isub = 100,
+ __lsub = 101,
+ __fsub = 102,
+ __dsub = 103,
+ __imul = 104,
+ __lmul = 105,
+ __fmul = 106,
+ __dmul = 107,
+ __idiv = 108,
+ __ldiv = 109,
+ __fdiv = 110,
+ __ddiv = 111,
+ __irem = 112,
+ __lrem = 113,
+ __frem = 114,
+ __drem = 115,
+ __ineg = 116,
+ __lneg = 117,
+ __fneg = 118,
+ __dneg = 119,
+ __ishl = 120,
+ __lshl = 121,
+ __ishr = 122,
+ __lshr = 123,
+ __iushr = 124,
+ __lushr = 125,
+ __iand = 126,
+ __land = 127,
+ __ior = 128,
+ __lor = 129,
+ __ixor = 130,
+ __lxor = 131,
+ __iinc = 132,
+ __i2l = 133,
+ __i2f = 134,
+ __i2d = 135,
+ __l2i = 136,
+ __l2f = 137,
+ __l2d = 138,
+ __f2i = 139,
+ __f2l = 140,
+ __f2d = 141,
+ __d2i = 142,
+ __d2l = 143,
+ __d2f = 144,
+ __i2b = 145,
+ __i2c = 146,
+ __i2s = 147,
+ __lcmp = 148,
+ __fcmpl = 149,
+ __fcmpg = 150,
+ __dcmpl = 151,
+ __dcmpg = 152,
+ __ifeq = 153,
+ __ifne = 154,
+ __iflt = 155,
+ __ifge = 156,
+ __ifgt = 157,
+ __ifle = 158,
+ __if_icmpeq = 159,
+ __if_icmpne = 160,
+ __if_icmplt = 161,
+ __if_icmpge = 162,
+ __if_icmpgt = 163,
+ __if_icmple = 164,
+ __if_acmpeq = 165,
+ __if_acmpne = 166,
+ __goto = 167,
+ __jsr = 168,
+ __ret = 169,
+ __tableswitch = 170,
+ __lookupswitch = 171,
+ __ireturn = 172,
+ __lreturn = 173,
+ __freturn = 174,
+ __dreturn = 175,
+ __areturn = 176,
+ __return = 177,
+ __getstatic = 178,
+ __putstatic = 179,
+ __getfield = 180,
+ __putfield = 181,
+ __invokevirtual = 182,
+ __invokespecial = 183,
+ __invokestatic = 184,
+ __invokeinterface = 185,
+ __invokedynamic = 186,
+ __new = 187,
+ __newarray = 188,
+ __anewarray = 189,
+ __arraylength = 190,
+ __athrow = 191,
+ __checkcast = 192,
+ __instanceof = 193,
+ __monitorenter = 194,
+ __monitorexit = 195,
+ __multianewarray = 197,
+ __ifnull = 198,
+ __ifnonnull = 199,
+ // This is where the pseudo-bytecodes start
+ __privileged_invokestatic = 235, // the privileged bytecodes are used for accessing host class members
+ __privileged_invokevirtual = 237,
+ __privileged_invokespecial = 238,
+ __ldc_nothrow = 239,
+ __methodhandle_invoke = 240,
+ __methodhandle_link = 241,
+ __goto_finally = 242,
+ __intrinsic_gettype = 243,
+ __athrow_no_unmap = 244,
+ __dynamic_getstatic = 245,
+ __dynamic_putstatic = 246,
+ __dynamic_getfield = 247,
+ __dynamic_putfield = 248,
+ __dynamic_invokeinterface = 249,
+ __dynamic_invokestatic = 250,
+ __dynamic_invokevirtual = 251,
+ __dynamic_invokespecial = 252,
+ __clone_array = 253,
+ __static_error = 254, // not a real instruction, this signals an instruction that is compiled as an exception
+ __iconst = 255
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.Runtime/PrimitiveTypeWrapper.cs b/src/IKVM.Runtime/PrimitiveTypeWrapper.cs
index bd6d579d59..4791e53e29 100644
--- a/src/IKVM.Runtime/PrimitiveTypeWrapper.cs
+++ b/src/IKVM.Runtime/PrimitiveTypeWrapper.cs
@@ -24,7 +24,6 @@ Jeroen Frijters
using System;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -36,11 +35,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class PrimitiveTypeWrapper : TypeWrapper
diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs
index 40576ea1fa..c85b9245b3 100644
--- a/src/IKVM.Runtime/ReflectUtil.cs
+++ b/src/IKVM.Runtime/ReflectUtil.cs
@@ -32,7 +32,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class ReflectUtil
diff --git a/src/IKVM.Runtime/Serialization.cs b/src/IKVM.Runtime/Serialization.cs
index c5f70fa896..00148fc738 100644
--- a/src/IKVM.Runtime/Serialization.cs
+++ b/src/IKVM.Runtime/Serialization.cs
@@ -25,8 +25,6 @@ Jeroen Frijters
using System.Runtime.Serialization;
using System.Security;
-using IKVM.Runtime;
-
#if IMPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
@@ -38,7 +36,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class Serialization
diff --git a/src/IKVM.Runtime/SimpleCallMethodWrapper.cs b/src/IKVM.Runtime/SimpleCallMethodWrapper.cs
index eadebf62ca..e9fb971dd6 100644
--- a/src/IKVM.Runtime/SimpleCallMethodWrapper.cs
+++ b/src/IKVM.Runtime/SimpleCallMethodWrapper.cs
@@ -25,19 +25,13 @@ Jeroen Frijters
#if IMPORTER || EXPORTER
using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
sealed class SimpleCallMethodWrapper : MethodWrapper
{
diff --git a/src/IKVM.Runtime/SimpleFieldWrapper.cs b/src/IKVM.Runtime/SimpleFieldWrapper.cs
index 30b1ab6b65..73e51fd8bd 100644
--- a/src/IKVM.Runtime/SimpleFieldWrapper.cs
+++ b/src/IKVM.Runtime/SimpleFieldWrapper.cs
@@ -23,25 +23,20 @@ Jeroen Frijters
*/
using System.Diagnostics;
-using IKVM.Runtime;
-
#if IMPORTER || EXPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
-
#endif
#if IMPORTER
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/SimpleOpCode.cs b/src/IKVM.Runtime/SimpleOpCode.cs
index fd4eba0789..e01c28878f 100644
--- a/src/IKVM.Runtime/SimpleOpCode.cs
+++ b/src/IKVM.Runtime/SimpleOpCode.cs
@@ -22,25 +22,16 @@ Jeroen Frijters
*/
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
-#else
-#endif
-
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
enum SimpleOpCode : byte
{
+
Call,
Callvirt,
Newobj
+
}
}
diff --git a/src/IKVM.Runtime/SmartMethodWrapper.cs b/src/IKVM.Runtime/SmartMethodWrapper.cs
index 74d34cbe33..96399c90b3 100644
--- a/src/IKVM.Runtime/SmartMethodWrapper.cs
+++ b/src/IKVM.Runtime/SmartMethodWrapper.cs
@@ -27,19 +27,13 @@ Jeroen Frijters
#if IMPORTER || EXPORTER
using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
abstract class SmartMethodWrapper : MethodWrapper
{
diff --git a/src/IKVM.Runtime/StackState.cs b/src/IKVM.Runtime/StackState.cs
new file mode 100644
index 0000000000..f0db760331
--- /dev/null
+++ b/src/IKVM.Runtime/StackState.cs
@@ -0,0 +1,122 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+
+namespace IKVM.Runtime
+{
+
+ struct StackState
+ {
+
+ private InstructionState state;
+ private int sp;
+
+ internal StackState(InstructionState state)
+ {
+ this.state = state;
+ sp = state.GetStackHeight();
+ }
+
+ internal TypeWrapper PeekType()
+ {
+ if (sp == 0)
+ {
+ throw new VerifyError("Unable to pop operand off an empty stack");
+ }
+ TypeWrapper type = state.GetStackByIndex(sp - 1);
+ if (VerifierTypeWrapper.IsThis(type))
+ {
+ type = ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ return type;
+ }
+
+ internal TypeWrapper PopAnyType()
+ {
+ if (sp == 0)
+ {
+ throw new VerifyError("Unable to pop operand off an empty stack");
+ }
+ TypeWrapper type = state.GetStackByIndex(--sp);
+ if (VerifierTypeWrapper.IsThis(type))
+ {
+ type = ((VerifierTypeWrapper)type).UnderlyingType;
+ }
+ if (VerifierTypeWrapper.IsFaultBlockException(type))
+ {
+ VerifierTypeWrapper.ClearFaultBlockException(type);
+ type = CoreClasses.java.lang.Throwable.Wrapper;
+ }
+ return type;
+ }
+
+ internal TypeWrapper PopType(TypeWrapper baseType)
+ {
+ return InstructionState.PopTypeImpl(baseType, PopAnyType());
+ }
+
+ // NOTE this can *not* be used to pop double or long
+ internal TypeWrapper PopType()
+ {
+ return InstructionState.PopTypeImpl(PopAnyType());
+ }
+
+ internal void PopInt()
+ {
+ InstructionState.PopIntImpl(PopAnyType());
+ }
+
+ internal void PopFloat()
+ {
+ InstructionState.PopFloatImpl(PopAnyType());
+ }
+
+ internal void PopDouble()
+ {
+ InstructionState.PopDoubleImpl(PopAnyType());
+ }
+
+ internal void PopLong()
+ {
+ InstructionState.PopLongImpl(PopAnyType());
+ }
+
+ internal TypeWrapper PopArrayType()
+ {
+ return InstructionState.PopArrayTypeImpl(PopAnyType());
+ }
+
+ // either null or an initialized object reference
+ internal TypeWrapper PopObjectType()
+ {
+ return InstructionState.PopObjectTypeImpl(PopAnyType());
+ }
+
+ // null or an initialized object reference derived from baseType (or baseType)
+ internal TypeWrapper PopObjectType(TypeWrapper baseType)
+ {
+ return InstructionState.PopObjectTypeImpl(baseType, PopObjectType());
+ }
+ }
+
+}
diff --git a/src/IKVM.Runtime/StringConstants.cs b/src/IKVM.Runtime/StringConstants.cs
index 1cc5f1f221..6cf5a8e554 100644
--- a/src/IKVM.Runtime/StringConstants.cs
+++ b/src/IKVM.Runtime/StringConstants.cs
@@ -22,7 +22,7 @@ Jeroen Frijters
*/
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class StringConstants
diff --git a/src/IKVM.Runtime/StubGen/AnnotationDefaultClassFileAttribute.cs b/src/IKVM.Runtime/StubGen/AnnotationDefaultClassFileAttribute.cs
index b033003c56..46996f0fb1 100644
--- a/src/IKVM.Runtime/StubGen/AnnotationDefaultClassFileAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/AnnotationDefaultClassFileAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class AnnotationDefaultClassFileAttribute : ClassFileAttribute
{
+
private ClassFileWriter classFile;
private byte[] buf;
@@ -45,5 +47,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte(b);
}
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/BigEndianStream.cs b/src/IKVM.Runtime/StubGen/BigEndianStream.cs
index 6a6ca46b13..3c667aeae4 100644
--- a/src/IKVM.Runtime/StubGen/BigEndianStream.cs
+++ b/src/IKVM.Runtime/StubGen/BigEndianStream.cs
@@ -26,8 +26,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class BigEndianStream
{
+
private Stream stream;
public BigEndianStream(Stream stream)
@@ -108,5 +110,7 @@ public void WriteUtf8(string str)
WriteUInt16((ushort)j);
stream.Write(buf, 0, j);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ClassFileAttribute.cs b/src/IKVM.Runtime/StubGen/ClassFileAttribute.cs
index 8ef21b5c5f..ab5e1e2b50 100644
--- a/src/IKVM.Runtime/StubGen/ClassFileAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/ClassFileAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
abstract class ClassFileAttribute
{
+
private ushort name_index;
public ClassFileAttribute(ushort name_index)
@@ -37,5 +39,7 @@ public virtual void Write(BigEndianStream bes)
{
bes.WriteUInt16(name_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ClassFileWriter.cs b/src/IKVM.Runtime/StubGen/ClassFileWriter.cs
index 5c306b2aeb..11ed4748dd 100644
--- a/src/IKVM.Runtime/StubGen/ClassFileWriter.cs
+++ b/src/IKVM.Runtime/StubGen/ClassFileWriter.cs
@@ -32,6 +32,7 @@ namespace IKVM.StubGen
sealed class ClassFileWriter : IAttributeOwner
{
+
private List cplist = new List();
private Dictionary cphashtable = new Dictionary();
private List fields = new List();
@@ -239,6 +240,7 @@ public void Write(Stream stream)
attribs[i].Write(bes);
}
}
+
}
}
diff --git a/src/IKVM.Runtime/StubGen/CodeAttribute.cs b/src/IKVM.Runtime/StubGen/CodeAttribute.cs
index d41460a81f..a73de1dd3d 100644
--- a/src/IKVM.Runtime/StubGen/CodeAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/CodeAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class CodeAttribute : ClassFileAttribute
{
+
private ClassFileWriter classFile;
private ushort max_stack;
private ushort max_locals;
@@ -69,5 +71,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt16(0); // no exceptions
bes.WriteUInt16(0); // no attributes
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/Constant.cs b/src/IKVM.Runtime/StubGen/Constant.cs
index 023e4bce59..d45bbb6ec2 100644
--- a/src/IKVM.Runtime/StubGen/Constant.cs
+++ b/src/IKVM.Runtime/StubGen/Constant.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
enum Constant
{
+
Utf8 = 1,
Integer = 3,
Float = 4,
@@ -37,5 +39,7 @@ enum Constant
Methodref = 10,
InterfaceMethodref = 11,
NameAndType = 12
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItem.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItem.cs
index 36a7c89d09..9a17aea004 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItem.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItem.cs
@@ -24,8 +24,11 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
abstract class ConstantPoolItem
- {
- public abstract void Write(BigEndianStream bes);
- }
+ {
+
+ public abstract void Write(BigEndianStream bes);
+ }
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemClass.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemClass.cs
index 92d5a80f3f..6e9ccb6d25 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemClass.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemClass.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemClass : ConstantPoolItem
{
+
private ushort name_index;
public ConstantPoolItemClass(ushort name_index)
@@ -52,5 +54,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Class);
bes.WriteUInt16(name_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemDouble.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemDouble.cs
index 7553259445..2024f0f95a 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemDouble.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemDouble.cs
@@ -25,8 +25,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemDouble : ConstantPoolItem
{
+
private double v;
public ConstantPoolItemDouble(double v)
@@ -54,5 +56,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Double);
bes.WriteDouble(v);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemFloat.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemFloat.cs
index 043193d6c1..a9e65f7495 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemFloat.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemFloat.cs
@@ -25,8 +25,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemFloat : ConstantPoolItem
{
+
private float v;
public ConstantPoolItemFloat(float v)
@@ -53,5 +55,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Float);
bes.WriteFloat(v);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemInt.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemInt.cs
index 25dbc71fc7..6671a04d76 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemInt.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemInt.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemInt : ConstantPoolItem
{
+
private int v;
public ConstantPoolItemInt(int v)
@@ -52,5 +54,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Integer);
bes.WriteUInt32((uint)v);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemLong.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemLong.cs
index 4f044962d3..4ea35e09f8 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemLong.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemLong.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemLong : ConstantPoolItem
{
+
private long v;
public ConstantPoolItemLong(long v)
@@ -52,5 +54,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Long);
bes.WriteInt64(v);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemMethodref.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemMethodref.cs
index 3f424d9e1e..a348e5225e 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemMethodref.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemMethodref.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemMethodref : ConstantPoolItem
{
+
private ushort class_index;
private ushort name_and_type_index;
@@ -56,5 +58,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt16(class_index);
bes.WriteUInt16(name_and_type_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemNameAndType.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemNameAndType.cs
index 977b5e9dfd..c946e069d0 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemNameAndType.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemNameAndType.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemNameAndType : ConstantPoolItem
{
+
private ushort name_index;
private ushort descriptor_index;
@@ -56,5 +58,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt16(name_index);
bes.WriteUInt16(descriptor_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemString.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemString.cs
index 34938d8e27..08a1a0e495 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemString.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemString.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemString : ConstantPoolItem
{
+
private ushort string_index;
public ConstantPoolItemString(ushort string_index)
@@ -52,5 +54,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.String);
bes.WriteUInt16(string_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantPoolItemUtf8.cs b/src/IKVM.Runtime/StubGen/ConstantPoolItemUtf8.cs
index 518c9cd029..bc1fe7cb40 100644
--- a/src/IKVM.Runtime/StubGen/ConstantPoolItemUtf8.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantPoolItemUtf8.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantPoolItemUtf8 : ConstantPoolItem
{
+
private string str;
public ConstantPoolItemUtf8(string str)
@@ -52,5 +54,7 @@ public override void Write(BigEndianStream bes)
bes.WriteByte((byte)Constant.Utf8);
bes.WriteUtf8(str);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ConstantValueAttribute.cs b/src/IKVM.Runtime/StubGen/ConstantValueAttribute.cs
index 43a1b026ea..d35d884282 100644
--- a/src/IKVM.Runtime/StubGen/ConstantValueAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/ConstantValueAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ConstantValueAttribute : ClassFileAttribute
{
+
private ushort constant_index;
public ConstantValueAttribute(ushort name_index, ushort constant_index)
@@ -40,5 +42,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt32(2);
bes.WriteUInt16(constant_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/DeprecatedAttribute.cs b/src/IKVM.Runtime/StubGen/DeprecatedAttribute.cs
index 9c94944ce6..15ca9fd5c3 100644
--- a/src/IKVM.Runtime/StubGen/DeprecatedAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/DeprecatedAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class DeprecatedAttribute : ClassFileAttribute
{
+
internal DeprecatedAttribute(ClassFileWriter classFile)
: base(classFile.AddUtf8("Deprecated"))
{
@@ -36,5 +38,7 @@ public override void Write(BigEndianStream bes)
base.Write(bes);
bes.WriteUInt32(0);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/ExceptionsAttribute.cs b/src/IKVM.Runtime/StubGen/ExceptionsAttribute.cs
index da454f3a6d..49caff7318 100644
--- a/src/IKVM.Runtime/StubGen/ExceptionsAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/ExceptionsAttribute.cs
@@ -25,8 +25,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class ExceptionsAttribute : ClassFileAttribute
{
+
private ClassFileWriter classFile;
private List classes = new List();
@@ -51,5 +53,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt16(idx);
}
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/FieldOrMethod.cs b/src/IKVM.Runtime/StubGen/FieldOrMethod.cs
index 6e27f8363f..14699a6f60 100644
--- a/src/IKVM.Runtime/StubGen/FieldOrMethod.cs
+++ b/src/IKVM.Runtime/StubGen/FieldOrMethod.cs
@@ -27,8 +27,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class FieldOrMethod : IAttributeOwner
{
+
private Modifiers access_flags;
private ushort name_index;
private ushort descriptor_index;
@@ -57,5 +59,7 @@ public void Write(BigEndianStream bes)
attribs[i].Write(bes);
}
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/IAttributeOwner.cs b/src/IKVM.Runtime/StubGen/IAttributeOwner.cs
index a5c2035340..d1a00616c2 100644
--- a/src/IKVM.Runtime/StubGen/IAttributeOwner.cs
+++ b/src/IKVM.Runtime/StubGen/IAttributeOwner.cs
@@ -24,8 +24,12 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
interface IAttributeOwner
{
+
void AddAttribute(ClassFileAttribute attrib);
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/InnerClassesAttribute.cs b/src/IKVM.Runtime/StubGen/InnerClassesAttribute.cs
index 38a98761a4..ac05c5c2da 100644
--- a/src/IKVM.Runtime/StubGen/InnerClassesAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/InnerClassesAttribute.cs
@@ -25,8 +25,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class InnerClassesAttribute : ClassFileAttribute
{
+
private ClassFileWriter classFile;
private List- classes = new List
- ();
@@ -70,5 +72,7 @@ public void Add(string inner, string outer, string name, ushort access)
i.inner_class_access_flags = access;
classes.Add(i);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/MethodParametersAttribute.cs b/src/IKVM.Runtime/StubGen/MethodParametersAttribute.cs
index 1f34df3621..5b79728c01 100644
--- a/src/IKVM.Runtime/StubGen/MethodParametersAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/MethodParametersAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class MethodParametersAttribute : ClassFileAttribute
{
+
private readonly ClassFileWriter classFile;
private readonly ushort[] names;
private readonly ushort[] flags;
@@ -55,5 +57,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt16(flags[i]);
}
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/RuntimeVisibleAnnotationsAttribute.cs b/src/IKVM.Runtime/StubGen/RuntimeVisibleAnnotationsAttribute.cs
index 5674f0f198..c4eea5710d 100644
--- a/src/IKVM.Runtime/StubGen/RuntimeVisibleAnnotationsAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/RuntimeVisibleAnnotationsAttribute.cs
@@ -27,8 +27,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class RuntimeVisibleAnnotationsAttribute : ClassFileAttribute
{
+
private ClassFileWriter classFile;
private MemoryStream mem;
private BigEndianStream bes;
@@ -176,5 +178,7 @@ internal uint Length
{
get { return (uint)mem.Length + 2; }
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/RuntimeVisibleParameterAnnotationsAttribute.cs b/src/IKVM.Runtime/StubGen/RuntimeVisibleParameterAnnotationsAttribute.cs
index 718307d1e6..aee6935a78 100644
--- a/src/IKVM.Runtime/StubGen/RuntimeVisibleParameterAnnotationsAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/RuntimeVisibleParameterAnnotationsAttribute.cs
@@ -25,8 +25,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class RuntimeVisibleParameterAnnotationsAttribute : ClassFileAttribute
{
+
private readonly List parameters = new List();
internal RuntimeVisibleParameterAnnotationsAttribute(ClassFileWriter classFile)
@@ -54,5 +56,7 @@ public override void Write(BigEndianStream bes)
attr.WriteImpl(bes);
}
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/RuntimeVisibleTypeAnnotationsAttribute.cs b/src/IKVM.Runtime/StubGen/RuntimeVisibleTypeAnnotationsAttribute.cs
index 0703a3b510..8256941d79 100644
--- a/src/IKVM.Runtime/StubGen/RuntimeVisibleTypeAnnotationsAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/RuntimeVisibleTypeAnnotationsAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class RuntimeVisibleTypeAnnotationsAttribute : ClassFileAttribute
{
+
private readonly byte[] data;
internal RuntimeVisibleTypeAnnotationsAttribute(ClassFileWriter classFile, byte[] data)
@@ -40,5 +42,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt32((uint)data.Length);
bes.WriteBytes(data);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/SerialVersionUID.cs b/src/IKVM.Runtime/StubGen/SerialVersionUID.cs
index 915dec98d9..147a1a2ea1 100644
--- a/src/IKVM.Runtime/StubGen/SerialVersionUID.cs
+++ b/src/IKVM.Runtime/StubGen/SerialVersionUID.cs
@@ -26,7 +26,7 @@ Jeroen Frijters
using System.Security.Cryptography;
using IKVM.Attributes;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.StubGen
{
@@ -34,6 +34,7 @@ namespace IKVM.StubGen
static class SerialVersionUID
{
+
readonly static SHA1 sha1 = SHA1.Create();
internal static long Compute(TypeWrapper tw)
diff --git a/src/IKVM.Runtime/StubGen/StringAttribute.cs b/src/IKVM.Runtime/StubGen/StringAttribute.cs
index d7e4e1dcb3..79f8377d99 100644
--- a/src/IKVM.Runtime/StubGen/StringAttribute.cs
+++ b/src/IKVM.Runtime/StubGen/StringAttribute.cs
@@ -24,8 +24,10 @@ Jeroen Frijters
namespace IKVM.StubGen
{
+
sealed class StringAttribute : ClassFileAttribute
{
+
private ushort string_index;
public StringAttribute(ushort name_index, ushort string_index)
@@ -40,5 +42,7 @@ public override void Write(BigEndianStream bes)
bes.WriteUInt32(2);
bes.WriteUInt16(string_index);
}
+
}
+
}
diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs
index 3e08781a38..c04e1389e2 100644
--- a/src/IKVM.Runtime/StubGen/StubGenerator.cs
+++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Collections.Generic;
using IKVM.Attributes;
-using IKVM.Internal;
using IKVM.Runtime;
#if EXPORTER
diff --git a/src/IKVM.Runtime/TypeFlags.cs b/src/IKVM.Runtime/TypeFlags.cs
index 8d942f5521..73b9ea6f72 100644
--- a/src/IKVM.Runtime/TypeFlags.cs
+++ b/src/IKVM.Runtime/TypeFlags.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
[Flags]
diff --git a/src/IKVM.Runtime/TypeNameUtil.cs b/src/IKVM.Runtime/TypeNameUtil.cs
index ba501098ef..b491902766 100644
--- a/src/IKVM.Runtime/TypeNameUtil.cs
+++ b/src/IKVM.Runtime/TypeNameUtil.cs
@@ -22,22 +22,12 @@ Jeroen Frijters
*/
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
-#else
-#endif
-
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class TypeNameUtil
{
+
// note that MangleNestedTypeName() assumes that there are less than 16 special characters
private const string specialCharactersString = "\\+,[]*&\u0000";
internal const string ProxiesContainer = "__";
@@ -149,6 +139,7 @@ internal static string GetProxyName(TypeWrapper[] interfaces)
{
return ProxiesContainer + "+" + GetProxyNestedName(interfaces);
}
+
}
}
diff --git a/src/IKVM.Runtime/TypeWrapper.cs b/src/IKVM.Runtime/TypeWrapper.cs
index 8b5c8343c0..23c6c849fc 100644
--- a/src/IKVM.Runtime/TypeWrapper.cs
+++ b/src/IKVM.Runtime/TypeWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Diagnostics;
using IKVM.Attributes;
-using IKVM.Runtime;
#if IMPORTER || EXPORTER
using IKVM.Reflection;
@@ -42,7 +41,7 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/TypeWrapperFactory.cs b/src/IKVM.Runtime/TypeWrapperFactory.cs
index dba010a90f..dab144844e 100644
--- a/src/IKVM.Runtime/TypeWrapperFactory.cs
+++ b/src/IKVM.Runtime/TypeWrapperFactory.cs
@@ -25,13 +25,10 @@ Jeroen Frijters
using System;
using System.Collections.Generic;
-#if NETCOREAPP
-using System.Runtime.Loader;
-#endif
-
#if IMPORTER || EXPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+
using Type = IKVM.Reflection.Type;
using ProtectionDomain = System.Object;
#else
@@ -41,7 +38,7 @@ Jeroen Frijters
using ProtectionDomain = java.security.ProtectionDomain;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
#if !EXPORTER
diff --git a/src/IKVM.Runtime/Types.cs b/src/IKVM.Runtime/Types.cs
index 7b2718bb11..bafb1525c3 100644
--- a/src/IKVM.Runtime/Types.cs
+++ b/src/IKVM.Runtime/Types.cs
@@ -23,13 +23,11 @@ Jeroen Frijters
*/
using System;
-using IKVM.Runtime;
-
#if IMPORTER || EXPORTER
using Type = IKVM.Reflection.Type;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
static class Types
diff --git a/src/IKVM.Runtime/TypicalMethodWrapper.cs b/src/IKVM.Runtime/TypicalMethodWrapper.cs
index d1f96eab13..88ab6530e5 100644
--- a/src/IKVM.Runtime/TypicalMethodWrapper.cs
+++ b/src/IKVM.Runtime/TypicalMethodWrapper.cs
@@ -33,11 +33,7 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
sealed class TypicalMethodWrapper : SmartMethodWrapper
{
diff --git a/src/IKVM.Runtime/UnicodeUtil.cs b/src/IKVM.Runtime/UnicodeUtil.cs
index df47087142..3955f23ab7 100644
--- a/src/IKVM.Runtime/UnicodeUtil.cs
+++ b/src/IKVM.Runtime/UnicodeUtil.cs
@@ -23,22 +23,12 @@ Jeroen Frijters
*/
using System;
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
-#else
-#endif
-
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
static class UnicodeUtil
{
+
// We use part of the Supplementary Private Use Area-B to encode
// invalid surrogates. If we encounter either of these two
// markers, we always encode the surrogate (single or pair)
diff --git a/src/IKVM.Runtime/UnloadableTypeWrapper.cs b/src/IKVM.Runtime/UnloadableTypeWrapper.cs
index 1e9e7b8399..e484340956 100644
--- a/src/IKVM.Runtime/UnloadableTypeWrapper.cs
+++ b/src/IKVM.Runtime/UnloadableTypeWrapper.cs
@@ -35,8 +35,9 @@ Jeroen Frijters
using IKVM.Tools.Importer;
#endif
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
sealed class UnloadableTypeWrapper : TypeWrapper
{
@@ -66,10 +67,7 @@ internal UnloadableTypeWrapper(string name, Type customModifier) :
this.customModifier = customModifier;
}
- internal override TypeWrapper BaseTypeWrapper
- {
- get { return null; }
- }
+ internal override TypeWrapper BaseTypeWrapper => null;
internal override ClassLoaderWrapper GetClassLoader()
{
@@ -102,13 +100,7 @@ protected override void LazyPublishMembers()
throw new InvalidOperationException("LazyPublishMembers called on UnloadableTypeWrapper: " + Name);
}
- internal override Type TypeAsTBD
- {
- get
- {
- throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
- }
- }
+ internal override Type TypeAsTBD => throw new InvalidOperationException("get_Type called on UnloadableTypeWrapper: " + Name);
internal override TypeWrapper[] Interfaces
{
@@ -126,36 +118,18 @@ internal override TypeWrapper[] Interfaces
}
}
- internal override TypeWrapper[] InnerClasses
- {
- get
- {
- throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper: " + Name);
- }
- }
+ internal override TypeWrapper[] InnerClasses => throw new InvalidOperationException("get_InnerClasses called on UnloadableTypeWrapper: " + Name);
- internal override TypeWrapper DeclaringTypeWrapper
- {
- get
- {
- throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
- }
- }
+ internal override TypeWrapper DeclaringTypeWrapper => throw new InvalidOperationException("get_DeclaringTypeWrapper called on UnloadableTypeWrapper: " + Name);
internal override void Finish()
{
throw new InvalidOperationException("Finish called on UnloadableTypeWrapper: " + Name);
}
- internal Type MissingType
- {
- get { return missingType; }
- }
+ internal Type MissingType => missingType;
- internal Type CustomModifier
- {
- get { return customModifier; }
- }
+ internal Type CustomModifier => customModifier;
internal void SetCustomModifier(Type type)
{
diff --git a/src/IKVM.Runtime/UntangledExceptionTable.cs b/src/IKVM.Runtime/UntangledExceptionTable.cs
new file mode 100644
index 0000000000..cf12988fb8
--- /dev/null
+++ b/src/IKVM.Runtime/UntangledExceptionTable.cs
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2002-2014 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System;
+
+using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry;
+
+namespace IKVM.Runtime
+{
+
+ struct UntangledExceptionTable
+ {
+ private readonly ExceptionTableEntry[] exceptions;
+
+ internal UntangledExceptionTable(ExceptionTableEntry[] exceptions)
+ {
+#if DEBUG
+ for (int i = 0; i < exceptions.Length; i++)
+ {
+ for (int j = i + 1; j < exceptions.Length; j++)
+ {
+ // check for partially overlapping try blocks (which is legal for the JVM, but not the CLR)
+ if (exceptions[i].startIndex < exceptions[j].startIndex &&
+ exceptions[j].startIndex < exceptions[i].endIndex &&
+ exceptions[i].endIndex < exceptions[j].endIndex)
+ {
+ throw new InvalidOperationException("Partially overlapping try blocks is broken");
+ }
+ // check that we didn't destroy the ordering, when sorting
+ if (exceptions[i].startIndex <= exceptions[j].startIndex &&
+ exceptions[i].endIndex >= exceptions[j].endIndex &&
+ exceptions[i].ordinal < exceptions[j].ordinal)
+ {
+ throw new InvalidOperationException("Non recursive try blocks is broken");
+ }
+ }
+ }
+#endif
+ this.exceptions = exceptions;
+ }
+
+ internal ExceptionTableEntry this[int index]
+ {
+ get { return exceptions[index]; }
+ }
+
+ internal int Length
+ {
+ get { return exceptions.Length; }
+ }
+
+ internal void SetFinally(int index)
+ {
+ exceptions[index] = new ExceptionTableEntry(exceptions[index].startIndex, exceptions[index].endIndex, exceptions[index].handlerIndex, exceptions[index].catch_type, exceptions[index].ordinal, true);
+ }
+ }
+
+}
diff --git a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs
index b916d3b281..00c03b8ba4 100644
--- a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs
+++ b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs
@@ -33,7 +33,7 @@
using System.Reflection.Emit;
using IKVM.Attributes;
-using IKVM.Internal;
+using IKVM.Runtime;
using java.lang.invoke;
diff --git a/src/IKVM.Runtime/Util/Java/Nio/DirectBufferMemoryManager.cs b/src/IKVM.Runtime/Util/Java/Nio/DirectBufferMemoryManager.cs
index 41e48b57ce..a1499920e1 100644
--- a/src/IKVM.Runtime/Util/Java/Nio/DirectBufferMemoryManager.cs
+++ b/src/IKVM.Runtime/Util/Java/Nio/DirectBufferMemoryManager.cs
@@ -1,7 +1,7 @@
using System;
using System.Buffers;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Lang;
namespace IKVM.Runtime.Util.Java.Nio
diff --git a/src/IKVM.Runtime/VerifierTypeWrapper.cs b/src/IKVM.Runtime/VerifierTypeWrapper.cs
index 57a57c32ff..f0dec8de74 100644
--- a/src/IKVM.Runtime/VerifierTypeWrapper.cs
+++ b/src/IKVM.Runtime/VerifierTypeWrapper.cs
@@ -28,15 +28,11 @@ Jeroen Frijters
using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;
-#else
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
+
// this is a container for the special verifier TypeWrappers
sealed class VerifierTypeWrapper : TypeWrapper
{
diff --git a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs
index 5cbfb6337b..58a612542a 100644
--- a/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs
+++ b/src/IKVM.Runtime/Vfs/VfsAssemblyClassDirectory.cs
@@ -4,7 +4,7 @@
using System.Linq;
using System.Reflection;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime.Syntax;
namespace IKVM.Runtime.Vfs
diff --git a/src/IKVM.Runtime/Vfs/VfsAssemblyClassFile.cs b/src/IKVM.Runtime/Vfs/VfsAssemblyClassFile.cs
index fae0a0dd20..67ef61a574 100644
--- a/src/IKVM.Runtime/Vfs/VfsAssemblyClassFile.cs
+++ b/src/IKVM.Runtime/Vfs/VfsAssemblyClassFile.cs
@@ -1,7 +1,7 @@
using System;
using System.IO;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Runtime.Accessors.Java.Lang;
namespace IKVM.Runtime.Vfs
diff --git a/src/IKVM.Runtime/VolatileLongDoubleFieldWrapper.cs b/src/IKVM.Runtime/VolatileLongDoubleFieldWrapper.cs
index db5cdb1228..36800198c1 100644
--- a/src/IKVM.Runtime/VolatileLongDoubleFieldWrapper.cs
+++ b/src/IKVM.Runtime/VolatileLongDoubleFieldWrapper.cs
@@ -23,23 +23,15 @@ Jeroen Frijters
*/
using System;
-using IKVM.Runtime;
-
#if IMPORTER || EXPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
-
-using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
using System.Reflection.Emit;
#endif
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
///
diff --git a/src/IKVM.Runtime/atomic.cs b/src/IKVM.Runtime/atomic.cs
index 5005d7e6e5..07211572d7 100644
--- a/src/IKVM.Runtime/atomic.cs
+++ b/src/IKVM.Runtime/atomic.cs
@@ -23,22 +23,24 @@ Jeroen Frijters
*/
using System;
-using IKVM.Internal;
+
using IKVM.Runtime;
#if IMPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+
using Type = IKVM.Reflection.Type;
#else
using System.Reflection;
using System.Reflection.Emit;
#endif
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
static class AtomicReferenceFieldUpdaterEmitter
{
+
internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags)
{
if (i >= 3
diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs
index 100795aeec..a3ea79ff03 100644
--- a/src/IKVM.Runtime/compiler.cs
+++ b/src/IKVM.Runtime/compiler.cs
@@ -27,7 +27,6 @@ Jeroen Frijters
using System.Diagnostics.SymbolStore;
using IKVM.Attributes;
-using IKVM.Internal;
using IKVM.ByteCode;
#if IMPORTER
@@ -41,10 +40,10 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-using ExceptionTableEntry = IKVM.Internal.ClassFile.Method.ExceptionTableEntry;
-using LocalVariableTableEntry = IKVM.Internal.ClassFile.Method.LocalVariableTableEntry;
-using Instruction = IKVM.Internal.ClassFile.Method.Instruction;
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
+using ExceptionTableEntry = IKVM.Runtime.ClassFile.Method.ExceptionTableEntry;
+using LocalVariableTableEntry = IKVM.Runtime.ClassFile.Method.LocalVariableTableEntry;
+using Instruction = IKVM.Runtime.ClassFile.Method.Instruction;
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
namespace IKVM.Runtime
{
diff --git a/src/IKVM.Runtime/intrinsics.cs b/src/IKVM.Runtime/intrinsics.cs
index f012292cd8..a903f1d796 100644
--- a/src/IKVM.Runtime/intrinsics.cs
+++ b/src/IKVM.Runtime/intrinsics.cs
@@ -25,8 +25,6 @@ Jeroen Frijters
using System;
using System.Collections.Generic;
-using IKVM.Runtime;
-
#if IMPORTER
using IKVM.Reflection;
using IKVM.Reflection.Emit;
@@ -38,105 +36,17 @@ Jeroen Frijters
using System.Reflection.Emit;
#endif
-using Instruction = IKVM.Internal.ClassFile.Method.Instruction;
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
+using Instruction = IKVM.Runtime.ClassFile.Method.Instruction;
+using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
- sealed class EmitIntrinsicContext
- {
-
- internal readonly MethodWrapper Method;
- internal readonly DynamicTypeWrapper.FinishContext Context;
- internal readonly CodeEmitter Emitter;
- readonly CodeInfo ma;
- internal readonly int OpcodeIndex;
- internal readonly MethodWrapper Caller;
- internal readonly ClassFile ClassFile;
- internal readonly Instruction[] Code;
- internal readonly InstructionFlags[] Flags;
- internal bool NonLeaf = true;
-
- internal EmitIntrinsicContext(MethodWrapper method, DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, CodeInfo ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags)
- {
- this.Method = method;
- this.Context = context;
- this.Emitter = ilgen;
- this.ma = ma;
- this.OpcodeIndex = opcodeIndex;
- this.Caller = caller;
- this.ClassFile = classFile;
- this.Code = code;
- this.Flags = flags;
- }
-
- internal bool MatchRange(int offset, int length)
- {
- if (OpcodeIndex + offset < 0)
- return false;
-
- if (OpcodeIndex + offset + length > Code.Length)
- return false;
-
- // we check for branches *into* the range, the start of the range may be a branch target
- for (int i = OpcodeIndex + offset + 1, end = OpcodeIndex + offset + length; i < end; i++)
- if ((Flags[i] & InstructionFlags.BranchTarget) != 0)
- return false;
-
- return true;
- }
-
- internal bool Match(int offset, NormalizedByteCode opcode)
- {
- return Code[OpcodeIndex + offset].NormalizedOpCode == opcode;
- }
-
- internal bool Match(int offset, NormalizedByteCode opcode, int arg)
- {
- return Code[OpcodeIndex + offset].NormalizedOpCode == opcode && Code[OpcodeIndex + offset].Arg1 == arg;
- }
-
- internal TypeWrapper GetStackTypeWrapper(int offset, int pos)
- {
- return ma.GetStackTypeWrapper(OpcodeIndex + offset, pos);
- }
-
- internal ClassFile.ConstantPoolItemMI GetMethodref(int offset)
- {
- return ClassFile.GetMethodref(Code[OpcodeIndex + offset].Arg1);
- }
-
- internal ClassFile.ConstantPoolItemFieldref GetFieldref(int offset)
- {
- return ClassFile.GetFieldref(Code[OpcodeIndex + offset].Arg1);
- }
-
- internal TypeWrapper GetClassLiteral(int offset)
- {
- return ClassFile.GetConstantPoolClassType(Code[OpcodeIndex + offset].Arg1);
- }
-
- internal string GetStringLiteral(int offset)
- {
- return ClassFile.GetConstantPoolConstantString(Code[OpcodeIndex + offset].Arg1);
- }
-
- internal ClassFile.ConstantType GetConstantType(int offset)
- {
- return ClassFile.GetConstantPoolConstantType(Code[OpcodeIndex + offset].Arg1);
- }
-
- internal void PatchOpCode(int offset, NormalizedByteCode opc)
- {
- Code[OpcodeIndex + offset].PatchOpCode(opc);
- }
-
- }
-
static class Intrinsics
{
+
private delegate bool Emitter(EmitIntrinsicContext eic);
+
private struct IntrinsicKey : IEquatable
{
private readonly string className;
diff --git a/src/IKVM.Runtime/profiler.cs b/src/IKVM.Runtime/profiler.cs
index 45cdfd0279..5c8115895d 100644
--- a/src/IKVM.Runtime/profiler.cs
+++ b/src/IKVM.Runtime/profiler.cs
@@ -25,97 +25,103 @@ Jeroen Frijters
using System.Collections.Generic;
using System.Diagnostics;
-sealed class Profiler
+namespace IKVM.Runtime
{
- private static Profiler instance = new Profiler();
- private static Dictionary counters = new Dictionary();
- [ThreadStatic]
- private static Stack stack;
- private sealed class Entry
+ sealed class Profiler
{
- internal long Time;
- internal long Count;
- }
- ~Profiler()
- {
- // get rid off the warning that "instance" is unused
- instance.Equals(null);
- Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "Event", "Count", "Time (ms)");
- Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "-----", "-----", "---------");
- long totalTime = 0;
- foreach(KeyValuePair e in counters)
+ private static Profiler instance = new Profiler();
+ private static Dictionary counters = new Dictionary();
+ [ThreadStatic]
+ private static Stack stack;
+
+ private sealed class Entry
{
- Entry entry = e.Value;
- if(entry.Time == 0)
- {
- Console.Error.WriteLine("{0,-40}{1,10}", e.Key, entry.Count);
- }
- else
- {
- totalTime += entry.Time / 10000;
- Console.Error.WriteLine("{0,-40}{1,10}{2,12}", e.Key, entry.Count, entry.Time / 10000);
- }
+ internal long Time;
+ internal long Count;
}
- Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "", "", "---------");
- Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "", "", totalTime);
- }
- [Conditional("PROFILE")]
- internal static void Enter(string name)
- {
- long ticks = DateTime.Now.Ticks;
- lock(counters)
+ ~Profiler()
{
- if(stack == null)
+ // get rid off the warning that "instance" is unused
+ instance.Equals(null);
+ Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "Event", "Count", "Time (ms)");
+ Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "-----", "-----", "---------");
+ long totalTime = 0;
+ foreach (KeyValuePair e in counters)
{
- stack = new Stack();
+ Entry entry = e.Value;
+ if (entry.Time == 0)
+ {
+ Console.Error.WriteLine("{0,-40}{1,10}", e.Key, entry.Count);
+ }
+ else
+ {
+ totalTime += entry.Time / 10000;
+ Console.Error.WriteLine("{0,-40}{1,10}{2,12}", e.Key, entry.Count, entry.Time / 10000);
+ }
}
- if(stack.Count > 0)
- {
- stack.Peek().Time += ticks;
- }
- Entry e;
- if(!counters.TryGetValue(name, out e))
+ Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "", "", "---------");
+ Console.Error.WriteLine("{0,-40}{1,10}{2,12}", "", "", totalTime);
+ }
+
+ [Conditional("PROFILE")]
+ internal static void Enter(string name)
+ {
+ long ticks = DateTime.Now.Ticks;
+ lock (counters)
{
- e = new Entry();
- counters[name] = e;
+ if (stack == null)
+ {
+ stack = new Stack();
+ }
+ if (stack.Count > 0)
+ {
+ stack.Peek().Time += ticks;
+ }
+ Entry e;
+ if (!counters.TryGetValue(name, out e))
+ {
+ e = new Entry();
+ counters[name] = e;
+ }
+ e.Count++;
+ e.Time -= ticks;
+ stack.Push(e);
}
- e.Count++;
- e.Time -= ticks;
- stack.Push(e);
}
- }
- [Conditional("PROFILE")]
- internal static void Leave(string name)
- {
- long ticks = DateTime.Now.Ticks;
- stack.Pop();
- lock(counters)
+ [Conditional("PROFILE")]
+ internal static void Leave(string name)
{
- Entry e = counters[name];
- e.Time += ticks;
- if(stack.Count > 0)
+ long ticks = DateTime.Now.Ticks;
+ stack.Pop();
+ lock (counters)
{
- ((Entry)stack.Peek()).Time -= ticks;
+ Entry e = counters[name];
+ e.Time += ticks;
+ if (stack.Count > 0)
+ {
+ ((Entry)stack.Peek()).Time -= ticks;
+ }
}
}
- }
- [Conditional("PROFILE")]
- internal static void Count(string name)
- {
- lock(counters)
+ [Conditional("PROFILE")]
+ internal static void Count(string name)
{
- Entry e;
- if(!counters.TryGetValue(name, out e))
+ lock (counters)
{
- e = new Entry();
- counters[name] = e;
+ Entry e;
+ if (!counters.TryGetValue(name, out e))
+ {
+ e = new Entry();
+ counters[name] = e;
+ }
+ e.Count++;
}
- e.Count++;
}
}
+
}
diff --git a/src/IKVM.Runtime/tracer.cs b/src/IKVM.Runtime/tracer.cs
index f55baffabe..8d8270f231 100644
--- a/src/IKVM.Runtime/tracer.cs
+++ b/src/IKVM.Runtime/tracer.cs
@@ -28,7 +28,7 @@ Jeroen Frijters
using System.Text.RegularExpressions;
using System.Threading;
-namespace IKVM.Internal
+namespace IKVM.Runtime
{
public static class Tracer
diff --git a/src/IKVM.Runtime/verifier.cs b/src/IKVM.Runtime/verifier.cs
deleted file mode 100644
index c60a838995..0000000000
--- a/src/IKVM.Runtime/verifier.cs
+++ /dev/null
@@ -1,4138 +0,0 @@
-/*
- Copyright (C) 2002-2014 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-using IKVM.ByteCode;
-using IKVM.Internal;
-
-#if IMPORTER
-using IKVM.Tools.Importer;
-#endif
-
-using ExceptionTableEntry = IKVM.Internal.ClassFile.Method.ExceptionTableEntry;
-using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
-
-sealed class InstructionState
-{
-
- private struct LocalStoreSites
- {
-
- private int[] data;
- private int count;
- private bool shared;
-
- internal LocalStoreSites Copy()
- {
- LocalStoreSites n = new LocalStoreSites();
- n.data = data;
- n.count = count;
- n.shared = true;
- return n;
- }
-
- internal static LocalStoreSites Alloc()
- {
- LocalStoreSites n = new LocalStoreSites();
- n.data = new int[4];
- return n;
- }
-
- internal void Add(int store)
- {
- for (int i = 0; i < count; i++)
- {
- if (data[i] == store)
- {
- return;
- }
- }
- if (count == data.Length)
- {
- int[] newarray = new int[data.Length * 2];
- Buffer.BlockCopy(data, 0, newarray, 0, data.Length * 4);
- data = newarray;
- shared = false;
- }
- if (shared)
- {
- shared = false;
- data = (int[])data.Clone();
- }
- data[count++] = store;
- }
-
- internal int this[int index]
- {
- get
- {
- return data[index];
- }
- }
-
- internal int Count
- {
- get
- {
- return count;
- }
- }
-
- internal static void MarkShared(LocalStoreSites[] localStoreSites)
- {
- for (int i = 0; i < localStoreSites.Length; i++)
- {
- localStoreSites[i].shared = true;
- }
- }
- }
-
- TypeWrapper[] stack;
- int stackSize;
- int stackEnd;
- TypeWrapper[] locals;
- bool unitializedThis;
- internal bool changed = true;
-
- private enum ShareFlags : byte
- {
- None = 0,
- Stack = 1,
- Locals = 2,
- All = Stack | Locals
- }
- private ShareFlags flags;
-
- private InstructionState(TypeWrapper[] stack, int stackSize, int stackEnd, TypeWrapper[] locals, bool unitializedThis)
- {
- this.flags = ShareFlags.All;
- this.stack = stack;
- this.stackSize = stackSize;
- this.stackEnd = stackEnd;
- this.locals = locals;
- this.unitializedThis = unitializedThis;
- }
-
- internal InstructionState(int maxLocals, int maxStack)
- {
- this.flags = ShareFlags.None;
- this.stack = new TypeWrapper[maxStack];
- this.stackEnd = maxStack;
- this.locals = new TypeWrapper[maxLocals];
- }
-
- internal InstructionState Copy()
- {
- return new InstructionState(stack, stackSize, stackEnd, locals, unitializedThis);
- }
-
- internal void CopyTo(InstructionState target)
- {
- target.flags = ShareFlags.All;
- target.stack = stack;
- target.stackSize = stackSize;
- target.stackEnd = stackEnd;
- target.locals = locals;
- target.unitializedThis = unitializedThis;
- target.changed = true;
- }
-
- internal InstructionState CopyLocals()
- {
- InstructionState copy = new InstructionState(new TypeWrapper[stack.Length], 0, stack.Length, locals, unitializedThis);
- copy.flags &= ~ShareFlags.Stack;
- return copy;
- }
-
- public static InstructionState operator +(InstructionState s1, InstructionState s2)
- {
- if (s1 == null)
- {
- return s2.Copy();
- }
- if (s1.stackSize != s2.stackSize || s1.stackEnd != s2.stackEnd)
- {
- throw new VerifyError(string.Format("Inconsistent stack height: {0} != {1}",
- s1.stackSize + s1.stack.Length - s1.stackEnd,
- s2.stackSize + s2.stack.Length - s2.stackEnd));
- }
- InstructionState s = s1.Copy();
- s.changed = s1.changed;
- for (int i = 0; i < s.stackSize; i++)
- {
- TypeWrapper type = s.stack[i];
- TypeWrapper type2 = s2.stack[i];
- if (type == type2)
- {
- // perfect match, nothing to do
- }
- else if ((type == VerifierTypeWrapper.ExtendedDouble && type2 == PrimitiveTypeWrapper.DOUBLE)
- || (type2 == VerifierTypeWrapper.ExtendedDouble && type == PrimitiveTypeWrapper.DOUBLE))
- {
- if (type != VerifierTypeWrapper.ExtendedDouble)
- {
- s.StackCopyOnWrite();
- s.stack[i] = VerifierTypeWrapper.ExtendedDouble;
- s.changed = true;
- }
- }
- else if ((type == VerifierTypeWrapper.ExtendedFloat && type2 == PrimitiveTypeWrapper.FLOAT)
- || (type2 == VerifierTypeWrapper.ExtendedFloat && type == PrimitiveTypeWrapper.FLOAT))
- {
- if (type != VerifierTypeWrapper.ExtendedFloat)
- {
- s.StackCopyOnWrite();
- s.stack[i] = VerifierTypeWrapper.ExtendedFloat;
- s.changed = true;
- }
- }
- else if (!type.IsPrimitive)
- {
- TypeWrapper baseType = InstructionState.FindCommonBaseType(type, type2);
- if (baseType == VerifierTypeWrapper.Invalid)
- {
- throw new VerifyError(string.Format("cannot merge {0} and {1}", type.Name, type2.Name));
- }
- if (type != baseType)
- {
- s.StackCopyOnWrite();
- s.stack[i] = baseType;
- s.changed = true;
- }
- }
- else
- {
- throw new VerifyError(string.Format("cannot merge {0} and {1}", type.Name, type2.Name));
- }
- }
- for (int i = 0; i < s.locals.Length; i++)
- {
- TypeWrapper type = s.locals[i];
- TypeWrapper type2 = s2.locals[i];
- TypeWrapper baseType = InstructionState.FindCommonBaseType(type, type2);
- if (type != baseType)
- {
- s.LocalsCopyOnWrite();
- s.locals[i] = baseType;
- s.changed = true;
- }
- }
- if (!s.unitializedThis && s2.unitializedThis)
- {
- s.unitializedThis = true;
- s.changed = true;
- }
- return s;
- }
-
- private static LocalStoreSites MergeStoreSites(LocalStoreSites h1, LocalStoreSites h2)
- {
- if (h1.Count == 0)
- {
- return h2.Copy();
- }
- if (h2.Count == 0)
- {
- return h1.Copy();
- }
- LocalStoreSites h = h1.Copy();
- for (int i = 0; i < h2.Count; i++)
- {
- h.Add(h2[i]);
- }
- return h;
- }
-
- internal void SetUnitializedThis(bool state)
- {
- unitializedThis = state;
- }
-
- internal void CheckUninitializedThis()
- {
- if (unitializedThis)
- {
- throw new VerifyError("Base class constructor wasn't called");
- }
- }
-
- internal static TypeWrapper FindCommonBaseType(TypeWrapper type1, TypeWrapper type2)
- {
- if (type1 == type2)
- {
- return type1;
- }
- if (type1 == VerifierTypeWrapper.Null)
- {
- return type2;
- }
- if (type2 == VerifierTypeWrapper.Null)
- {
- return type1;
- }
- if (type1 == VerifierTypeWrapper.Invalid || type2 == VerifierTypeWrapper.Invalid)
- {
- return VerifierTypeWrapper.Invalid;
- }
- if (VerifierTypeWrapper.IsFaultBlockException(type1))
- {
- VerifierTypeWrapper.ClearFaultBlockException(type1);
- return FindCommonBaseType(CoreClasses.java.lang.Throwable.Wrapper, type2);
- }
- if (VerifierTypeWrapper.IsFaultBlockException(type2))
- {
- VerifierTypeWrapper.ClearFaultBlockException(type2);
- return FindCommonBaseType(type1, CoreClasses.java.lang.Throwable.Wrapper);
- }
- if (type1.IsPrimitive || type2.IsPrimitive)
- {
- return VerifierTypeWrapper.Invalid;
- }
- if (type1 == VerifierTypeWrapper.UninitializedThis || type2 == VerifierTypeWrapper.UninitializedThis)
- {
- return VerifierTypeWrapper.Invalid;
- }
- if (VerifierTypeWrapper.IsNew(type1) || VerifierTypeWrapper.IsNew(type2))
- {
- return VerifierTypeWrapper.Invalid;
- }
- if (VerifierTypeWrapper.IsThis(type1))
- {
- type1 = ((VerifierTypeWrapper)type1).UnderlyingType;
- }
- if (VerifierTypeWrapper.IsThis(type2))
- {
- type2 = ((VerifierTypeWrapper)type2).UnderlyingType;
- }
- if (type1.IsUnloadable || type2.IsUnloadable)
- {
- return VerifierTypeWrapper.Unloadable;
- }
- if (type1.ArrayRank > 0 && type2.ArrayRank > 0)
- {
- int rank = 1;
- int rank1 = type1.ArrayRank - 1;
- int rank2 = type2.ArrayRank - 1;
- TypeWrapper elem1 = type1.ElementTypeWrapper;
- TypeWrapper elem2 = type2.ElementTypeWrapper;
- while (rank1 != 0 && rank2 != 0)
- {
- elem1 = elem1.ElementTypeWrapper;
- elem2 = elem2.ElementTypeWrapper;
- rank++;
- rank1--;
- rank2--;
- }
- // NOTE arrays of value types have special merging semantics!
- // NOTE we don't have to test for the case where the element types are the same, because that
- // is only relevant if the ranks are the same, but if that is the case the types are completely
- // identical, in which case the identity test at the top of this method already returned.
- TypeWrapper baseType;
- if (elem1.IsPrimitive || elem2.IsPrimitive || elem1.IsNonPrimitiveValueType || elem2.IsNonPrimitiveValueType)
- {
- baseType = CoreClasses.java.lang.Object.Wrapper;
- rank--;
- if (rank == 0)
- {
- return baseType;
- }
- }
- else
- {
- baseType = FindCommonBaseTypeHelper(elem1, elem2);
- }
- return baseType.MakeArrayType(rank);
- }
- return FindCommonBaseTypeHelper(type1, type2);
- }
-
- private static TypeWrapper FindCommonBaseTypeHelper(TypeWrapper t1, TypeWrapper t2)
- {
- if (t1 == t2)
- {
- return t1;
- }
- if (t1.IsInterface || t2.IsInterface)
- {
- // NOTE according to a paper by Alessandro Coglio & Allen Goldberg titled
- // "Type Safety in the JVM: Some Problems in Java 2 SDK 1.2 and Proposed Solutions"
- // the common base of two interfaces is java.lang.Object, and there is special
- // treatment for java.lang.Object types that allow it to be assigned to any interface
- // type, the JVM's typesafety then depends on the invokeinterface instruction to make
- // sure that the reference actually implements the interface.
- // NOTE the ECMA CLI spec also specifies this interface merging algorithm, so we can't
- // really do anything more clever than this.
- return CoreClasses.java.lang.Object.Wrapper;
- }
- Stack st1 = new Stack();
- Stack st2 = new Stack();
- while (t1 != null)
- {
- st1.Push(t1);
- t1 = t1.BaseTypeWrapper;
- }
- while (t2 != null)
- {
- st2.Push(t2);
- t2 = t2.BaseTypeWrapper;
- }
- if (HasMissingBaseType(st1) || HasMissingBaseType(st2))
- {
- return VerifierTypeWrapper.Unloadable;
- }
- TypeWrapper type = CoreClasses.java.lang.Object.Wrapper;
- for (; ; )
- {
- t1 = st1.Count > 0 ? st1.Pop() : null;
- t2 = st2.Count > 0 ? st2.Pop() : null;
- if (t1 != t2)
- {
- return type;
- }
- type = t1;
- }
- }
-
- private static bool HasMissingBaseType(Stack st)
- {
-#if IMPORTER
- if (st.Pop().IsUnloadable)
- {
- // we have a missing type in base class hierarchy
- StaticCompiler.IssueMissingTypeMessage(st.Pop().TypeAsBaseType.BaseType);
- return true;
- }
-#endif
- return false;
- }
-
- private void SetLocal1(int index, TypeWrapper type)
- {
- try
- {
- LocalsCopyOnWrite();
- if (index > 0 && locals[index - 1] != VerifierTypeWrapper.Invalid && locals[index - 1].IsWidePrimitive)
- {
- locals[index - 1] = VerifierTypeWrapper.Invalid;
- }
- locals[index] = type;
- }
- catch (IndexOutOfRangeException)
- {
- throw new VerifyError("Illegal local variable number");
- }
- }
-
- private void SetLocal2(int index, TypeWrapper type)
- {
- try
- {
- LocalsCopyOnWrite();
- if (index > 0 && locals[index - 1] != VerifierTypeWrapper.Invalid && locals[index - 1].IsWidePrimitive)
- {
- locals[index - 1] = VerifierTypeWrapper.Invalid;
- }
- locals[index] = type;
- locals[index + 1] = VerifierTypeWrapper.Invalid;
- }
- catch (IndexOutOfRangeException)
- {
- throw new VerifyError("Illegal local variable number");
- }
- }
-
- internal void GetLocalInt(int index)
- {
- if (GetLocalType(index) != PrimitiveTypeWrapper.INT)
- {
- throw new VerifyError("Invalid local type");
- }
- }
-
- internal void SetLocalInt(int index, int instructionIndex)
- {
- SetLocal1(index, PrimitiveTypeWrapper.INT);
- }
-
- internal void GetLocalLong(int index)
- {
- if (GetLocalType(index) != PrimitiveTypeWrapper.LONG)
- {
- throw new VerifyError("incorrect local type, not long");
- }
- }
-
- internal void SetLocalLong(int index, int instructionIndex)
- {
- SetLocal2(index, PrimitiveTypeWrapper.LONG);
- }
-
- internal void GetLocalFloat(int index)
- {
- if (GetLocalType(index) != PrimitiveTypeWrapper.FLOAT)
- {
- throw new VerifyError("incorrect local type, not float");
- }
- }
-
- internal void SetLocalFloat(int index, int instructionIndex)
- {
- SetLocal1(index, PrimitiveTypeWrapper.FLOAT);
- }
-
- internal void GetLocalDouble(int index)
- {
- if (GetLocalType(index) != PrimitiveTypeWrapper.DOUBLE)
- {
- throw new VerifyError("incorrect local type, not double");
- }
- }
-
- internal void SetLocalDouble(int index, int instructionIndex)
- {
- SetLocal2(index, PrimitiveTypeWrapper.DOUBLE);
- }
-
- internal TypeWrapper GetLocalType(int index)
- {
- try
- {
- return locals[index];
- }
- catch (IndexOutOfRangeException)
- {
- throw new VerifyError("Illegal local variable number");
- }
- }
-
- // this is used by the compiler (indirectly, through MethodAnalyzer.GetLocalTypeWrapper),
- // we've already verified the code so we know we won't run outside the array boundary,
- // and we don't need to record the fact that we're reading the local.
- internal TypeWrapper GetLocalTypeEx(int index)
- {
- return locals[index];
- }
-
- internal void SetLocalType(int index, TypeWrapper type, int instructionIndex)
- {
- if (type.IsWidePrimitive)
- {
- SetLocal2(index, type);
- }
- else
- {
- SetLocal1(index, type);
- }
- }
-
- internal void PushType(TypeWrapper type)
- {
- if (type.IsIntOnStackPrimitive)
- {
- type = PrimitiveTypeWrapper.INT;
- }
- PushHelper(type);
- }
-
- internal void PushInt()
- {
- PushHelper(PrimitiveTypeWrapper.INT);
- }
-
- internal void PushLong()
- {
- PushHelper(PrimitiveTypeWrapper.LONG);
- }
-
- internal void PushFloat()
- {
- PushHelper(PrimitiveTypeWrapper.FLOAT);
- }
-
- internal void PushExtendedFloat()
- {
- PushHelper(VerifierTypeWrapper.ExtendedFloat);
- }
-
- internal void PushDouble()
- {
- PushHelper(PrimitiveTypeWrapper.DOUBLE);
- }
-
- internal void PushExtendedDouble()
- {
- PushHelper(VerifierTypeWrapper.ExtendedDouble);
- }
-
- internal void PopInt()
- {
- PopIntImpl(PopAnyType());
- }
-
- internal static void PopIntImpl(TypeWrapper type)
- {
- if (type != PrimitiveTypeWrapper.INT)
- {
- throw new VerifyError("Int expected on stack");
- }
- }
-
- internal bool PopFloat()
- {
- TypeWrapper tw = PopAnyType();
- PopFloatImpl(tw);
- return tw == VerifierTypeWrapper.ExtendedFloat;
- }
-
- internal static void PopFloatImpl(TypeWrapper tw)
- {
- if (tw != PrimitiveTypeWrapper.FLOAT && tw != VerifierTypeWrapper.ExtendedFloat)
- {
- throw new VerifyError("Float expected on stack");
- }
- }
-
- internal bool PopDouble()
- {
- TypeWrapper tw = PopAnyType();
- PopDoubleImpl(tw);
- return tw == VerifierTypeWrapper.ExtendedDouble;
- }
-
- internal static void PopDoubleImpl(TypeWrapper tw)
- {
- if (tw != PrimitiveTypeWrapper.DOUBLE && tw != VerifierTypeWrapper.ExtendedDouble)
- {
- throw new VerifyError("Double expected on stack");
- }
- }
-
- internal void PopLong()
- {
- PopLongImpl(PopAnyType());
- }
-
- internal static void PopLongImpl(TypeWrapper tw)
- {
- if (tw != PrimitiveTypeWrapper.LONG)
- {
- throw new VerifyError("Long expected on stack");
- }
- }
-
- internal TypeWrapper PopArrayType()
- {
- return PopArrayTypeImpl(PopAnyType());
- }
-
- internal static TypeWrapper PopArrayTypeImpl(TypeWrapper type)
- {
- if (!VerifierTypeWrapper.IsNullOrUnloadable(type) && type.ArrayRank == 0)
- {
- throw new VerifyError("Array reference expected on stack");
- }
- return type;
- }
-
- // null or an initialized object reference
- internal TypeWrapper PopObjectType()
- {
- return PopObjectTypeImpl(PopType());
- }
-
- internal static TypeWrapper PopObjectTypeImpl(TypeWrapper type)
- {
- if (type.IsPrimitive || VerifierTypeWrapper.IsNew(type) || type == VerifierTypeWrapper.UninitializedThis)
- {
- throw new VerifyError("Expected object reference on stack");
- }
- return type;
- }
-
- // null or an initialized object reference derived from baseType (or baseType)
- internal TypeWrapper PopObjectType(TypeWrapper baseType)
- {
- return PopObjectTypeImpl(baseType, PopObjectType());
- }
-
- internal static TypeWrapper PopObjectTypeImpl(TypeWrapper baseType, TypeWrapper type)
- {
- // HACK because of the way interfaces references works, if baseType
- // is an interface or array of interfaces, any reference will be accepted
- if (!baseType.IsUnloadable && !baseType.IsInterfaceOrInterfaceArray && !(type.IsUnloadable || type.IsAssignableTo(baseType)))
- {
- throw new VerifyError("Unexpected type " + type.Name + " where " + baseType.Name + " was expected");
- }
- return type;
- }
-
- internal TypeWrapper PeekType()
- {
- if (stackSize == 0)
- {
- throw new VerifyError("Unable to pop operand off an empty stack");
- }
- return stack[stackSize - 1];
- }
-
- internal void MultiPopAnyType(int count)
- {
- while (count-- != 0)
- {
- PopAnyType();
- }
- }
-
- internal TypeWrapper PopFaultBlockException()
- {
- return stack[--stackSize];
- }
-
- internal TypeWrapper PopAnyType()
- {
- if (stackSize == 0)
- {
- throw new VerifyError("Unable to pop operand off an empty stack");
- }
- TypeWrapper type = stack[--stackSize];
- if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
- {
- stackEnd++;
- }
- if (VerifierTypeWrapper.IsThis(type))
- {
- type = ((VerifierTypeWrapper)type).UnderlyingType;
- }
- if (VerifierTypeWrapper.IsFaultBlockException(type))
- {
- VerifierTypeWrapper.ClearFaultBlockException(type);
- type = CoreClasses.java.lang.Throwable.Wrapper;
- }
- return type;
- }
-
- // NOTE this can *not* be used to pop double or long
- internal TypeWrapper PopType()
- {
- return PopTypeImpl(PopAnyType());
- }
-
- internal static TypeWrapper PopTypeImpl(TypeWrapper type)
- {
- if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
- {
- throw new VerifyError("Attempt to split long or double on the stack");
- }
- return type;
- }
-
- // this will accept null, a primitive type of the specified type or an initialized reference of the
- // specified type or derived from it
- // NOTE this can also be used to pop double or long
- internal TypeWrapper PopType(TypeWrapper baseType)
- {
- return PopTypeImpl(baseType, PopAnyType());
- }
-
- internal static TypeWrapper PopTypeImpl(TypeWrapper baseType, TypeWrapper type)
- {
- if (baseType.IsIntOnStackPrimitive)
- {
- baseType = PrimitiveTypeWrapper.INT;
- }
- if (VerifierTypeWrapper.IsNew(type) || type == VerifierTypeWrapper.UninitializedThis)
- {
- throw new VerifyError("Expecting to find object/array on stack");
- }
- if (type == baseType)
- {
- return type;
- }
- else if (type == VerifierTypeWrapper.ExtendedDouble && baseType == PrimitiveTypeWrapper.DOUBLE)
- {
- return type;
- }
- else if (type == VerifierTypeWrapper.ExtendedFloat && baseType == PrimitiveTypeWrapper.FLOAT)
- {
- return type;
- }
- else if (type.IsPrimitive || baseType.IsPrimitive)
- {
- // throw at the end of the method
- }
- else if (baseType == CoreClasses.java.lang.Object.Wrapper)
- {
- return type;
- }
- else if (type.IsUnloadable || baseType.IsUnloadable)
- {
- return type;
- }
- else if (baseType.IsInterfaceOrInterfaceArray)
- {
- // because of the way interfaces references works, if baseType
- // is an interface or array of interfaces, any reference will be accepted
- return type;
- }
- else if (type.IsAssignableTo(baseType))
- {
- return type;
- }
- else if (HasMissingBaseType(type) || HasMissingBaseType(baseType))
- {
- return type;
- }
- throw new VerifyError("Unexpected type " + type.Name + " where " + baseType.Name + " was expected");
- }
-
- private static bool HasMissingBaseType(TypeWrapper tw)
- {
-#if IMPORTER
- for (TypeWrapper baseTypeWrapper; (baseTypeWrapper = tw.BaseTypeWrapper) != null; tw = baseTypeWrapper)
- {
- if (baseTypeWrapper.IsUnloadable)
- {
- StaticCompiler.IssueMissingTypeMessage(tw.TypeAsBaseType.BaseType);
- return true;
- }
- }
-#endif
- return false;
- }
-
- internal int GetStackHeight()
- {
- return stackSize;
- }
-
- internal TypeWrapper GetStackSlot(int pos)
- {
- TypeWrapper tw = stack[stackSize - 1 - pos];
- if (tw == VerifierTypeWrapper.ExtendedDouble)
- {
- tw = PrimitiveTypeWrapper.DOUBLE;
- }
- else if (tw == VerifierTypeWrapper.ExtendedFloat)
- {
- tw = PrimitiveTypeWrapper.FLOAT;
- }
- return tw;
- }
-
- internal TypeWrapper GetStackSlotEx(int pos)
- {
- return stack[stackSize - 1 - pos];
- }
-
- internal TypeWrapper GetStackByIndex(int index)
- {
- return stack[index];
- }
-
- private void PushHelper(TypeWrapper type)
- {
- if (type.IsWidePrimitive || type == VerifierTypeWrapper.ExtendedDouble)
- {
- stackEnd--;
- }
- if (stackSize >= stackEnd)
- {
- throw new VerifyError("Stack overflow");
- }
- StackCopyOnWrite();
- stack[stackSize++] = type;
- }
-
- internal void MarkInitialized(TypeWrapper type, TypeWrapper initType, int instructionIndex)
- {
- System.Diagnostics.Debug.Assert(type != null && initType != null);
-
- for (int i = 0; i < locals.Length; i++)
- {
- if (locals[i] == type)
- {
- LocalsCopyOnWrite();
- locals[i] = initType;
- }
- }
- for (int i = 0; i < stackSize; i++)
- {
- if (stack[i] == type)
- {
- StackCopyOnWrite();
- stack[i] = initType;
- }
- }
- }
-
- private void StackCopyOnWrite()
- {
- if ((flags & ShareFlags.Stack) != 0)
- {
- flags &= ~ShareFlags.Stack;
- stack = (TypeWrapper[])stack.Clone();
- }
- }
-
- private void LocalsCopyOnWrite()
- {
- if ((flags & ShareFlags.Locals) != 0)
- {
- flags &= ~ShareFlags.Locals;
- locals = (TypeWrapper[])locals.Clone();
- }
- }
-
- internal void DumpLocals()
- {
- Console.Write("// ");
- string sep = "";
- for (int i = 0; i < locals.Length; i++)
- {
- Console.Write(sep);
- Console.Write(locals[i]);
- sep = ", ";
- }
- Console.WriteLine();
- }
-
- internal void DumpStack()
- {
- Console.Write("// ");
- string sep = "";
- for (int i = 0; i < stackSize; i++)
- {
- Console.Write(sep);
- Console.Write(stack[i]);
- sep = ", ";
- }
- Console.WriteLine();
- }
-
- internal void ClearFaultBlockException()
- {
- if (VerifierTypeWrapper.IsFaultBlockException(stack[0]))
- {
- StackCopyOnWrite();
- changed = true;
- stack[0] = CoreClasses.java.lang.Throwable.Wrapper;
- }
- }
-}
-
-struct StackState
-{
- private InstructionState state;
- private int sp;
-
- internal StackState(InstructionState state)
- {
- this.state = state;
- sp = state.GetStackHeight();
- }
-
- internal TypeWrapper PeekType()
- {
- if (sp == 0)
- {
- throw new VerifyError("Unable to pop operand off an empty stack");
- }
- TypeWrapper type = state.GetStackByIndex(sp - 1);
- if (VerifierTypeWrapper.IsThis(type))
- {
- type = ((VerifierTypeWrapper)type).UnderlyingType;
- }
- return type;
- }
-
- internal TypeWrapper PopAnyType()
- {
- if (sp == 0)
- {
- throw new VerifyError("Unable to pop operand off an empty stack");
- }
- TypeWrapper type = state.GetStackByIndex(--sp);
- if (VerifierTypeWrapper.IsThis(type))
- {
- type = ((VerifierTypeWrapper)type).UnderlyingType;
- }
- if (VerifierTypeWrapper.IsFaultBlockException(type))
- {
- VerifierTypeWrapper.ClearFaultBlockException(type);
- type = CoreClasses.java.lang.Throwable.Wrapper;
- }
- return type;
- }
-
- internal TypeWrapper PopType(TypeWrapper baseType)
- {
- return InstructionState.PopTypeImpl(baseType, PopAnyType());
- }
-
- // NOTE this can *not* be used to pop double or long
- internal TypeWrapper PopType()
- {
- return InstructionState.PopTypeImpl(PopAnyType());
- }
-
- internal void PopInt()
- {
- InstructionState.PopIntImpl(PopAnyType());
- }
-
- internal void PopFloat()
- {
- InstructionState.PopFloatImpl(PopAnyType());
- }
-
- internal void PopDouble()
- {
- InstructionState.PopDoubleImpl(PopAnyType());
- }
-
- internal void PopLong()
- {
- InstructionState.PopLongImpl(PopAnyType());
- }
-
- internal TypeWrapper PopArrayType()
- {
- return InstructionState.PopArrayTypeImpl(PopAnyType());
- }
-
- // either null or an initialized object reference
- internal TypeWrapper PopObjectType()
- {
- return InstructionState.PopObjectTypeImpl(PopAnyType());
- }
-
- // null or an initialized object reference derived from baseType (or baseType)
- internal TypeWrapper PopObjectType(TypeWrapper baseType)
- {
- return InstructionState.PopObjectTypeImpl(baseType, PopObjectType());
- }
-}
-
-sealed class ExceptionSorter : IComparer
-{
- public int Compare(ExceptionTableEntry e1, ExceptionTableEntry e2)
- {
- if (e1.startIndex < e2.startIndex)
- {
- return -1;
- }
- if (e1.startIndex == e2.startIndex)
- {
- if (e1.endIndex == e2.endIndex)
- {
- if (e1.ordinal > e2.ordinal)
- {
- return -1;
- }
- if (e1.ordinal == e2.ordinal)
- {
- return 0;
- }
- return 1;
- }
- if (e1.endIndex > e2.endIndex)
- {
- return -1;
- }
- }
- return 1;
- }
-}
-
-struct UntangledExceptionTable
-{
- private readonly ExceptionTableEntry[] exceptions;
-
- internal UntangledExceptionTable(ExceptionTableEntry[] exceptions)
- {
-#if DEBUG
- for (int i = 0; i < exceptions.Length; i++)
- {
- for (int j = i + 1; j < exceptions.Length; j++)
- {
- // check for partially overlapping try blocks (which is legal for the JVM, but not the CLR)
- if (exceptions[i].startIndex < exceptions[j].startIndex &&
- exceptions[j].startIndex < exceptions[i].endIndex &&
- exceptions[i].endIndex < exceptions[j].endIndex)
- {
- throw new InvalidOperationException("Partially overlapping try blocks is broken");
- }
- // check that we didn't destroy the ordering, when sorting
- if (exceptions[i].startIndex <= exceptions[j].startIndex &&
- exceptions[i].endIndex >= exceptions[j].endIndex &&
- exceptions[i].ordinal < exceptions[j].ordinal)
- {
- throw new InvalidOperationException("Non recursive try blocks is broken");
- }
- }
- }
-#endif
- this.exceptions = exceptions;
- }
-
- internal ExceptionTableEntry this[int index]
- {
- get { return exceptions[index]; }
- }
-
- internal int Length
- {
- get { return exceptions.Length; }
- }
-
- internal void SetFinally(int index)
- {
- exceptions[index] = new ExceptionTableEntry(exceptions[index].startIndex, exceptions[index].endIndex, exceptions[index].handlerIndex, exceptions[index].catch_type, exceptions[index].ordinal, true);
- }
-}
-
-struct CodeInfo
-{
- private readonly InstructionState[] state;
-
- internal CodeInfo(InstructionState[] state)
- {
- this.state = state;
- }
-
- internal bool HasState(int index)
- {
- return state[index] != null;
- }
-
- internal int GetStackHeight(int index)
- {
- return state[index].GetStackHeight();
- }
-
- internal TypeWrapper GetStackTypeWrapper(int index, int pos)
- {
- TypeWrapper type = state[index].GetStackSlot(pos);
- if (VerifierTypeWrapper.IsThis(type))
- {
- type = ((VerifierTypeWrapper)type).UnderlyingType;
- }
- return type;
- }
-
- internal TypeWrapper GetRawStackTypeWrapper(int index, int pos)
- {
- return state[index].GetStackSlot(pos);
- }
-
- internal bool IsStackTypeExtendedDouble(int index, int pos)
- {
- return state[index].GetStackSlotEx(pos) == VerifierTypeWrapper.ExtendedDouble;
- }
-
- internal TypeWrapper GetLocalTypeWrapper(int index, int local)
- {
- return state[index].GetLocalTypeEx(local);
- }
-}
-
-sealed class MethodAnalyzer
-{
- private readonly static TypeWrapper ByteArrayType;
- private readonly static TypeWrapper BooleanArrayType;
- private readonly static TypeWrapper ShortArrayType;
- private readonly static TypeWrapper CharArrayType;
- private readonly static TypeWrapper IntArrayType;
- private readonly static TypeWrapper FloatArrayType;
- private readonly static TypeWrapper DoubleArrayType;
- private readonly static TypeWrapper LongArrayType;
- private readonly static TypeWrapper java_lang_ThreadDeath;
- private readonly TypeWrapper host; // used to by Unsafe.defineAnonymousClass() to provide access to private members of the host
- private readonly TypeWrapper wrapper;
- private readonly MethodWrapper mw;
- private readonly ClassFile classFile;
- private readonly ClassFile.Method method;
- private readonly ClassLoaderWrapper classLoader;
- private readonly TypeWrapper thisType;
- private readonly InstructionState[] state;
- private List errorMessages;
- private readonly Dictionary newTypes = new Dictionary();
- private readonly Dictionary faultTypes = new Dictionary();
-
- static MethodAnalyzer()
- {
- ByteArrayType = PrimitiveTypeWrapper.BYTE.MakeArrayType(1);
- BooleanArrayType = PrimitiveTypeWrapper.BOOLEAN.MakeArrayType(1);
- ShortArrayType = PrimitiveTypeWrapper.SHORT.MakeArrayType(1);
- CharArrayType = PrimitiveTypeWrapper.CHAR.MakeArrayType(1);
- IntArrayType = PrimitiveTypeWrapper.INT.MakeArrayType(1);
- FloatArrayType = PrimitiveTypeWrapper.FLOAT.MakeArrayType(1);
- DoubleArrayType = PrimitiveTypeWrapper.DOUBLE.MakeArrayType(1);
- LongArrayType = PrimitiveTypeWrapper.LONG.MakeArrayType(1);
- java_lang_ThreadDeath = ClassLoaderWrapper.LoadClassCritical("java.lang.ThreadDeath");
- }
-
- internal MethodAnalyzer(TypeWrapper host, TypeWrapper wrapper, MethodWrapper mw, ClassFile classFile, ClassFile.Method method, ClassLoaderWrapper classLoader)
- {
- if (method.VerifyError != null)
- {
- throw new VerifyError(method.VerifyError);
- }
-
- this.host = host;
- this.wrapper = wrapper;
- this.mw = mw;
- this.classFile = classFile;
- this.method = method;
- this.classLoader = classLoader;
- state = new InstructionState[method.Instructions.Length];
-
- try
- {
- // ensure that exception blocks and handlers start and end at instruction boundaries
- for (int i = 0; i < method.ExceptionTable.Length; i++)
- {
- int start = method.ExceptionTable[i].startIndex;
- int end = method.ExceptionTable[i].endIndex;
- int handler = method.ExceptionTable[i].handlerIndex;
- if (start >= end || start == -1 || end == -1 || handler <= 0)
- {
- throw new IndexOutOfRangeException();
- }
- }
- }
- catch (IndexOutOfRangeException)
- {
- // TODO figure out if we should throw this during class loading
- throw new ClassFormatError(string.Format("Illegal exception table (class: {0}, method: {1}, signature: {2}", classFile.Name, method.Name, method.Signature));
- }
-
- // start by computing the initial state, the stack is empty and the locals contain the arguments
- state[0] = new InstructionState(method.MaxLocals, method.MaxStack);
- int firstNonArgLocalIndex = 0;
- if (!method.IsStatic)
- {
- thisType = VerifierTypeWrapper.MakeThis(wrapper);
- // this reference. If we're a constructor, the this reference is uninitialized.
- if (method.IsConstructor)
- {
- state[0].SetLocalType(firstNonArgLocalIndex++, VerifierTypeWrapper.UninitializedThis, -1);
- state[0].SetUnitializedThis(true);
- }
- else
- {
- state[0].SetLocalType(firstNonArgLocalIndex++, thisType, -1);
- }
- }
- else
- {
- thisType = null;
- }
- // mw can be null when we're invoked from IsSideEffectFreeStaticInitializer
- TypeWrapper[] argTypeWrappers = mw == null ? TypeWrapper.EmptyArray : mw.GetParameters();
- for (int i = 0; i < argTypeWrappers.Length; i++)
- {
- TypeWrapper type = argTypeWrappers[i];
- if (type.IsIntOnStackPrimitive)
- {
- type = PrimitiveTypeWrapper.INT;
- }
- state[0].SetLocalType(firstNonArgLocalIndex++, type, -1);
- if (type.IsWidePrimitive)
- {
- firstNonArgLocalIndex++;
- }
- }
- AnalyzeTypeFlow();
- VerifyPassTwo();
- PatchLoadConstants();
- }
-
- private void PatchLoadConstants()
- {
- ClassFile.Method.Instruction[] code = method.Instructions;
- for (int i = 0; i < code.Length; i++)
- {
- if (state[i] != null)
- {
- switch (code[i].NormalizedOpCode)
- {
- case NormalizedByteCode.__ldc:
- switch (GetConstantPoolConstantType(code[i].Arg1))
- {
- case ClassFile.ConstantType.Double:
- case ClassFile.ConstantType.Float:
- case ClassFile.ConstantType.Integer:
- case ClassFile.ConstantType.Long:
- case ClassFile.ConstantType.String:
- case ClassFile.ConstantType.LiveObject:
- code[i].PatchOpCode(NormalizedByteCode.__ldc_nothrow);
- break;
- }
- break;
- }
- }
- }
- }
-
- internal CodeInfo GetCodeInfoAndErrors(UntangledExceptionTable exceptions, out List errors)
- {
- CodeInfo codeInfo = new CodeInfo(state);
- OptimizationPass(codeInfo, classFile, method, exceptions, wrapper, classLoader);
- PatchHardErrorsAndDynamicMemberAccess(wrapper, mw);
- errors = errorMessages;
- if (AnalyzePotentialFaultBlocks(codeInfo, method, exceptions))
- {
- AnalyzeTypeFlow();
- }
- ConvertFinallyBlocks(codeInfo, method, exceptions);
- return codeInfo;
- }
-
- private void AnalyzeTypeFlow()
- {
- InstructionState s = new InstructionState(method.MaxLocals, method.MaxStack);
- bool done = false;
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- while (!done)
- {
- done = true;
- for (int i = 0; i < instructions.Length; i++)
- {
- if (state[i] != null && state[i].changed)
- {
- try
- {
- //Console.WriteLine(method.Instructions[i].PC + ": " + method.Instructions[i].OpCode.ToString());
- done = false;
- state[i].changed = false;
- // mark the exception handlers reachable from this instruction
- for (int j = 0; j < method.ExceptionTable.Length; j++)
- {
- if (method.ExceptionTable[j].startIndex <= i && i < method.ExceptionTable[j].endIndex)
- {
- MergeExceptionHandler(j, state[i]);
- }
- }
- state[i].CopyTo(s);
- ClassFile.Method.Instruction instr = instructions[i];
- switch (instr.NormalizedOpCode)
- {
- case NormalizedByteCode.__aload:
- {
- TypeWrapper type = s.GetLocalType(instr.NormalizedArg1);
- if (type == VerifierTypeWrapper.Invalid || type.IsPrimitive)
- {
- throw new VerifyError("Object reference expected");
- }
- s.PushType(type);
- break;
- }
- case NormalizedByteCode.__astore:
- {
- if (VerifierTypeWrapper.IsFaultBlockException(s.PeekType()))
- {
- s.SetLocalType(instr.NormalizedArg1, s.PopFaultBlockException(), i);
- break;
- }
- // NOTE since the reference can be uninitialized, we cannot use PopObjectType
- TypeWrapper type = s.PopType();
- if (type.IsPrimitive)
- {
- throw new VerifyError("Object reference expected");
- }
- s.SetLocalType(instr.NormalizedArg1, type, i);
- break;
- }
- case NormalizedByteCode.__aconst_null:
- s.PushType(VerifierTypeWrapper.Null);
- break;
- case NormalizedByteCode.__aaload:
- {
- s.PopInt();
- TypeWrapper type = s.PopArrayType();
- if (type == VerifierTypeWrapper.Null)
- {
- // if the array is null, we have use null as the element type, because
- // otherwise the rest of the code will not verify correctly
- s.PushType(VerifierTypeWrapper.Null);
- }
- else if (type.IsUnloadable)
- {
- s.PushType(VerifierTypeWrapper.Unloadable);
- }
- else
- {
- type = type.ElementTypeWrapper;
- if (type.IsPrimitive)
- {
- throw new VerifyError("Object array expected");
- }
- s.PushType(type);
- }
- break;
- }
- case NormalizedByteCode.__aastore:
- s.PopObjectType();
- s.PopInt();
- s.PopArrayType();
- // TODO check that elem is assignable to the array
- break;
- case NormalizedByteCode.__baload:
- {
- s.PopInt();
- TypeWrapper type = s.PopArrayType();
- if (!VerifierTypeWrapper.IsNullOrUnloadable(type) &&
- type != ByteArrayType &&
- type != BooleanArrayType)
- {
- throw new VerifyError();
- }
- s.PushInt();
- break;
- }
- case NormalizedByteCode.__bastore:
- {
- s.PopInt();
- s.PopInt();
- TypeWrapper type = s.PopArrayType();
- if (!VerifierTypeWrapper.IsNullOrUnloadable(type) &&
- type != ByteArrayType &&
- type != BooleanArrayType)
- {
- throw new VerifyError();
- }
- break;
- }
- case NormalizedByteCode.__caload:
- s.PopInt();
- s.PopObjectType(CharArrayType);
- s.PushInt();
- break;
- case NormalizedByteCode.__castore:
- s.PopInt();
- s.PopInt();
- s.PopObjectType(CharArrayType);
- break;
- case NormalizedByteCode.__saload:
- s.PopInt();
- s.PopObjectType(ShortArrayType);
- s.PushInt();
- break;
- case NormalizedByteCode.__sastore:
- s.PopInt();
- s.PopInt();
- s.PopObjectType(ShortArrayType);
- break;
- case NormalizedByteCode.__iaload:
- s.PopInt();
- s.PopObjectType(IntArrayType);
- s.PushInt();
- break;
- case NormalizedByteCode.__iastore:
- s.PopInt();
- s.PopInt();
- s.PopObjectType(IntArrayType);
- break;
- case NormalizedByteCode.__laload:
- s.PopInt();
- s.PopObjectType(LongArrayType);
- s.PushLong();
- break;
- case NormalizedByteCode.__lastore:
- s.PopLong();
- s.PopInt();
- s.PopObjectType(LongArrayType);
- break;
- case NormalizedByteCode.__daload:
- s.PopInt();
- s.PopObjectType(DoubleArrayType);
- s.PushDouble();
- break;
- case NormalizedByteCode.__dastore:
- s.PopDouble();
- s.PopInt();
- s.PopObjectType(DoubleArrayType);
- break;
- case NormalizedByteCode.__faload:
- s.PopInt();
- s.PopObjectType(FloatArrayType);
- s.PushFloat();
- break;
- case NormalizedByteCode.__fastore:
- s.PopFloat();
- s.PopInt();
- s.PopObjectType(FloatArrayType);
- break;
- case NormalizedByteCode.__arraylength:
- s.PopArrayType();
- s.PushInt();
- break;
- case NormalizedByteCode.__iconst:
- s.PushInt();
- break;
- case NormalizedByteCode.__if_icmpeq:
- case NormalizedByteCode.__if_icmpne:
- case NormalizedByteCode.__if_icmplt:
- case NormalizedByteCode.__if_icmpge:
- case NormalizedByteCode.__if_icmpgt:
- case NormalizedByteCode.__if_icmple:
- s.PopInt();
- s.PopInt();
- break;
- case NormalizedByteCode.__ifeq:
- case NormalizedByteCode.__ifge:
- case NormalizedByteCode.__ifgt:
- case NormalizedByteCode.__ifle:
- case NormalizedByteCode.__iflt:
- case NormalizedByteCode.__ifne:
- s.PopInt();
- break;
- case NormalizedByteCode.__ifnonnull:
- case NormalizedByteCode.__ifnull:
- // TODO it might be legal to use an unitialized ref here
- s.PopObjectType();
- break;
- case NormalizedByteCode.__if_acmpeq:
- case NormalizedByteCode.__if_acmpne:
- // TODO it might be legal to use an unitialized ref here
- s.PopObjectType();
- s.PopObjectType();
- break;
- case NormalizedByteCode.__getstatic:
- case NormalizedByteCode.__dynamic_getstatic:
- // special support for when we're being called from IsSideEffectFreeStaticInitializer
- if (mw == null)
- {
- switch (GetFieldref(instr.Arg1).Signature[0])
- {
- case 'B':
- case 'Z':
- case 'C':
- case 'S':
- case 'I':
- s.PushInt();
- break;
- case 'F':
- s.PushFloat();
- break;
- case 'D':
- s.PushDouble();
- break;
- case 'J':
- s.PushLong();
- break;
- case 'L':
- case '[':
- throw new VerifyError();
- default:
- throw new InvalidOperationException();
- }
- }
- else
- {
- ClassFile.ConstantPoolItemFieldref cpi = GetFieldref(instr.Arg1);
- if (cpi.GetField() != null && cpi.GetField().FieldTypeWrapper.IsUnloadable)
- {
- s.PushType(cpi.GetField().FieldTypeWrapper);
- }
- else
- {
- s.PushType(cpi.GetFieldType());
- }
- }
- break;
- case NormalizedByteCode.__putstatic:
- case NormalizedByteCode.__dynamic_putstatic:
- // special support for when we're being called from IsSideEffectFreeStaticInitializer
- if (mw == null)
- {
- switch (GetFieldref(instr.Arg1).Signature[0])
- {
- case 'B':
- case 'Z':
- case 'C':
- case 'S':
- case 'I':
- s.PopInt();
- break;
- case 'F':
- s.PopFloat();
- break;
- case 'D':
- s.PopDouble();
- break;
- case 'J':
- s.PopLong();
- break;
- case 'L':
- case '[':
- if (s.PopAnyType() != VerifierTypeWrapper.Null)
- {
- throw new VerifyError();
- }
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- else
- {
- s.PopType(GetFieldref(instr.Arg1).GetFieldType());
- }
- break;
- case NormalizedByteCode.__getfield:
- case NormalizedByteCode.__dynamic_getfield:
- {
- s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
- ClassFile.ConstantPoolItemFieldref cpi = GetFieldref(instr.Arg1);
- if (cpi.GetField() != null && cpi.GetField().FieldTypeWrapper.IsUnloadable)
- {
- s.PushType(cpi.GetField().FieldTypeWrapper);
- }
- else
- {
- s.PushType(cpi.GetFieldType());
- }
- break;
- }
- case NormalizedByteCode.__putfield:
- case NormalizedByteCode.__dynamic_putfield:
- s.PopType(GetFieldref(instr.Arg1).GetFieldType());
- // putfield is allowed to access the uninitialized this
- if (s.PeekType() == VerifierTypeWrapper.UninitializedThis
- && wrapper.IsAssignableTo(GetFieldref(instr.Arg1).GetClassType()))
- {
- s.PopType();
- }
- else
- {
- s.PopObjectType(GetFieldref(instr.Arg1).GetClassType());
- }
- break;
- case NormalizedByteCode.__ldc_nothrow:
- case NormalizedByteCode.__ldc:
- {
- switch (GetConstantPoolConstantType(instr.Arg1))
- {
- case ClassFile.ConstantType.Double:
- s.PushDouble();
- break;
- case ClassFile.ConstantType.Float:
- s.PushFloat();
- break;
- case ClassFile.ConstantType.Integer:
- s.PushInt();
- break;
- case ClassFile.ConstantType.Long:
- s.PushLong();
- break;
- case ClassFile.ConstantType.String:
- s.PushType(CoreClasses.java.lang.String.Wrapper);
- break;
- case ClassFile.ConstantType.LiveObject:
- s.PushType(CoreClasses.java.lang.Object.Wrapper);
- break;
- case ClassFile.ConstantType.Class:
- if (classFile.MajorVersion < 49)
- {
- throw new VerifyError("Illegal type in constant pool");
- }
- s.PushType(CoreClasses.java.lang.Class.Wrapper);
- break;
- case ClassFile.ConstantType.MethodHandle:
- s.PushType(CoreClasses.java.lang.invoke.MethodHandle.Wrapper);
- break;
- case ClassFile.ConstantType.MethodType:
- s.PushType(CoreClasses.java.lang.invoke.MethodType.Wrapper);
- break;
- default:
- // NOTE this is not a VerifyError, because it cannot happen (unless we have
- // a bug in ClassFile.GetConstantPoolConstantType)
- throw new InvalidOperationException();
- }
- break;
- }
- case NormalizedByteCode.__clone_array:
- case NormalizedByteCode.__invokevirtual:
- case NormalizedByteCode.__invokespecial:
- case NormalizedByteCode.__invokeinterface:
- case NormalizedByteCode.__invokestatic:
- case NormalizedByteCode.__dynamic_invokevirtual:
- case NormalizedByteCode.__dynamic_invokespecial:
- case NormalizedByteCode.__dynamic_invokeinterface:
- case NormalizedByteCode.__dynamic_invokestatic:
- case NormalizedByteCode.__privileged_invokevirtual:
- case NormalizedByteCode.__privileged_invokespecial:
- case NormalizedByteCode.__privileged_invokestatic:
- case NormalizedByteCode.__methodhandle_invoke:
- case NormalizedByteCode.__methodhandle_link:
- {
- ClassFile.ConstantPoolItemMI cpi = GetMethodref(instr.Arg1);
- TypeWrapper retType = cpi.GetRetType();
- // HACK to allow the result of Unsafe.getObjectVolatile() (on an array)
- // to be used with Unsafe.putObject() we need to propagate the
- // element type here as the return type (instead of object)
- if (cpi.GetMethod() != null
- && cpi.GetMethod().IsIntrinsic
- && cpi.Class == "sun.misc.Unsafe"
- && cpi.Name == "getObjectVolatile"
- && Intrinsics.IsSupportedArrayTypeForUnsafeOperation(s.GetStackSlot(1)))
- {
- retType = s.GetStackSlot(1).ElementTypeWrapper;
- }
- s.MultiPopAnyType(cpi.GetArgTypes().Length);
- if (instr.NormalizedOpCode != NormalizedByteCode.__invokestatic
- && instr.NormalizedOpCode != NormalizedByteCode.__dynamic_invokestatic)
- {
- TypeWrapper type = s.PopType();
- if (ReferenceEquals(cpi.Name, StringConstants.INIT))
- {
- // after we've invoked the constructor, the uninitialized references
- // are now initialized
- if (type == VerifierTypeWrapper.UninitializedThis)
- {
- if (s.GetLocalTypeEx(0) == type)
- {
- s.SetLocalType(0, thisType, i);
- }
- s.MarkInitialized(type, wrapper, i);
- s.SetUnitializedThis(false);
- }
- else if (VerifierTypeWrapper.IsNew(type))
- {
- s.MarkInitialized(type, ((VerifierTypeWrapper)type).UnderlyingType, i);
- }
- else
- {
- // This is a VerifyError, but it will be caught by our second pass
- }
- }
- }
- if (retType != PrimitiveTypeWrapper.VOID)
- {
- if (cpi.GetMethod() != null && cpi.GetMethod().ReturnType.IsUnloadable)
- {
- s.PushType(cpi.GetMethod().ReturnType);
- }
- else if (retType == PrimitiveTypeWrapper.DOUBLE)
- {
- s.PushExtendedDouble();
- }
- else if (retType == PrimitiveTypeWrapper.FLOAT)
- {
- s.PushExtendedFloat();
- }
- else
- {
- s.PushType(retType);
- }
- }
- break;
- }
- case NormalizedByteCode.__invokedynamic:
- {
- ClassFile.ConstantPoolItemInvokeDynamic cpi = GetInvokeDynamic(instr.Arg1);
- s.MultiPopAnyType(cpi.GetArgTypes().Length);
- TypeWrapper retType = cpi.GetRetType();
- if (retType != PrimitiveTypeWrapper.VOID)
- {
- if (retType == PrimitiveTypeWrapper.DOUBLE)
- {
- s.PushExtendedDouble();
- }
- else if (retType == PrimitiveTypeWrapper.FLOAT)
- {
- s.PushExtendedFloat();
- }
- else
- {
- s.PushType(retType);
- }
- }
- break;
- }
- case NormalizedByteCode.__goto:
- break;
- case NormalizedByteCode.__istore:
- s.PopInt();
- s.SetLocalInt(instr.NormalizedArg1, i);
- break;
- case NormalizedByteCode.__iload:
- s.GetLocalInt(instr.NormalizedArg1);
- s.PushInt();
- break;
- case NormalizedByteCode.__ineg:
- s.PopInt();
- s.PushInt();
- break;
- case NormalizedByteCode.__iadd:
- case NormalizedByteCode.__isub:
- case NormalizedByteCode.__imul:
- case NormalizedByteCode.__idiv:
- case NormalizedByteCode.__irem:
- case NormalizedByteCode.__iand:
- case NormalizedByteCode.__ior:
- case NormalizedByteCode.__ixor:
- case NormalizedByteCode.__ishl:
- case NormalizedByteCode.__ishr:
- case NormalizedByteCode.__iushr:
- s.PopInt();
- s.PopInt();
- s.PushInt();
- break;
- case NormalizedByteCode.__lneg:
- s.PopLong();
- s.PushLong();
- break;
- case NormalizedByteCode.__ladd:
- case NormalizedByteCode.__lsub:
- case NormalizedByteCode.__lmul:
- case NormalizedByteCode.__ldiv:
- case NormalizedByteCode.__lrem:
- case NormalizedByteCode.__land:
- case NormalizedByteCode.__lor:
- case NormalizedByteCode.__lxor:
- s.PopLong();
- s.PopLong();
- s.PushLong();
- break;
- case NormalizedByteCode.__lshl:
- case NormalizedByteCode.__lshr:
- case NormalizedByteCode.__lushr:
- s.PopInt();
- s.PopLong();
- s.PushLong();
- break;
- case NormalizedByteCode.__fneg:
- if (s.PopFloat())
- {
- s.PushExtendedFloat();
- }
- else
- {
- s.PushFloat();
- }
- break;
- case NormalizedByteCode.__fadd:
- case NormalizedByteCode.__fsub:
- case NormalizedByteCode.__fmul:
- case NormalizedByteCode.__fdiv:
- case NormalizedByteCode.__frem:
- s.PopFloat();
- s.PopFloat();
- s.PushExtendedFloat();
- break;
- case NormalizedByteCode.__dneg:
- if (s.PopDouble())
- {
- s.PushExtendedDouble();
- }
- else
- {
- s.PushDouble();
- }
- break;
- case NormalizedByteCode.__dadd:
- case NormalizedByteCode.__dsub:
- case NormalizedByteCode.__dmul:
- case NormalizedByteCode.__ddiv:
- case NormalizedByteCode.__drem:
- s.PopDouble();
- s.PopDouble();
- s.PushExtendedDouble();
- break;
- case NormalizedByteCode.__new:
- {
- // mark the type, so that we can ascertain that it is a "new object"
- TypeWrapper type;
- if (!newTypes.TryGetValue(i, out type))
- {
- type = GetConstantPoolClassType(instr.Arg1);
- if (type.IsArray)
- {
- throw new VerifyError("Illegal use of array type");
- }
- type = VerifierTypeWrapper.MakeNew(type, i);
- newTypes[i] = type;
- }
- s.PushType(type);
- break;
- }
- case NormalizedByteCode.__multianewarray:
- {
- if (instr.Arg2 < 1)
- {
- throw new VerifyError("Illegal dimension argument");
- }
- for (int j = 0; j < instr.Arg2; j++)
- {
- s.PopInt();
- }
- TypeWrapper type = GetConstantPoolClassType(instr.Arg1);
- if (type.ArrayRank < instr.Arg2)
- {
- throw new VerifyError("Illegal dimension argument");
- }
- s.PushType(type);
- break;
- }
- case NormalizedByteCode.__anewarray:
- {
- s.PopInt();
- TypeWrapper type = GetConstantPoolClassType(instr.Arg1);
- if (type.IsUnloadable)
- {
- s.PushType(new UnloadableTypeWrapper("[" + type.SigName));
- }
- else
- {
- s.PushType(type.MakeArrayType(1));
- }
- break;
- }
- case NormalizedByteCode.__newarray:
- s.PopInt();
- switch (instr.Arg1)
- {
- case 4:
- s.PushType(BooleanArrayType);
- break;
- case 5:
- s.PushType(CharArrayType);
- break;
- case 6:
- s.PushType(FloatArrayType);
- break;
- case 7:
- s.PushType(DoubleArrayType);
- break;
- case 8:
- s.PushType(ByteArrayType);
- break;
- case 9:
- s.PushType(ShortArrayType);
- break;
- case 10:
- s.PushType(IntArrayType);
- break;
- case 11:
- s.PushType(LongArrayType);
- break;
- default:
- throw new VerifyError("Bad type");
- }
- break;
- case NormalizedByteCode.__swap:
- {
- TypeWrapper t1 = s.PopType();
- TypeWrapper t2 = s.PopType();
- s.PushType(t1);
- s.PushType(t2);
- break;
- }
- case NormalizedByteCode.__dup:
- {
- TypeWrapper t = s.PopType();
- s.PushType(t);
- s.PushType(t);
- break;
- }
- case NormalizedByteCode.__dup2:
- {
- TypeWrapper t = s.PopAnyType();
- if (t.IsWidePrimitive || t == VerifierTypeWrapper.ExtendedDouble)
- {
- s.PushType(t);
- s.PushType(t);
- }
- else
- {
- TypeWrapper t2 = s.PopType();
- s.PushType(t2);
- s.PushType(t);
- s.PushType(t2);
- s.PushType(t);
- }
- break;
- }
- case NormalizedByteCode.__dup_x1:
- {
- TypeWrapper value1 = s.PopType();
- TypeWrapper value2 = s.PopType();
- s.PushType(value1);
- s.PushType(value2);
- s.PushType(value1);
- break;
- }
- case NormalizedByteCode.__dup2_x1:
- {
- TypeWrapper value1 = s.PopAnyType();
- if (value1.IsWidePrimitive || value1 == VerifierTypeWrapper.ExtendedDouble)
- {
- TypeWrapper value2 = s.PopType();
- s.PushType(value1);
- s.PushType(value2);
- s.PushType(value1);
- }
- else
- {
- TypeWrapper value2 = s.PopType();
- TypeWrapper value3 = s.PopType();
- s.PushType(value2);
- s.PushType(value1);
- s.PushType(value3);
- s.PushType(value2);
- s.PushType(value1);
- }
- break;
- }
- case NormalizedByteCode.__dup_x2:
- {
- TypeWrapper value1 = s.PopType();
- TypeWrapper value2 = s.PopAnyType();
- if (value2.IsWidePrimitive || value2 == VerifierTypeWrapper.ExtendedDouble)
- {
- s.PushType(value1);
- s.PushType(value2);
- s.PushType(value1);
- }
- else
- {
- TypeWrapper value3 = s.PopType();
- s.PushType(value1);
- s.PushType(value3);
- s.PushType(value2);
- s.PushType(value1);
- }
- break;
- }
- case NormalizedByteCode.__dup2_x2:
- {
- TypeWrapper value1 = s.PopAnyType();
- if (value1.IsWidePrimitive || value1 == VerifierTypeWrapper.ExtendedDouble)
- {
- TypeWrapper value2 = s.PopAnyType();
- if (value2.IsWidePrimitive || value2 == VerifierTypeWrapper.ExtendedDouble)
- {
- // Form 4
- s.PushType(value1);
- s.PushType(value2);
- s.PushType(value1);
- }
- else
- {
- // Form 2
- TypeWrapper value3 = s.PopType();
- s.PushType(value1);
- s.PushType(value3);
- s.PushType(value2);
- s.PushType(value1);
- }
- }
- else
- {
- TypeWrapper value2 = s.PopType();
- TypeWrapper value3 = s.PopAnyType();
- if (value3.IsWidePrimitive || value3 == VerifierTypeWrapper.ExtendedDouble)
- {
- // Form 3
- s.PushType(value2);
- s.PushType(value1);
- s.PushType(value3);
- s.PushType(value2);
- s.PushType(value1);
- }
- else
- {
- // Form 4
- TypeWrapper value4 = s.PopType();
- s.PushType(value2);
- s.PushType(value1);
- s.PushType(value4);
- s.PushType(value3);
- s.PushType(value2);
- s.PushType(value1);
- }
- }
- break;
- }
- case NormalizedByteCode.__pop:
- s.PopType();
- break;
- case NormalizedByteCode.__pop2:
- {
- TypeWrapper type = s.PopAnyType();
- if (!type.IsWidePrimitive && type != VerifierTypeWrapper.ExtendedDouble)
- {
- s.PopType();
- }
- break;
- }
- case NormalizedByteCode.__monitorenter:
- case NormalizedByteCode.__monitorexit:
- // TODO these bytecodes are allowed on an uninitialized object, but
- // we don't support that at the moment...
- s.PopObjectType();
- break;
- case NormalizedByteCode.__return:
- // mw is null if we're called from IsSideEffectFreeStaticInitializer
- if (mw != null)
- {
- if (mw.ReturnType != PrimitiveTypeWrapper.VOID)
- {
- throw new VerifyError("Wrong return type in function");
- }
- // if we're a constructor, make sure we called the base class constructor
- s.CheckUninitializedThis();
- }
- break;
- case NormalizedByteCode.__areturn:
- s.PopObjectType(mw.ReturnType);
- break;
- case NormalizedByteCode.__ireturn:
- {
- s.PopInt();
- if (!mw.ReturnType.IsIntOnStackPrimitive)
- {
- throw new VerifyError("Wrong return type in function");
- }
- break;
- }
- case NormalizedByteCode.__lreturn:
- s.PopLong();
- if (mw.ReturnType != PrimitiveTypeWrapper.LONG)
- {
- throw new VerifyError("Wrong return type in function");
- }
- break;
- case NormalizedByteCode.__freturn:
- s.PopFloat();
- if (mw.ReturnType != PrimitiveTypeWrapper.FLOAT)
- {
- throw new VerifyError("Wrong return type in function");
- }
- break;
- case NormalizedByteCode.__dreturn:
- s.PopDouble();
- if (mw.ReturnType != PrimitiveTypeWrapper.DOUBLE)
- {
- throw new VerifyError("Wrong return type in function");
- }
- break;
- case NormalizedByteCode.__fload:
- s.GetLocalFloat(instr.NormalizedArg1);
- s.PushFloat();
- break;
- case NormalizedByteCode.__fstore:
- s.PopFloat();
- s.SetLocalFloat(instr.NormalizedArg1, i);
- break;
- case NormalizedByteCode.__dload:
- s.GetLocalDouble(instr.NormalizedArg1);
- s.PushDouble();
- break;
- case NormalizedByteCode.__dstore:
- s.PopDouble();
- s.SetLocalDouble(instr.NormalizedArg1, i);
- break;
- case NormalizedByteCode.__lload:
- s.GetLocalLong(instr.NormalizedArg1);
- s.PushLong();
- break;
- case NormalizedByteCode.__lstore:
- s.PopLong();
- s.SetLocalLong(instr.NormalizedArg1, i);
- break;
- case NormalizedByteCode.__lconst_0:
- case NormalizedByteCode.__lconst_1:
- s.PushLong();
- break;
- case NormalizedByteCode.__fconst_0:
- case NormalizedByteCode.__fconst_1:
- case NormalizedByteCode.__fconst_2:
- s.PushFloat();
- break;
- case NormalizedByteCode.__dconst_0:
- case NormalizedByteCode.__dconst_1:
- s.PushDouble();
- break;
- case NormalizedByteCode.__lcmp:
- s.PopLong();
- s.PopLong();
- s.PushInt();
- break;
- case NormalizedByteCode.__fcmpl:
- case NormalizedByteCode.__fcmpg:
- s.PopFloat();
- s.PopFloat();
- s.PushInt();
- break;
- case NormalizedByteCode.__dcmpl:
- case NormalizedByteCode.__dcmpg:
- s.PopDouble();
- s.PopDouble();
- s.PushInt();
- break;
- case NormalizedByteCode.__checkcast:
- s.PopObjectType();
- s.PushType(GetConstantPoolClassType(instr.Arg1));
- break;
- case NormalizedByteCode.__instanceof:
- s.PopObjectType();
- s.PushInt();
- break;
- case NormalizedByteCode.__iinc:
- s.GetLocalInt(instr.Arg1);
- break;
- case NormalizedByteCode.__athrow:
- if (VerifierTypeWrapper.IsFaultBlockException(s.PeekType()))
- {
- s.PopFaultBlockException();
- }
- else
- {
- s.PopObjectType(CoreClasses.java.lang.Throwable.Wrapper);
- }
- break;
- case NormalizedByteCode.__tableswitch:
- case NormalizedByteCode.__lookupswitch:
- s.PopInt();
- break;
- case NormalizedByteCode.__i2b:
- s.PopInt();
- s.PushInt();
- break;
- case NormalizedByteCode.__i2c:
- s.PopInt();
- s.PushInt();
- break;
- case NormalizedByteCode.__i2s:
- s.PopInt();
- s.PushInt();
- break;
- case NormalizedByteCode.__i2l:
- s.PopInt();
- s.PushLong();
- break;
- case NormalizedByteCode.__i2f:
- s.PopInt();
- s.PushFloat();
- break;
- case NormalizedByteCode.__i2d:
- s.PopInt();
- s.PushDouble();
- break;
- case NormalizedByteCode.__l2i:
- s.PopLong();
- s.PushInt();
- break;
- case NormalizedByteCode.__l2f:
- s.PopLong();
- s.PushFloat();
- break;
- case NormalizedByteCode.__l2d:
- s.PopLong();
- s.PushDouble();
- break;
- case NormalizedByteCode.__f2i:
- s.PopFloat();
- s.PushInt();
- break;
- case NormalizedByteCode.__f2l:
- s.PopFloat();
- s.PushLong();
- break;
- case NormalizedByteCode.__f2d:
- s.PopFloat();
- s.PushDouble();
- break;
- case NormalizedByteCode.__d2i:
- s.PopDouble();
- s.PushInt();
- break;
- case NormalizedByteCode.__d2f:
- s.PopDouble();
- s.PushFloat();
- break;
- case NormalizedByteCode.__d2l:
- s.PopDouble();
- s.PushLong();
- break;
- case NormalizedByteCode.__nop:
- if (i + 1 == instructions.Length)
- {
- throw new VerifyError("Falling off the end of the code");
- }
- break;
- case NormalizedByteCode.__static_error:
- break;
- case NormalizedByteCode.__jsr:
- case NormalizedByteCode.__ret:
- throw new VerifyError("Bad instruction");
- default:
- throw new NotImplementedException(instr.NormalizedOpCode.ToString());
- }
- if (s.GetStackHeight() > method.MaxStack)
- {
- throw new VerifyError("Stack size too large");
- }
- for (int j = 0; j < method.ExceptionTable.Length; j++)
- {
- if (method.ExceptionTable[j].endIndex == i + 1)
- {
- MergeExceptionHandler(j, s);
- }
- }
- try
- {
- switch (ByteCodeMetaData.GetFlowControl(instr.NormalizedOpCode))
- {
- case ByteCodeFlowControl.Switch:
- for (int j = 0; j < instr.SwitchEntryCount; j++)
- {
- state[instr.GetSwitchTargetIndex(j)] += s;
- }
- state[instr.DefaultTarget] += s;
- break;
- case ByteCodeFlowControl.CondBranch:
- state[i + 1] += s;
- state[instr.TargetIndex] += s;
- break;
- case ByteCodeFlowControl.Branch:
- state[instr.TargetIndex] += s;
- break;
- case ByteCodeFlowControl.Return:
- case ByteCodeFlowControl.Throw:
- break;
- case ByteCodeFlowControl.Next:
- state[i + 1] += s;
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- catch (IndexOutOfRangeException)
- {
- // we're going to assume that this always means that we have an invalid branch target
- // NOTE because PcIndexMap returns -1 for illegal PCs (in the middle of an instruction) and
- // we always use that value as an index into the state array, any invalid PC will result
- // in an IndexOutOfRangeException
- throw new VerifyError("Illegal target of jump or branch");
- }
- }
- catch (VerifyError x)
- {
- string opcode = instructions[i].NormalizedOpCode.ToString();
- if (opcode.StartsWith("__"))
- {
- opcode = opcode.Substring(2);
- }
- throw new VerifyError(string.Format("{5} (class: {0}, method: {1}, signature: {2}, offset: {3}, instruction: {4})",
- classFile.Name, method.Name, method.Signature, instructions[i].PC, opcode, x.Message), x);
- }
- }
- }
- }
- }
-
- private void MergeExceptionHandler(int exceptionIndex, InstructionState curr)
- {
- int idx = method.ExceptionTable[exceptionIndex].handlerIndex;
- InstructionState ex = curr.CopyLocals();
- int catch_type = method.ExceptionTable[exceptionIndex].catch_type;
- if (catch_type == 0)
- {
- TypeWrapper tw;
- if (!faultTypes.TryGetValue(idx, out tw))
- {
- tw = VerifierTypeWrapper.MakeFaultBlockException(this, idx);
- faultTypes.Add(idx, tw);
- }
- ex.PushType(tw);
- }
- else
- {
- // TODO if the exception type is unloadable we should consider pushing
- // Throwable as the type and recording a loader constraint
- ex.PushType(GetConstantPoolClassType(catch_type));
- }
- state[idx] += ex;
- }
-
- // this verification pass must run on the unmodified bytecode stream
- private void VerifyPassTwo()
- {
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- for (int i = 0; i < instructions.Length; i++)
- {
- if (state[i] != null)
- {
- try
- {
- switch (instructions[i].NormalizedOpCode)
- {
- case NormalizedByteCode.__invokeinterface:
- case NormalizedByteCode.__invokespecial:
- case NormalizedByteCode.__invokestatic:
- case NormalizedByteCode.__invokevirtual:
- VerifyInvokePassTwo(i);
- break;
- case NormalizedByteCode.__invokedynamic:
- VerifyInvokeDynamic(i);
- break;
- }
- }
- catch (VerifyError x)
- {
- string opcode = instructions[i].NormalizedOpCode.ToString();
- if (opcode.StartsWith("__"))
- {
- opcode = opcode.Substring(2);
- }
- throw new VerifyError(string.Format("{5} (class: {0}, method: {1}, signature: {2}, offset: {3}, instruction: {4})",
- classFile.Name, method.Name, method.Signature, instructions[i].PC, opcode, x.Message), x);
- }
- }
- }
- }
-
- private void VerifyInvokePassTwo(int index)
- {
- StackState stack = new StackState(state[index]);
- NormalizedByteCode invoke = method.Instructions[index].NormalizedOpCode;
- ClassFile.ConstantPoolItemMI cpi = GetMethodref(method.Instructions[index].Arg1);
- if ((invoke == NormalizedByteCode.__invokestatic || invoke == NormalizedByteCode.__invokespecial) && classFile.MajorVersion >= 52)
- {
- // invokestatic and invokespecial may be used to invoke interface methods in Java 8
- // but invokespecial can only invoke methods in the current interface or a directly implemented interface
- if (invoke == NormalizedByteCode.__invokespecial && cpi is ClassFile.ConstantPoolItemInterfaceMethodref)
- {
- if (cpi.GetClassType() == host)
- {
- // ok
- }
- else if (cpi.GetClassType() != wrapper && Array.IndexOf(wrapper.Interfaces, cpi.GetClassType()) == -1)
- {
- throw new VerifyError("Bad invokespecial instruction: interface method reference is in an indirect superinterface.");
- }
- }
- }
- else if ((cpi is ClassFile.ConstantPoolItemInterfaceMethodref) != (invoke == NormalizedByteCode.__invokeinterface))
- {
- throw new VerifyError("Illegal constant pool index");
- }
- if (invoke != NormalizedByteCode.__invokespecial && ReferenceEquals(cpi.Name, StringConstants.INIT))
- {
- throw new VerifyError("Must call initializers using invokespecial");
- }
- if (ReferenceEquals(cpi.Name, StringConstants.CLINIT))
- {
- throw new VerifyError("Illegal call to internal method");
- }
- TypeWrapper[] args = cpi.GetArgTypes();
- for (int j = args.Length - 1; j >= 0; j--)
- {
- stack.PopType(args[j]);
- }
- if (invoke == NormalizedByteCode.__invokeinterface)
- {
- int argcount = args.Length + 1;
- for (int j = 0; j < args.Length; j++)
- {
- if (args[j].IsWidePrimitive)
- {
- argcount++;
- }
- }
- if (method.Instructions[index].Arg2 != argcount)
- {
- throw new VerifyError("Inconsistent args size");
- }
- }
- bool isnew = false;
- TypeWrapper thisType;
- if (invoke == NormalizedByteCode.__invokestatic)
- {
- thisType = null;
- }
- else
- {
- thisType = SigTypeToClassName(stack.PeekType(), cpi.GetClassType(), wrapper);
- if (ReferenceEquals(cpi.Name, StringConstants.INIT))
- {
- TypeWrapper type = stack.PopType();
- isnew = VerifierTypeWrapper.IsNew(type);
- if ((isnew && ((VerifierTypeWrapper)type).UnderlyingType != cpi.GetClassType()) ||
- (type == VerifierTypeWrapper.UninitializedThis && cpi.GetClassType() != wrapper.BaseTypeWrapper && cpi.GetClassType() != wrapper) ||
- (!isnew && type != VerifierTypeWrapper.UninitializedThis))
- {
- // TODO oddly enough, Java fails verification for the class without
- // even running the constructor, so maybe constructors are always
- // verified...
- // NOTE when a constructor isn't verifiable, the static initializer
- // doesn't run either
- throw new VerifyError("Call to wrong initialization method");
- }
- }
- else
- {
- if (invoke != NormalizedByteCode.__invokeinterface)
- {
- TypeWrapper refType = stack.PopObjectType();
- TypeWrapper targetType = cpi.GetClassType();
- if (!VerifierTypeWrapper.IsNullOrUnloadable(refType) &&
- !targetType.IsUnloadable &&
- !refType.IsAssignableTo(targetType))
- {
- throw new VerifyError("Incompatible object argument for function call");
- }
- // for invokespecial we also need to make sure we're calling ourself or a base class
- if (invoke == NormalizedByteCode.__invokespecial)
- {
- if (VerifierTypeWrapper.IsNullOrUnloadable(refType))
- {
- // ok
- }
- else if (refType.IsSubTypeOf(wrapper))
- {
- // ok
- }
- else if (host != null && refType.IsSubTypeOf(host))
- {
- // ok
- }
- else
- {
- throw new VerifyError("Incompatible target object for invokespecial");
- }
- if (targetType.IsUnloadable)
- {
- // ok
- }
- else if (wrapper.IsSubTypeOf(targetType))
- {
- // ok
- }
- else if (host != null && host.IsSubTypeOf(targetType))
- {
- // ok
- }
- else
- {
- throw new VerifyError("Invokespecial cannot call subclass methods");
- }
- }
- }
- else /* __invokeinterface */
- {
- // NOTE unlike in the above case, we also allow *any* interface target type
- // regardless of whether it is compatible or not, because if it is not compatible
- // we want an IncompatibleClassChangeError at runtime
- TypeWrapper refType = stack.PopObjectType();
- TypeWrapper targetType = cpi.GetClassType();
- if (!VerifierTypeWrapper.IsNullOrUnloadable(refType)
- && !targetType.IsUnloadable
- && !refType.IsAssignableTo(targetType)
- && !targetType.IsInterface)
- {
- throw new VerifyError("Incompatible object argument for function call");
- }
- }
- }
- }
- }
-
- private void VerifyInvokeDynamic(int index)
- {
- StackState stack = new StackState(state[index]);
- ClassFile.ConstantPoolItemInvokeDynamic cpi = GetInvokeDynamic(method.Instructions[index].Arg1);
- TypeWrapper[] args = cpi.GetArgTypes();
- for (int j = args.Length - 1; j >= 0; j--)
- {
- stack.PopType(args[j]);
- }
- }
-
- private static void OptimizationPass(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, UntangledExceptionTable exceptions, TypeWrapper wrapper, ClassLoaderWrapper classLoader)
- {
- // Optimization pass
- if (classLoader.RemoveAsserts)
- {
- // While the optimization is general, in practice it never happens that a getstatic is used on a final field,
- // so we only look for this if assert initialization has been optimized out.
- if (classFile.HasAssertions)
- {
- // compute branch targets
- InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(codeInfo, method.Instructions, exceptions, 0, false);
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- for (int i = 0; i < instructions.Length; i++)
- {
- if (instructions[i].NormalizedOpCode == NormalizedByteCode.__getstatic
- && instructions[i + 1].NormalizedOpCode == NormalizedByteCode.__ifne
- && instructions[i + 1].TargetIndex > i
- && (flags[i + 1] & InstructionFlags.BranchTarget) == 0)
- {
- var field = classFile.GetFieldref(instructions[i].Arg1).GetField() as ConstantFieldWrapper;
- if (field != null && field.FieldTypeWrapper == PrimitiveTypeWrapper.BOOLEAN && (bool)field.GetConstantValue())
- {
- // We know the branch will always be taken, so we replace the getstatic/ifne by a goto.
- instructions[i].PatchOpCode(NormalizedByteCode.__goto, instructions[i + 1].TargetIndex);
- }
- }
- }
- }
- }
- }
-
- private void PatchHardErrorsAndDynamicMemberAccess(TypeWrapper wrapper, MethodWrapper mw)
- {
- // Now we do another pass to find "hard error" instructions
- if (true)
- {
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- for (int i = 0; i < instructions.Length; i++)
- {
- if (state[i] != null)
- {
- StackState stack = new StackState(state[i]);
- switch (instructions[i].NormalizedOpCode)
- {
- case NormalizedByteCode.__invokeinterface:
- case NormalizedByteCode.__invokespecial:
- case NormalizedByteCode.__invokestatic:
- case NormalizedByteCode.__invokevirtual:
- PatchInvoke(wrapper, ref instructions[i], stack);
- break;
- case NormalizedByteCode.__getfield:
- case NormalizedByteCode.__putfield:
- case NormalizedByteCode.__getstatic:
- case NormalizedByteCode.__putstatic:
- PatchFieldAccess(wrapper, mw, ref instructions[i], stack);
- break;
- case NormalizedByteCode.__ldc:
- switch (classFile.GetConstantPoolConstantType(instructions[i].Arg1))
- {
- case ClassFile.ConstantType.Class:
- {
- TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- break;
- }
- case ClassFile.ConstantType.MethodType:
- {
- ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(instructions[i].Arg1);
- TypeWrapper[] args = cpi.GetArgTypes();
- TypeWrapper tw = cpi.GetRetType();
- for (int j = 0; !tw.IsUnloadable && j < args.Length; j++)
- {
- tw = args[j];
- }
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- break;
- }
- case ClassFile.ConstantType.MethodHandle:
- PatchLdcMethodHandle(ref instructions[i]);
- break;
- }
- break;
- case NormalizedByteCode.__new:
- {
- TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- else if (!tw.IsAccessibleFrom(wrapper))
- {
- SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
- }
- else if (tw.IsAbstract)
- {
- SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.InstantiationError, "{0}", tw.Name);
- }
- break;
- }
- case NormalizedByteCode.__multianewarray:
- case NormalizedByteCode.__anewarray:
- {
- TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- else if (!tw.IsAccessibleFrom(wrapper))
- {
- SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
- }
- break;
- }
- case NormalizedByteCode.__checkcast:
- case NormalizedByteCode.__instanceof:
- {
- TypeWrapper tw = classFile.GetConstantPoolClassType(instructions[i].Arg1);
- if (tw.IsUnloadable)
- {
- // If the type is unloadable, we always generate the dynamic code
- // (regardless of ClassLoaderWrapper.DisableDynamicBinding), because at runtime,
- // null references should always pass thru without attempting
- // to load the type (for Sun compatibility).
- }
- else if (!tw.IsAccessibleFrom(wrapper))
- {
- SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name);
- }
- break;
- }
- case NormalizedByteCode.__aaload:
- {
- stack.PopInt();
- TypeWrapper tw = stack.PopArrayType();
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- break;
- }
- case NormalizedByteCode.__aastore:
- {
- stack.PopObjectType();
- stack.PopInt();
- TypeWrapper tw = stack.PopArrayType();
- if (tw.IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instructions[i], tw);
- }
- break;
- }
- default:
- break;
- }
- }
- }
- }
- }
-
- private void PatchLdcMethodHandle(ref ClassFile.Method.Instruction instr)
- {
- ClassFile.ConstantPoolItemMethodHandle cpi = classFile.GetConstantPoolConstantMethodHandle(instr.Arg1);
- if (cpi.GetClassType().IsUnloadable)
- {
- ConditionalPatchNoClassDefFoundError(ref instr, cpi.GetClassType());
- }
- else if (!cpi.GetClassType().IsAccessibleFrom(wrapper))
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access class {0} from class {1}", cpi.Class, wrapper.Name);
- }
- else if (cpi.Kind == ReferenceKind.InvokeVirtual
- && cpi.GetClassType() == CoreClasses.java.lang.invoke.MethodHandle.Wrapper
- && (cpi.Name == "invoke" || cpi.Name == "invokeExact"))
- {
- // it's allowed to use ldc to create a MethodHandle invoker
- }
- else if (cpi.Member == null || cpi.Member.IsStatic != (cpi.Kind == ReferenceKind.GetStatic || cpi.Kind == ReferenceKind.PutStatic || cpi.Kind == ReferenceKind.InvokeStatic))
- {
- HardError err;
- string msg;
- switch (cpi.Kind)
- {
- case ReferenceKind.GetField:
- case ReferenceKind.GetStatic:
- case ReferenceKind.PutField:
- case ReferenceKind.PutStatic:
- err = HardError.NoSuchFieldError;
- msg = cpi.Name;
- break;
- default:
- err = HardError.NoSuchMethodError;
- msg = cpi.Class + "." + cpi.Name + cpi.Signature;
- break;
- }
- SetHardError(wrapper.GetClassLoader(), ref instr, err, msg, cpi.Class, cpi.Name, SigToString(cpi.Signature));
- }
- else if (!cpi.Member.IsAccessibleFrom(cpi.GetClassType(), wrapper, cpi.GetClassType()))
- {
- if (cpi.Member.IsProtected && wrapper.IsSubTypeOf(cpi.Member.DeclaringType))
- {
- // this is allowed, the receiver will be narrowed to current type
- }
- else
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}/{3}, from {4}", cpi.Class, cpi.Name, SigToString(cpi.Signature), cpi.Kind, wrapper.Name);
- }
- }
- }
-
- private static string SigToString(string sig)
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- string sep = "";
- int dims = 0;
- for (int i = 0; i < sig.Length; i++)
- {
- if (sig[i] == '(' || sig[i] == ')')
- {
- sb.Append(sig[i]);
- sep = "";
- continue;
- }
- else if (sig[i] == '[')
- {
- dims++;
- continue;
- }
- sb.Append(sep);
- sep = ",";
- switch (sig[i])
- {
- case 'V':
- sb.Append("void");
- break;
- case 'B':
- sb.Append("byte");
- break;
- case 'Z':
- sb.Append("boolean");
- break;
- case 'S':
- sb.Append("short");
- break;
- case 'C':
- sb.Append("char");
- break;
- case 'I':
- sb.Append("int");
- break;
- case 'J':
- sb.Append("long");
- break;
- case 'F':
- sb.Append("float");
- break;
- case 'D':
- sb.Append("double");
- break;
- case 'L':
- sb.Append(sig, i + 1, sig.IndexOf(';', i + 1) - (i + 1));
- i = sig.IndexOf(';', i + 1);
- break;
- }
- for (; dims != 0; dims--)
- {
- sb.Append("[]");
- }
- }
- return sb.ToString();
- }
-
- internal static InstructionFlags[] ComputePartialReachability(CodeInfo codeInfo, ClassFile.Method.Instruction[] instructions, UntangledExceptionTable exceptions, int initialInstructionIndex, bool skipFaultBlocks)
- {
- InstructionFlags[] flags = new InstructionFlags[instructions.Length];
- flags[initialInstructionIndex] |= InstructionFlags.Reachable;
- UpdatePartialReachability(flags, codeInfo, instructions, exceptions, skipFaultBlocks);
- return flags;
- }
-
- private static void UpdatePartialReachability(InstructionFlags[] flags, CodeInfo codeInfo, ClassFile.Method.Instruction[] instructions, UntangledExceptionTable exceptions, bool skipFaultBlocks)
- {
- bool done = false;
- while (!done)
- {
- done = true;
- for (int i = 0; i < instructions.Length; i++)
- {
- if ((flags[i] & (InstructionFlags.Reachable | InstructionFlags.Processed)) == InstructionFlags.Reachable)
- {
- done = false;
- flags[i] |= InstructionFlags.Processed;
- // mark the exception handlers reachable from this instruction
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
- {
- int idx = exceptions[j].handlerIndex;
- if (!skipFaultBlocks || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(idx, 0)))
- {
- flags[idx] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
- }
- }
- }
- MarkSuccessors(instructions, flags, i);
- }
- }
- }
- }
-
- private static void MarkSuccessors(ClassFile.Method.Instruction[] code, InstructionFlags[] flags, int index)
- {
- switch (ByteCodeMetaData.GetFlowControl(code[index].NormalizedOpCode))
- {
- case ByteCodeFlowControl.Switch:
- {
- for (int i = 0; i < code[index].SwitchEntryCount; i++)
- {
- flags[code[index].GetSwitchTargetIndex(i)] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
- }
- flags[code[index].DefaultTarget] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
- break;
- }
- case ByteCodeFlowControl.Branch:
- flags[code[index].TargetIndex] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
- break;
- case ByteCodeFlowControl.CondBranch:
- flags[code[index].TargetIndex] |= InstructionFlags.Reachable | InstructionFlags.BranchTarget;
- flags[index + 1] |= InstructionFlags.Reachable;
- break;
- case ByteCodeFlowControl.Return:
- case ByteCodeFlowControl.Throw:
- break;
- case ByteCodeFlowControl.Next:
- flags[index + 1] |= InstructionFlags.Reachable;
- break;
- default:
- throw new InvalidOperationException();
- }
- }
-
- internal static UntangledExceptionTable UntangleExceptionBlocks(ClassFile classFile, ClassFile.Method method)
- {
- ClassFile.Method.Instruction[] instructions = method.Instructions;
- ExceptionTableEntry[] exceptionTable = method.ExceptionTable;
- List ar = new List(exceptionTable);
-
- // This optimization removes the recursive exception handlers that Java compiler place around
- // the exit of a synchronization block to be "safe" in the face of asynchronous exceptions.
- // (see http://weblog.ikvm.net/PermaLink.aspx?guid=3af9548e-4905-4557-8809-65a205ce2cd6)
- // We can safely remove them since the code we generate for this construct isn't async safe anyway,
- // but there is another reason why this optimization may be slightly controversial. In some
- // pathological cases it can cause observable differences, where the Sun JVM would spin in an
- // infinite loop, but we will throw an exception. However, the perf benefit is large enough to
- // warrant this "incompatibility".
- // Note that there is also code in the exception handler handling code that detects these bytecode
- // sequences to try to compile them into a fault block, instead of an exception handler.
- for (int i = 0; i < ar.Count; i++)
- {
- ExceptionTableEntry ei = ar[i];
- if (ei.startIndex == ei.handlerIndex && ei.catch_type == 0)
- {
- int index = ei.startIndex;
- if (index + 2 < instructions.Length
- && ei.endIndex == index + 2
- && instructions[index].NormalizedOpCode == NormalizedByteCode.__aload
- && instructions[index + 1].NormalizedOpCode == NormalizedByteCode.__monitorexit
- && instructions[index + 2].NormalizedOpCode == NormalizedByteCode.__athrow)
- {
- // this is the async exception guard that Jikes and the Eclipse Java Compiler produce
- ar.RemoveAt(i);
- i--;
- }
- else if (index + 4 < instructions.Length
- && ei.endIndex == index + 3
- && instructions[index].NormalizedOpCode == NormalizedByteCode.__astore
- && instructions[index + 1].NormalizedOpCode == NormalizedByteCode.__aload
- && instructions[index + 2].NormalizedOpCode == NormalizedByteCode.__monitorexit
- && instructions[index + 3].NormalizedOpCode == NormalizedByteCode.__aload
- && instructions[index + 4].NormalizedOpCode == NormalizedByteCode.__athrow
- && instructions[index].NormalizedArg1 == instructions[index + 3].NormalizedArg1)
- {
- // this is the async exception guard that javac produces
- ar.RemoveAt(i);
- i--;
- }
- else if (index + 1 < instructions.Length
- && ei.endIndex == index + 1
- && instructions[index].NormalizedOpCode == NormalizedByteCode.__astore)
- {
- // this is the finally guard that javac produces
- ar.RemoveAt(i);
- i--;
- }
- }
- }
-
- // Modern versions of javac split try blocks when the try block contains a return statement.
- // Here we merge these exception blocks again, because it allows us to generate more efficient code.
- for (int i = 0; i < ar.Count - 1; i++)
- {
- if (ar[i].endIndex + 1 == ar[i + 1].startIndex
- && ar[i].handlerIndex == ar[i + 1].handlerIndex
- && ar[i].catch_type == ar[i + 1].catch_type
- && IsReturn(instructions[ar[i].endIndex].NormalizedOpCode))
- {
- ar[i] = new ExceptionTableEntry(ar[i].startIndex, ar[i + 1].endIndex, ar[i].handlerIndex, ar[i].catch_type, ar[i].ordinal);
- ar.RemoveAt(i + 1);
- i--;
- }
- }
-
- restart:
- for (int i = 0; i < ar.Count; i++)
- {
- ExceptionTableEntry ei = ar[i];
- for (int j = 0; j < ar.Count; j++)
- {
- ExceptionTableEntry ej = ar[j];
- if (ei.startIndex <= ej.startIndex && ej.startIndex < ei.endIndex)
- {
- // 0006/test.j
- if (ej.endIndex > ei.endIndex)
- {
- ExceptionTableEntry emi = new ExceptionTableEntry(ej.startIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ExceptionTableEntry emj = new ExceptionTableEntry(ej.startIndex, ei.endIndex, ej.handlerIndex, ej.catch_type, ej.ordinal);
- ei = new ExceptionTableEntry(ei.startIndex, emi.startIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ej = new ExceptionTableEntry(emj.endIndex, ej.endIndex, ej.handlerIndex, ej.catch_type, ej.ordinal);
- ar[i] = ei;
- ar[j] = ej;
- ar.Insert(j, emj);
- ar.Insert(i + 1, emi);
- goto restart;
- }
- // 0007/test.j
- else if (j > i && ej.endIndex < ei.endIndex)
- {
- ExceptionTableEntry emi = new ExceptionTableEntry(ej.startIndex, ej.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ExceptionTableEntry eei = new ExceptionTableEntry(ej.endIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ei = new ExceptionTableEntry(ei.startIndex, emi.startIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ar[i] = ei;
- ar.Insert(i + 1, eei);
- ar.Insert(i + 1, emi);
- goto restart;
- }
- }
- }
- }
- // Split try blocks at branch targets (branches from outside the try block)
- restart_split:
- for (int i = 0; i < ar.Count; i++)
- {
- ExceptionTableEntry ei = ar[i];
- int start = ei.startIndex;
- int end = ei.endIndex;
- for (int j = 0; j < instructions.Length; j++)
- {
- if (j < start || j >= end)
- {
- switch (instructions[j].NormalizedOpCode)
- {
- case NormalizedByteCode.__tableswitch:
- case NormalizedByteCode.__lookupswitch:
- // start at -1 to have an opportunity to handle the default offset
- for (int k = -1; k < instructions[j].SwitchEntryCount; k++)
- {
- int targetIndex = (k == -1 ? instructions[j].DefaultTarget : instructions[j].GetSwitchTargetIndex(k));
- if (ei.startIndex < targetIndex && targetIndex < ei.endIndex)
- {
- ExceptionTableEntry en = new ExceptionTableEntry(targetIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ei = new ExceptionTableEntry(ei.startIndex, targetIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ar[i] = ei;
- ar.Insert(i + 1, en);
- goto restart_split;
- }
- }
- break;
- case NormalizedByteCode.__ifeq:
- case NormalizedByteCode.__ifne:
- case NormalizedByteCode.__iflt:
- case NormalizedByteCode.__ifge:
- case NormalizedByteCode.__ifgt:
- case NormalizedByteCode.__ifle:
- case NormalizedByteCode.__if_icmpeq:
- case NormalizedByteCode.__if_icmpne:
- case NormalizedByteCode.__if_icmplt:
- case NormalizedByteCode.__if_icmpge:
- case NormalizedByteCode.__if_icmpgt:
- case NormalizedByteCode.__if_icmple:
- case NormalizedByteCode.__if_acmpeq:
- case NormalizedByteCode.__if_acmpne:
- case NormalizedByteCode.__ifnull:
- case NormalizedByteCode.__ifnonnull:
- case NormalizedByteCode.__goto:
- {
- int targetIndex = instructions[j].Arg1;
- if (ei.startIndex < targetIndex && targetIndex < ei.endIndex)
- {
- ExceptionTableEntry en = new ExceptionTableEntry(targetIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ei = new ExceptionTableEntry(ei.startIndex, targetIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ar[i] = ei;
- ar.Insert(i + 1, en);
- goto restart_split;
- }
- break;
- }
- }
- }
- }
- }
- // exception handlers are also a kind of jump, so we need to split try blocks around handlers as well
- for (int i = 0; i < ar.Count; i++)
- {
- ExceptionTableEntry ei = ar[i];
- for (int j = 0; j < ar.Count; j++)
- {
- ExceptionTableEntry ej = ar[j];
- if (ei.startIndex < ej.handlerIndex && ej.handlerIndex < ei.endIndex)
- {
- ExceptionTableEntry en = new ExceptionTableEntry(ej.handlerIndex, ei.endIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ei = new ExceptionTableEntry(ei.startIndex, ej.handlerIndex, ei.handlerIndex, ei.catch_type, ei.ordinal);
- ar[i] = ei;
- ar.Insert(i + 1, en);
- goto restart_split;
- }
- }
- }
- // filter out zero length try blocks
- for (int i = 0; i < ar.Count; i++)
- {
- ExceptionTableEntry ei = ar[i];
- if (ei.startIndex == ei.endIndex)
- {
- ar.RemoveAt(i);
- i--;
- }
- else
- {
- // exception blocks that only contain harmless instructions (i.e. instructions that will *never* throw an exception)
- // are also filtered out (to improve the quality of the generated code)
- TypeWrapper exceptionType = ei.catch_type == 0 ? CoreClasses.java.lang.Throwable.Wrapper : classFile.GetConstantPoolClassType(ei.catch_type);
- if (exceptionType.IsUnloadable)
- {
- // we can't remove handlers for unloadable types
- }
- else if (java_lang_ThreadDeath.IsAssignableTo(exceptionType))
- {
- // We only remove exception handlers that could catch ThreadDeath in limited cases, because it can be thrown
- // asynchronously (and thus appear on any instruction). This is particularly important to ensure that
- // we run finally blocks when a thread is killed.
- // Note that even so, we aren't remotely async exception safe.
- int start = ei.startIndex;
- int end = ei.endIndex;
- for (int j = start; j < end; j++)
- {
- switch (instructions[j].NormalizedOpCode)
- {
- case NormalizedByteCode.__aload:
- case NormalizedByteCode.__iload:
- case NormalizedByteCode.__lload:
- case NormalizedByteCode.__fload:
- case NormalizedByteCode.__dload:
- case NormalizedByteCode.__astore:
- case NormalizedByteCode.__istore:
- case NormalizedByteCode.__lstore:
- case NormalizedByteCode.__fstore:
- case NormalizedByteCode.__dstore:
- break;
- case NormalizedByteCode.__dup:
- case NormalizedByteCode.__dup_x1:
- case NormalizedByteCode.__dup_x2:
- case NormalizedByteCode.__dup2:
- case NormalizedByteCode.__dup2_x1:
- case NormalizedByteCode.__dup2_x2:
- case NormalizedByteCode.__pop:
- case NormalizedByteCode.__pop2:
- break;
- case NormalizedByteCode.__return:
- case NormalizedByteCode.__areturn:
- case NormalizedByteCode.__ireturn:
- case NormalizedByteCode.__lreturn:
- case NormalizedByteCode.__freturn:
- case NormalizedByteCode.__dreturn:
- break;
- case NormalizedByteCode.__goto:
- // if there is a branch that stays inside the block, we should keep the block
- if (start <= instructions[j].TargetIndex && instructions[j].TargetIndex < end)
- goto next;
- break;
- default:
- goto next;
- }
- }
- ar.RemoveAt(i);
- i--;
- }
- else
- {
- int start = ei.startIndex;
- int end = ei.endIndex;
- for (int j = start; j < end; j++)
- {
- if (ByteCodeMetaData.CanThrowException(instructions[j].NormalizedOpCode))
- {
- goto next;
- }
- }
- ar.RemoveAt(i);
- i--;
- }
- }
- next:;
- }
-
- ExceptionTableEntry[] exceptions = ar.ToArray();
- Array.Sort(exceptions, new ExceptionSorter());
-
- return new UntangledExceptionTable(exceptions);
- }
-
- private static bool IsReturn(NormalizedByteCode bc)
- {
- return bc == NormalizedByteCode.__return
- || bc == NormalizedByteCode.__areturn
- || bc == NormalizedByteCode.__dreturn
- || bc == NormalizedByteCode.__ireturn
- || bc == NormalizedByteCode.__freturn
- || bc == NormalizedByteCode.__lreturn;
- }
-
- private static bool AnalyzePotentialFaultBlocks(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
- {
- ClassFile.Method.Instruction[] code = method.Instructions;
- bool changed = false;
- bool done = false;
- while (!done)
- {
- done = true;
- Stack stack = new Stack();
- ExceptionTableEntry current = new ExceptionTableEntry(0, code.Length, -1, ushort.MaxValue, -1);
- stack.Push(current);
- for (int i = 0; i < exceptions.Length; i++)
- {
- while (exceptions[i].startIndex >= current.endIndex)
- {
- current = stack.Pop();
- }
- Debug.Assert(exceptions[i].startIndex >= current.startIndex && exceptions[i].endIndex <= current.endIndex);
- if (exceptions[i].catch_type == 0
- && codeInfo.HasState(exceptions[i].handlerIndex)
- && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0)))
- {
- InstructionFlags[] flags = MethodAnalyzer.ComputePartialReachability(codeInfo, method.Instructions, exceptions, exceptions[i].handlerIndex, true);
- for (int j = 0; j < code.Length; j++)
- {
- if ((flags[j] & InstructionFlags.Reachable) != 0)
- {
- switch (code[j].NormalizedOpCode)
- {
- case NormalizedByteCode.__return:
- case NormalizedByteCode.__areturn:
- case NormalizedByteCode.__ireturn:
- case NormalizedByteCode.__lreturn:
- case NormalizedByteCode.__freturn:
- case NormalizedByteCode.__dreturn:
- goto not_fault_block;
- case NormalizedByteCode.__athrow:
- for (int k = i + 1; k < exceptions.Length; k++)
- {
- if (exceptions[k].startIndex <= j && j < exceptions[k].endIndex)
- {
- goto not_fault_block;
- }
- }
- if (VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
- && codeInfo.GetRawStackTypeWrapper(j, 0) != codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0))
- {
- goto not_fault_block;
- }
- break;
- }
- if (j < current.startIndex || j >= current.endIndex)
- {
- goto not_fault_block;
- }
- else if (exceptions[i].startIndex <= j && j < exceptions[i].endIndex)
- {
- goto not_fault_block;
- }
- else
- {
- continue;
- }
- not_fault_block:
- VerifierTypeWrapper.ClearFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0));
- done = false;
- changed = true;
- break;
- }
- }
- }
- stack.Push(current);
- current = exceptions[i];
- }
- }
- return changed;
- }
-
- private static void ConvertFinallyBlocks(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
- {
- ClassFile.Method.Instruction[] code = method.Instructions;
- InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, 0, false);
- for (int i = 0; i < exceptions.Length; i++)
- {
- if (exceptions[i].catch_type == 0
- && codeInfo.HasState(exceptions[i].handlerIndex)
- && VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(exceptions[i].handlerIndex, 0)))
- {
- int exit;
- if (IsSynchronizedBlockHandler(code, exceptions[i].handlerIndex)
- && exceptions[i].endIndex - 2 >= exceptions[i].startIndex
- && TryFindSingleTryBlockExit(code, flags, exceptions, new ExceptionTableEntry(exceptions[i].startIndex, exceptions[i].endIndex - 2, exceptions[i].handlerIndex, 0, exceptions[i].ordinal), i, out exit)
- && exit == exceptions[i].endIndex - 2
- && (flags[exit + 1] & InstructionFlags.BranchTarget) == 0
- && MatchInstructions(code, exit, exceptions[i].handlerIndex + 1)
- && MatchInstructions(code, exit + 1, exceptions[i].handlerIndex + 2)
- && MatchExceptionCoverage(exceptions, i, exceptions[i].handlerIndex + 1, exceptions[i].handlerIndex + 3, exit, exit + 2)
- && exceptions[i].handlerIndex <= ushort.MaxValue)
- {
- code[exit].PatchOpCode(NormalizedByteCode.__goto_finally, exceptions[i].endIndex, (short)exceptions[i].handlerIndex);
- exceptions.SetFinally(i);
- }
- else if (TryFindSingleTryBlockExit(code, flags, exceptions, exceptions[i], i, out exit)
- // the stack must be empty
- && codeInfo.GetStackHeight(exit) == 0
- // the exit code must not be reachable (except from within the try-block),
- // because we're going to patch it to jump around the exit code
- && !IsReachableFromOutsideTryBlock(codeInfo, code, exceptions, exceptions[i], exit))
- {
- int exitHandlerEnd;
- int faultHandlerEnd;
- if (MatchFinallyBlock(codeInfo, code, exceptions, exceptions[i].handlerIndex, exit, out exitHandlerEnd, out faultHandlerEnd))
- {
- if (exit != exitHandlerEnd
- && codeInfo.GetStackHeight(exitHandlerEnd) == 0
- && MatchExceptionCoverage(exceptions, -1, exceptions[i].handlerIndex, faultHandlerEnd, exit, exitHandlerEnd))
- {
- // We use Arg2 (which is a short) to store the handler in the __goto_finally pseudo-opcode,
- // so we can only do that if handlerIndex fits in a short (note that we can use the sign bit too).
- if (exceptions[i].handlerIndex <= ushort.MaxValue)
- {
- code[exit].PatchOpCode(NormalizedByteCode.__goto_finally, exitHandlerEnd, (short)exceptions[i].handlerIndex);
- exceptions.SetFinally(i);
- }
- }
- }
- }
- }
- }
- }
-
- private static bool IsSynchronizedBlockHandler(ClassFile.Method.Instruction[] code, int index)
- {
- return code[index].NormalizedOpCode == NormalizedByteCode.__astore
- && code[index + 1].NormalizedOpCode == NormalizedByteCode.__aload
- && code[index + 2].NormalizedOpCode == NormalizedByteCode.__monitorexit
- && code[index + 3].NormalizedOpCode == NormalizedByteCode.__aload && code[index + 3].Arg1 == code[index].Arg1
- && code[index + 4].NormalizedOpCode == NormalizedByteCode.__athrow;
- }
-
- private static bool MatchExceptionCoverage(UntangledExceptionTable exceptions, int skipException, int startFault, int endFault, int startExit, int endExit)
- {
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (j != skipException && ExceptionCovers(exceptions[j], startFault, endFault) != ExceptionCovers(exceptions[j], startExit, endExit))
- {
- return false;
- }
- }
- return true;
- }
-
- private static bool ExceptionCovers(ExceptionTableEntry exception, int start, int end)
- {
- return exception.startIndex < end && exception.endIndex > start;
- }
-
- private static bool MatchFinallyBlock(CodeInfo codeInfo, ClassFile.Method.Instruction[] code, UntangledExceptionTable exceptions, int faultHandler, int exitHandler, out int exitHandlerEnd, out int faultHandlerEnd)
- {
- exitHandlerEnd = -1;
- faultHandlerEnd = -1;
- if (code[faultHandler].NormalizedOpCode != NormalizedByteCode.__astore)
- {
- return false;
- }
- int startFault = faultHandler;
- int faultLocal = code[faultHandler++].NormalizedArg1;
- for (; ; )
- {
- if (code[faultHandler].NormalizedOpCode == NormalizedByteCode.__aload
- && code[faultHandler].NormalizedArg1 == faultLocal
- && code[faultHandler + 1].NormalizedOpCode == NormalizedByteCode.__athrow)
- {
- // make sure that instructions that we haven't covered aren't reachable
- InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, startFault, false);
- for (int i = 0; i < flags.Length; i++)
- {
- if ((i < startFault || i > faultHandler + 1) && (flags[i] & InstructionFlags.Reachable) != 0)
- {
- return false;
- }
- }
- exitHandlerEnd = exitHandler;
- faultHandlerEnd = faultHandler;
- return true;
- }
- if (!MatchInstructions(code, faultHandler, exitHandler))
- {
- return false;
- }
- faultHandler++;
- exitHandler++;
- }
- }
-
- private static bool MatchInstructions(ClassFile.Method.Instruction[] code, int i, int j)
- {
- if (code[i].NormalizedOpCode != code[j].NormalizedOpCode)
- {
- return false;
- }
- switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
- {
- case ByteCodeFlowControl.Branch:
- case ByteCodeFlowControl.CondBranch:
- if (code[i].Arg1 - i != code[j].Arg1 - j)
- {
- return false;
- }
- break;
- case ByteCodeFlowControl.Switch:
- if (code[i].SwitchEntryCount != code[j].SwitchEntryCount)
- {
- return false;
- }
- for (int k = 0; k < code[i].SwitchEntryCount; k++)
- {
- if (code[i].GetSwitchTargetIndex(k) != code[j].GetSwitchTargetIndex(k))
- {
- return false;
- }
- }
- if (code[i].DefaultTarget != code[j].DefaultTarget)
- {
- return false;
- }
- break;
- default:
- if (code[i].Arg1 != code[j].Arg1)
- {
- return false;
- }
- if (code[i].Arg2 != code[j].Arg2)
- {
- return false;
- }
- break;
- }
- return true;
- }
-
- private static bool IsReachableFromOutsideTryBlock(CodeInfo codeInfo, ClassFile.Method.Instruction[] code, UntangledExceptionTable exceptions, ExceptionTableEntry tryBlock, int instructionIndex)
- {
- InstructionFlags[] flags = new InstructionFlags[code.Length];
- flags[0] |= InstructionFlags.Reachable;
- // We mark the first instruction of the try-block as already processed, so that UpdatePartialReachability will skip the try-block.
- // Note that we can do this, because it is not possible to jump into the middle of a try-block (after the exceptions have been untangled).
- flags[tryBlock.startIndex] = InstructionFlags.Processed;
- // We mark the successor instructions of the instruction we're examinining as reachable,
- // to figure out if the code following the handler somehow branches back to it.
- MarkSuccessors(code, flags, instructionIndex);
- UpdatePartialReachability(flags, codeInfo, code, exceptions, false);
- return (flags[instructionIndex] & InstructionFlags.Reachable) != 0;
- }
-
- private static bool TryFindSingleTryBlockExit(ClassFile.Method.Instruction[] code, InstructionFlags[] flags, UntangledExceptionTable exceptions, ExceptionTableEntry exception, int exceptionIndex, out int exit)
- {
- exit = -1;
- bool fail = false;
- bool nextIsReachable = false;
- for (int i = exception.startIndex; !fail && i < exception.endIndex; i++)
- {
- if ((flags[i] & InstructionFlags.Reachable) != 0)
- {
- nextIsReachable = false;
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (j != exceptionIndex && exceptions[j].startIndex >= exception.startIndex && exception.endIndex <= exceptions[j].endIndex)
- {
- UpdateTryBlockExit(exception, exceptions[j].handlerIndex, ref exit, ref fail);
- }
- }
- switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
- {
- case ByteCodeFlowControl.Switch:
- {
- for (int j = 0; j < code[i].SwitchEntryCount; j++)
- {
- UpdateTryBlockExit(exception, code[i].GetSwitchTargetIndex(j), ref exit, ref fail);
- }
- UpdateTryBlockExit(exception, code[i].DefaultTarget, ref exit, ref fail);
- break;
- }
- case ByteCodeFlowControl.Branch:
- UpdateTryBlockExit(exception, code[i].TargetIndex, ref exit, ref fail);
- break;
- case ByteCodeFlowControl.CondBranch:
- UpdateTryBlockExit(exception, code[i].TargetIndex, ref exit, ref fail);
- nextIsReachable = true;
- break;
- case ByteCodeFlowControl.Return:
- fail = true;
- break;
- case ByteCodeFlowControl.Throw:
- break;
- case ByteCodeFlowControl.Next:
- nextIsReachable = true;
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- }
- if (nextIsReachable)
- {
- UpdateTryBlockExit(exception, exception.endIndex, ref exit, ref fail);
- }
- return !fail && exit != -1;
- }
-
- private static void UpdateTryBlockExit(ExceptionTableEntry exception, int targetIndex, ref int exitIndex, ref bool fail)
- {
- if (exception.startIndex <= targetIndex && targetIndex < exception.endIndex)
- {
- // branch stays inside try block
- }
- else if (exitIndex == -1)
- {
- exitIndex = targetIndex;
- }
- else if (exitIndex != targetIndex)
- {
- fail = true;
- }
- }
-
- private void ConditionalPatchNoClassDefFoundError(ref ClassFile.Method.Instruction instruction, TypeWrapper tw)
- {
- ClassLoaderWrapper loader = wrapper.GetClassLoader();
- if (loader.DisableDynamicBinding)
- {
- SetHardError(loader, ref instruction, HardError.NoClassDefFoundError, "{0}", tw.Name);
- }
- }
-
- private void SetHardError(ClassLoaderWrapper classLoader, ref ClassFile.Method.Instruction instruction, HardError hardError, string message, params object[] args)
- {
- string text = string.Format(message, args);
-#if IMPORTER
- Message msg;
- switch (hardError)
- {
- case HardError.NoClassDefFoundError:
- msg = Message.EmittedNoClassDefFoundError;
- break;
- case HardError.IllegalAccessError:
- msg = Message.EmittedIllegalAccessError;
- break;
- case HardError.InstantiationError:
- msg = Message.EmittedIllegalAccessError;
- break;
- case HardError.IncompatibleClassChangeError:
- case HardError.IllegalAccessException:
- msg = Message.EmittedIncompatibleClassChangeError;
- break;
- case HardError.NoSuchFieldError:
- msg = Message.EmittedNoSuchFieldError;
- break;
- case HardError.AbstractMethodError:
- msg = Message.EmittedAbstractMethodError;
- break;
- case HardError.NoSuchMethodError:
- msg = Message.EmittedNoSuchMethodError;
- break;
- case HardError.LinkageError:
- msg = Message.EmittedLinkageError;
- break;
- default:
- throw new InvalidOperationException();
- }
- classLoader.IssueMessage(msg, classFile.Name + "." + method.Name + method.Signature, text);
-#endif
- instruction.SetHardError(hardError, AllocErrorMessage(text));
- }
-
- private void PatchInvoke(TypeWrapper wrapper, ref ClassFile.Method.Instruction instr, StackState stack)
- {
- ClassFile.ConstantPoolItemMI cpi = GetMethodref(instr.Arg1);
- NormalizedByteCode invoke = instr.NormalizedOpCode;
- bool isnew = false;
- TypeWrapper thisType;
- if (invoke == NormalizedByteCode.__invokevirtual
- && cpi.Class == "java.lang.invoke.MethodHandle"
- && (cpi.Name == "invoke" || cpi.Name == "invokeExact" || cpi.Name == "invokeBasic"))
- {
- if (cpi.GetArgTypes().Length > 127 && MethodHandleUtil.SlotCount(cpi.GetArgTypes()) > 254)
- {
- instr.SetHardError(HardError.LinkageError, AllocErrorMessage("bad parameter count"));
- return;
- }
- instr.PatchOpCode(NormalizedByteCode.__methodhandle_invoke);
- return;
- }
- else if (invoke == NormalizedByteCode.__invokestatic
- && cpi.Class == "java.lang.invoke.MethodHandle"
- && (cpi.Name == "linkToVirtual" || cpi.Name == "linkToStatic" || cpi.Name == "linkToSpecial" || cpi.Name == "linkToInterface")
- && CoreClasses.java.lang.invoke.MethodHandle.Wrapper.IsPackageAccessibleFrom(wrapper))
- {
- instr.PatchOpCode(NormalizedByteCode.__methodhandle_link);
- return;
- }
- else if (invoke == NormalizedByteCode.__invokestatic)
- {
- thisType = null;
- }
- else
- {
- TypeWrapper[] args = cpi.GetArgTypes();
- for (int j = args.Length - 1; j >= 0; j--)
- {
- stack.PopType(args[j]);
- }
- thisType = SigTypeToClassName(stack.PeekType(), cpi.GetClassType(), wrapper);
- if (ReferenceEquals(cpi.Name, StringConstants.INIT))
- {
- TypeWrapper type = stack.PopType();
- isnew = VerifierTypeWrapper.IsNew(type);
- }
- }
-
- if (cpi.GetClassType().IsUnloadable)
- {
- if (wrapper.GetClassLoader().DisableDynamicBinding)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name);
- }
- else
- {
- switch (invoke)
- {
- case NormalizedByteCode.__invokeinterface:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_invokeinterface);
- break;
- case NormalizedByteCode.__invokestatic:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_invokestatic);
- break;
- case NormalizedByteCode.__invokevirtual:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_invokevirtual);
- break;
- case NormalizedByteCode.__invokespecial:
- if (isnew)
- {
- instr.PatchOpCode(NormalizedByteCode.__dynamic_invokespecial);
- }
- else
- {
- throw new VerifyError("Invokespecial cannot call subclass methods");
- }
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- }
- else if (invoke == NormalizedByteCode.__invokeinterface && !cpi.GetClassType().IsInterface)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "invokeinterface on non-interface");
- }
- else if (cpi.GetClassType().IsInterface && invoke != NormalizedByteCode.__invokeinterface && ((invoke != NormalizedByteCode.__invokestatic && invoke != NormalizedByteCode.__invokespecial) || classFile.MajorVersion < 52))
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError,
- classFile.MajorVersion < 52
- ? "interface method must be invoked using invokeinterface"
- : "interface method must be invoked using invokeinterface, invokespecial or invokestatic");
- }
- else
- {
- MethodWrapper targetMethod = invoke == NormalizedByteCode.__invokespecial ? cpi.GetMethodForInvokespecial() : cpi.GetMethod();
- if (targetMethod != null)
- {
- string errmsg = CheckLoaderConstraints(cpi, targetMethod);
- if (errmsg != null)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "{0}", errmsg);
- }
- else if (targetMethod.IsStatic == (invoke == NormalizedByteCode.__invokestatic))
- {
- if (targetMethod.IsAbstract && invoke == NormalizedByteCode.__invokespecial && (targetMethod.GetMethod() == null || targetMethod.GetMethod().IsAbstract))
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.AbstractMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
- }
- else if (invoke == NormalizedByteCode.__invokeinterface && targetMethod.IsPrivate)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "private interface method requires invokespecial, not invokeinterface: method {0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
- }
- else if (targetMethod.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType))
- {
- return;
- }
- else if (host != null && targetMethod.IsAccessibleFrom(cpi.GetClassType(), host, thisType))
- {
- switch (invoke)
- {
- case NormalizedByteCode.__invokespecial:
- instr.PatchOpCode(NormalizedByteCode.__privileged_invokespecial);
- break;
- case NormalizedByteCode.__invokestatic:
- instr.PatchOpCode(NormalizedByteCode.__privileged_invokestatic);
- break;
- case NormalizedByteCode.__invokevirtual:
- instr.PatchOpCode(NormalizedByteCode.__privileged_invokevirtual);
- break;
- default:
- throw new InvalidOperationException();
- }
- return;
- }
- else
- {
- // NOTE special case for incorrect invocation of Object.clone(), because this could mean
- // we're calling clone() on an array
- // (bug in javac, see http://developer.java.sun.com/developer/bugParade/bugs/4329886.html)
- if (cpi.GetClassType() == CoreClasses.java.lang.Object.Wrapper
- && thisType.IsArray
- && ReferenceEquals(cpi.Name, StringConstants.CLONE))
- {
- // Patch the instruction, so that the compiler doesn't need to do this test again.
- instr.PatchOpCode(NormalizedByteCode.__clone_array);
- return;
- }
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access method {0}.{1}{2} from class {3}", ToSlash(targetMethod.DeclaringType.Name), cpi.Name, ToSlash(cpi.Signature), ToSlash(wrapper.Name));
- }
- }
- else
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "static call to non-static method (or v.v.)");
- }
- }
- else
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature);
- }
- }
- }
-
- private static string ToSlash(string str)
- {
- return str.Replace('.', '/');
- }
-
- private void PatchFieldAccess(TypeWrapper wrapper, MethodWrapper mw, ref ClassFile.Method.Instruction instr, StackState stack)
- {
- ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1);
- bool isStatic;
- bool write;
- TypeWrapper thisType;
- switch (instr.NormalizedOpCode)
- {
- case NormalizedByteCode.__getfield:
- isStatic = false;
- write = false;
- thisType = SigTypeToClassName(stack.PopObjectType(GetFieldref(instr.Arg1).GetClassType()), cpi.GetClassType(), wrapper);
- break;
- case NormalizedByteCode.__putfield:
- stack.PopType(GetFieldref(instr.Arg1).GetFieldType());
- isStatic = false;
- write = true;
- // putfield is allowed to access the unintialized this
- if (stack.PeekType() == VerifierTypeWrapper.UninitializedThis
- && wrapper.IsAssignableTo(GetFieldref(instr.Arg1).GetClassType()))
- {
- thisType = wrapper;
- }
- else
- {
- thisType = SigTypeToClassName(stack.PopObjectType(GetFieldref(instr.Arg1).GetClassType()), cpi.GetClassType(), wrapper);
- }
- break;
- case NormalizedByteCode.__getstatic:
- isStatic = true;
- write = false;
- thisType = null;
- break;
- case NormalizedByteCode.__putstatic:
- // special support for when we're being called from IsSideEffectFreeStaticInitializer
- if (mw == null)
- {
- switch (GetFieldref(instr.Arg1).Signature[0])
- {
- case 'B':
- case 'Z':
- case 'C':
- case 'S':
- case 'I':
- stack.PopInt();
- break;
- case 'F':
- stack.PopFloat();
- break;
- case 'D':
- stack.PopDouble();
- break;
- case 'J':
- stack.PopLong();
- break;
- case 'L':
- case '[':
- if (stack.PopAnyType() != VerifierTypeWrapper.Null)
- {
- throw new VerifyError();
- }
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- else
- {
- stack.PopType(GetFieldref(instr.Arg1).GetFieldType());
- }
- isStatic = true;
- write = true;
- thisType = null;
- break;
- default:
- throw new InvalidOperationException();
- }
- if (mw == null)
- {
- // We're being called from IsSideEffectFreeStaticInitializer,
- // no further checks are possible (nor needed).
- }
- else if (cpi.GetClassType().IsUnloadable)
- {
- if (wrapper.GetClassLoader().DisableDynamicBinding)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name);
- }
- else
- {
- switch (instr.NormalizedOpCode)
- {
- case NormalizedByteCode.__getstatic:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_getstatic);
- break;
- case NormalizedByteCode.__putstatic:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_putstatic);
- break;
- case NormalizedByteCode.__getfield:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_getfield);
- break;
- case NormalizedByteCode.__putfield:
- instr.PatchOpCode(NormalizedByteCode.__dynamic_putfield);
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- return;
- }
- else
- {
- FieldWrapper field = cpi.GetField();
- if (field == null)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchFieldError, "{0}.{1}", cpi.Class, cpi.Name);
- return;
- }
- if (false && cpi.GetFieldType() != field.FieldTypeWrapper && !cpi.GetFieldType().IsUnloadable & !field.FieldTypeWrapper.IsUnloadable)
- {
-#if IMPORTER
- StaticCompiler.LinkageError("Field \"{2}.{3}\" is of type \"{0}\" instead of type \"{1}\" as expected by \"{4}\"", field.FieldTypeWrapper, cpi.GetFieldType(), cpi.GetClassType().Name, cpi.Name, wrapper.Name);
-#endif
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "Loader constraints violated: {0}.{1}", field.DeclaringType.Name, field.Name);
- return;
- }
- if (field.IsStatic != isStatic)
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "Static field access to non-static field (or v.v.)");
- return;
- }
- if (!field.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType))
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Try to access field {0}.{1} from class {2}", field.DeclaringType.Name, field.Name, wrapper.Name);
- return;
- }
- // are we trying to mutate a final field? (they are read-only from outside of the defining class)
- if (write && field.IsFinal
- && ((isStatic ? wrapper != cpi.GetClassType() : wrapper != thisType) || (wrapper.GetClassLoader().StrictFinalFieldSemantics && (isStatic ? (mw != null && mw.Name != "") : (mw == null || mw.Name != "")))))
- {
- SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Field {0}.{1} is final", field.DeclaringType.Name, field.Name);
- return;
- }
- }
- }
-
- // TODO this method should have a better name
- private TypeWrapper SigTypeToClassName(TypeWrapper type, TypeWrapper nullType, TypeWrapper wrapper)
- {
- if (type == VerifierTypeWrapper.UninitializedThis)
- {
- return wrapper;
- }
- else if (VerifierTypeWrapper.IsNew(type))
- {
- return ((VerifierTypeWrapper)type).UnderlyingType;
- }
- else if (type == VerifierTypeWrapper.Null)
- {
- return nullType;
- }
- else
- {
- return type;
- }
- }
-
- private int AllocErrorMessage(string message)
- {
- if (errorMessages == null)
- {
- errorMessages = new List();
- }
- int index = errorMessages.Count;
- errorMessages.Add(message);
- return index;
- }
-
- private string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, MethodWrapper mw)
- {
-#if NETFRAMEWORK
- if (cpi.GetRetType() != mw.ReturnType && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable)
-#else
- if (cpi.GetRetType() != mw.ReturnType && cpi.GetRetType().Name != mw.ReturnType.Name && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable)
-#endif
- {
-#if IMPORTER
- StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a return type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", mw.ReturnType, cpi.GetRetType(), cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name);
-#endif
- return "Loader constraints violated (return type): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature;
- }
- TypeWrapper[] here = cpi.GetArgTypes();
- TypeWrapper[] there = mw.GetParameters();
- for (int i = 0; i < here.Length; i++)
- {
-#if NETFRAMEWORK
- if (here[i] != there[i] && !here[i].IsUnloadable && !there[i].IsUnloadable)
-#else
- if (here[i] != there[i] && here[i].Name != there[i].Name && !here[i].IsUnloadable && !there[i].IsUnloadable)
-#endif
- {
-#if IMPORTER
- StaticCompiler.LinkageError("Method \"{2}.{3}{4}\" has a argument type \"{0}\" instead of type \"{1}\" as expected by \"{5}\"", there[i], here[i], cpi.GetClassType().Name, cpi.Name, cpi.Signature, classFile.Name);
-#endif
- return "Loader constraints violated (arg " + i + "): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature;
- }
- }
- return null;
- }
-
- private ClassFile.ConstantPoolItemInvokeDynamic GetInvokeDynamic(int index)
- {
- try
- {
- ClassFile.ConstantPoolItemInvokeDynamic item = classFile.GetInvokeDynamic(index);
- if (item != null)
- {
- return item;
- }
- }
- catch (InvalidCastException)
- {
- }
- catch (IndexOutOfRangeException)
- {
- }
- throw new VerifyError("Illegal constant pool index");
- }
-
- private ClassFile.ConstantPoolItemMI GetMethodref(int index)
- {
- try
- {
- ClassFile.ConstantPoolItemMI item = classFile.GetMethodref(index);
- if (item != null)
- {
- return item;
- }
- }
- catch (InvalidCastException)
- {
- }
- catch (IndexOutOfRangeException)
- {
- }
- throw new VerifyError("Illegal constant pool index");
- }
-
- private ClassFile.ConstantPoolItemFieldref GetFieldref(int index)
- {
- try
- {
- ClassFile.ConstantPoolItemFieldref item = classFile.GetFieldref(index);
- if (item != null)
- {
- return item;
- }
- }
- catch (InvalidCastException)
- {
- }
- catch (IndexOutOfRangeException)
- {
- }
- throw new VerifyError("Illegal constant pool index");
- }
-
- private ClassFile.ConstantType GetConstantPoolConstantType(int index)
- {
- try
- {
- return classFile.GetConstantPoolConstantType(index);
- }
- catch (IndexOutOfRangeException)
- {
- // constant pool index out of range
- }
- catch (InvalidOperationException)
- {
- // specified constant pool entry doesn't contain a constant
- }
- catch (NullReferenceException)
- {
- // specified constant pool entry is empty (entry 0 or the filler following a wide entry)
- }
- throw new VerifyError("Illegal constant pool index");
- }
-
- private TypeWrapper GetConstantPoolClassType(int index)
- {
- try
- {
- return classFile.GetConstantPoolClassType(index);
- }
- catch (InvalidCastException)
- {
- }
- catch (IndexOutOfRangeException)
- {
- }
- catch (NullReferenceException)
- {
- }
- throw new VerifyError("Illegal constant pool index");
- }
-
- internal void ClearFaultBlockException(int instructionIndex)
- {
- Debug.Assert(state[instructionIndex].GetStackHeight() == 1);
- state[instructionIndex].ClearFaultBlockException();
- }
-
- private static void DumpMethod(CodeInfo codeInfo, ClassFile.Method method, UntangledExceptionTable exceptions)
- {
- ClassFile.Method.Instruction[] code = method.Instructions;
- InstructionFlags[] flags = ComputePartialReachability(codeInfo, code, exceptions, 0, false);
- for (int i = 0; i < code.Length; i++)
- {
- bool label = (flags[i] & InstructionFlags.BranchTarget) != 0;
- if (!label)
- {
- for (int j = 0; j < exceptions.Length; j++)
- {
- if (exceptions[j].startIndex == i
- || exceptions[j].endIndex == i
- || exceptions[j].handlerIndex == i)
- {
- label = true;
- break;
- }
- }
- }
- if (label)
- {
- Console.WriteLine("label{0}:", i);
- }
- if ((flags[i] & InstructionFlags.Reachable) != 0)
- {
- Console.Write(" {1}", i, code[i].NormalizedOpCode.ToString().Substring(2));
- switch (ByteCodeMetaData.GetFlowControl(code[i].NormalizedOpCode))
- {
- case ByteCodeFlowControl.Branch:
- case ByteCodeFlowControl.CondBranch:
- Console.Write(" label{0}", code[i].Arg1);
- break;
- }
- switch (code[i].NormalizedOpCode)
- {
- case NormalizedByteCode.__iload:
- case NormalizedByteCode.__lload:
- case NormalizedByteCode.__fload:
- case NormalizedByteCode.__dload:
- case NormalizedByteCode.__aload:
- case NormalizedByteCode.__istore:
- case NormalizedByteCode.__lstore:
- case NormalizedByteCode.__fstore:
- case NormalizedByteCode.__dstore:
- case NormalizedByteCode.__astore:
- case NormalizedByteCode.__iconst:
- Console.Write(" {0}", code[i].Arg1);
- break;
- case NormalizedByteCode.__ldc:
- case NormalizedByteCode.__ldc_nothrow:
- case NormalizedByteCode.__getfield:
- case NormalizedByteCode.__getstatic:
- case NormalizedByteCode.__putfield:
- case NormalizedByteCode.__putstatic:
- case NormalizedByteCode.__invokeinterface:
- case NormalizedByteCode.__invokespecial:
- case NormalizedByteCode.__invokestatic:
- case NormalizedByteCode.__invokevirtual:
- case NormalizedByteCode.__new:
- Console.Write(" #{0}", code[i].Arg1);
- break;
- }
- Console.WriteLine();
- }
- }
- for (int i = 0; i < exceptions.Length; i++)
- {
- Console.WriteLine(".catch #{0} from label{1} to label{2} using label{3}", exceptions[i].catch_type, exceptions[i].startIndex, exceptions[i].endIndex, exceptions[i].handlerIndex);
- }
- }
-}
diff --git a/src/IKVM.Tools.Exporter/BootstrapBootstrapClassLoader.cs b/src/IKVM.Tools.Exporter/BootstrapBootstrapClassLoader.cs
index c10bf2dbfe..1bcdc5e1db 100644
--- a/src/IKVM.Tools.Exporter/BootstrapBootstrapClassLoader.cs
+++ b/src/IKVM.Tools.Exporter/BootstrapBootstrapClassLoader.cs
@@ -24,7 +24,6 @@ Jeroen Frijters
using System;
using IKVM.Attributes;
-using IKVM.Internal;
using IKVM.Runtime;
sealed class BootstrapBootstrapClassLoader : ClassLoaderWrapper
diff --git a/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs b/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs
index 2f44f95aef..f0a418adfa 100644
--- a/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs
+++ b/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs
@@ -4,7 +4,6 @@
using System.IO.Compression;
using System.Linq;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Runtime;
using IKVM.Tools.Importer;
@@ -31,8 +30,8 @@ static class IkvmExporterInternal
///
public static int Execute(IkvmExporterOptions options)
{
- IKVM.Internal.Tracer.EnableTraceConsoleListener();
- IKVM.Internal.Tracer.EnableTraceForDebug();
+ IKVM.Runtime.Tracer.EnableTraceConsoleListener();
+ IKVM.Runtime.Tracer.EnableTraceForDebug();
var references = new List();
if (options.References != null)
diff --git a/src/IKVM.Tools.Exporter/Intrinsics.cs b/src/IKVM.Tools.Exporter/Intrinsics.cs
index f40f5149e6..101ce73183 100644
--- a/src/IKVM.Tools.Exporter/Intrinsics.cs
+++ b/src/IKVM.Tools.Exporter/Intrinsics.cs
@@ -21,7 +21,7 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
+using IKVM.Runtime;
static class Intrinsics
{
@@ -32,3 +32,4 @@ internal static bool IsIntrinsic(MethodWrapper methodWrapper)
}
}
+
diff --git a/src/IKVM.Tools.Exporter/StubTypeWrapper.cs b/src/IKVM.Tools.Exporter/StubTypeWrapper.cs
index 7cb2053921..873a0dbf58 100644
--- a/src/IKVM.Tools.Exporter/StubTypeWrapper.cs
+++ b/src/IKVM.Tools.Exporter/StubTypeWrapper.cs
@@ -24,39 +24,44 @@ Jeroen Frijters
using System;
using IKVM.Attributes;
-using IKVM.Internal;
using Type = IKVM.Reflection.Type;
-sealed class StubTypeWrapper : TypeWrapper
+namespace IKVM.Runtime
{
- private readonly bool remapped;
- private readonly TypeWrapper baseWrapper;
- internal StubTypeWrapper(Modifiers modifiers, string name, TypeWrapper baseWrapper, bool remapped)
- : base(TypeFlags.None, modifiers, name)
+ sealed class StubTypeWrapper : TypeWrapper
{
- this.remapped = remapped;
- this.baseWrapper = baseWrapper;
- }
- internal override TypeWrapper BaseTypeWrapper
- {
- get { return baseWrapper; }
- }
+ private readonly bool remapped;
+ private readonly TypeWrapper baseWrapper;
- internal override ClassLoaderWrapper GetClassLoader()
- {
- return ClassLoaderWrapper.GetBootstrapClassLoader();
- }
+ internal StubTypeWrapper(Modifiers modifiers, string name, TypeWrapper baseWrapper, bool remapped)
+ : base(TypeFlags.None, modifiers, name)
+ {
+ this.remapped = remapped;
+ this.baseWrapper = baseWrapper;
+ }
- internal override Type TypeAsTBD
- {
- get { throw new NotSupportedException(); }
- }
+ internal override TypeWrapper BaseTypeWrapper
+ {
+ get { return baseWrapper; }
+ }
- internal override bool IsRemapped
- {
- get { return remapped; }
+ internal override ClassLoaderWrapper GetClassLoader()
+ {
+ return ClassLoaderWrapper.GetBootstrapClassLoader();
+ }
+
+ internal override Type TypeAsTBD
+ {
+ get { throw new NotSupportedException(); }
+ }
+
+ internal override bool IsRemapped
+ {
+ get { return remapped; }
+ }
}
+
}
diff --git a/src/IKVM.Tools.Importer/AotTypeWrapper.cs b/src/IKVM.Tools.Importer/AotTypeWrapper.cs
index 90f5758c64..0918b62841 100644
--- a/src/IKVM.Tools.Importer/AotTypeWrapper.cs
+++ b/src/IKVM.Tools.Importer/AotTypeWrapper.cs
@@ -26,7 +26,6 @@ Jeroen Frijters
using System.Collections.Generic;
using IKVM.Attributes;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using IKVM.Runtime;
diff --git a/src/IKVM.Tools.Importer/AssemblyResolver.cs b/src/IKVM.Tools.Importer/AssemblyResolver.cs
index 4315773afc..a227eac215 100644
--- a/src/IKVM.Tools.Importer/AssemblyResolver.cs
+++ b/src/IKVM.Tools.Importer/AssemblyResolver.cs
@@ -25,8 +25,8 @@ Jeroen Frijters
using System.Collections.Generic;
using System.IO;
-using IKVM.Internal;
using IKVM.Reflection;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer
{
diff --git a/src/IKVM.Tools.Importer/CompilerClassLoader.cs b/src/IKVM.Tools.Importer/CompilerClassLoader.cs
index 5ba606b77d..1b447887e2 100644
--- a/src/IKVM.Tools.Importer/CompilerClassLoader.cs
+++ b/src/IKVM.Tools.Importer/CompilerClassLoader.cs
@@ -35,7 +35,6 @@ Jeroen Frijters
using IKVM.Attributes;
using IKVM.ByteCode.Reading;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using IKVM.Runtime;
diff --git a/src/IKVM.Tools.Importer/FakeTypes.cs b/src/IKVM.Tools.Importer/FakeTypes.cs
index a3dec3f1a8..84b57015bc 100644
--- a/src/IKVM.Tools.Importer/FakeTypes.cs
+++ b/src/IKVM.Tools.Importer/FakeTypes.cs
@@ -21,16 +21,16 @@ Jeroen Frijters
jeroen@frijters.net
*/
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
namespace IKVM.Tools.Importer
{
- static class FakeTypes
+ static class FakeTypes
{
private static Type genericEnumEnumType;
diff --git a/src/IKVM.Tools.Importer/IkvmImporterInternal.cs b/src/IKVM.Tools.Importer/IkvmImporterInternal.cs
index af3e12a143..e84cdae0d9 100644
--- a/src/IKVM.Tools.Importer/IkvmImporterInternal.cs
+++ b/src/IKVM.Tools.Importer/IkvmImporterInternal.cs
@@ -29,7 +29,6 @@ Jeroen Frijters
using System.Threading;
using IKVM.ByteCode.Reading;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using IKVM.Runtime;
diff --git a/src/IKVM.Tools.Importer/MapXml/Beq.cs b/src/IKVM.Tools.Importer/MapXml/Beq.cs
index 7816cd31ec..3da5f40b8c 100644
--- a/src/IKVM.Tools.Importer/MapXml/Beq.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Beq.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Bge_Un.cs b/src/IKVM.Tools.Importer/MapXml/Bge_Un.cs
index 566e250848..f9025947b7 100644
--- a/src/IKVM.Tools.Importer/MapXml/Bge_Un.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Bge_Un.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ble_Un.cs b/src/IKVM.Tools.Importer/MapXml/Ble_Un.cs
index ed3e51be4b..a6e7305c12 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ble_Un.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ble_Un.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Blt.cs b/src/IKVM.Tools.Importer/MapXml/Blt.cs
index d6001e822c..57dc18ddf8 100644
--- a/src/IKVM.Tools.Importer/MapXml/Blt.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Blt.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Blt_Un.cs b/src/IKVM.Tools.Importer/MapXml/Blt_Un.cs
index 352120577a..3021f570e9 100644
--- a/src/IKVM.Tools.Importer/MapXml/Blt_Un.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Blt_Un.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Bne_Un.cs b/src/IKVM.Tools.Importer/MapXml/Bne_Un.cs
index 273321f758..757e964901 100644
--- a/src/IKVM.Tools.Importer/MapXml/Bne_Un.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Bne_Un.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Br.cs b/src/IKVM.Tools.Importer/MapXml/Br.cs
index fa302e2c21..a72e72ce3a 100644
--- a/src/IKVM.Tools.Importer/MapXml/Br.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Br.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/BrFalse.cs b/src/IKVM.Tools.Importer/MapXml/BrFalse.cs
index 0f300a8645..51da5410cf 100644
--- a/src/IKVM.Tools.Importer/MapXml/BrFalse.cs
+++ b/src/IKVM.Tools.Importer/MapXml/BrFalse.cs
@@ -23,9 +23,8 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/BrLabel.cs b/src/IKVM.Tools.Importer/MapXml/BrLabel.cs
index 55de8432db..2a693c5e3c 100644
--- a/src/IKVM.Tools.Importer/MapXml/BrLabel.cs
+++ b/src/IKVM.Tools.Importer/MapXml/BrLabel.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Xml.Linq;
using System.Xml.Serialization;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/BrTrue.cs b/src/IKVM.Tools.Importer/MapXml/BrTrue.cs
index 7cfd344ac9..886d99899d 100644
--- a/src/IKVM.Tools.Importer/MapXml/BrTrue.cs
+++ b/src/IKVM.Tools.Importer/MapXml/BrTrue.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Branch.cs b/src/IKVM.Tools.Importer/MapXml/Branch.cs
index ea0e8598e3..58c2e5d950 100644
--- a/src/IKVM.Tools.Importer/MapXml/Branch.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Branch.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Call.cs b/src/IKVM.Tools.Importer/MapXml/Call.cs
index ee7da26896..d81d15ba31 100644
--- a/src/IKVM.Tools.Importer/MapXml/Call.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Call.cs
@@ -27,9 +27,9 @@ Jeroen Frijters
using System.Linq;
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Castclass.cs b/src/IKVM.Tools.Importer/MapXml/Castclass.cs
index 5823d0be44..d7f3ff7fc1 100644
--- a/src/IKVM.Tools.Importer/MapXml/Castclass.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Castclass.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs b/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs
index 13ce89d45e..b79758e69e 100644
--- a/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Castclass_impl.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/ClassInitializer.cs b/src/IKVM.Tools.Importer/MapXml/ClassInitializer.cs
index f2948ead67..b64f8a1531 100644
--- a/src/IKVM.Tools.Importer/MapXml/ClassInitializer.cs
+++ b/src/IKVM.Tools.Importer/MapXml/ClassInitializer.cs
@@ -22,10 +22,8 @@ Jeroen Frijters
*/
-using System.Linq;
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
diff --git a/src/IKVM.Tools.Importer/MapXml/CodeGenContext.cs b/src/IKVM.Tools.Importer/MapXml/CodeGenContext.cs
index 6b351fa802..fee9cf4f26 100644
--- a/src/IKVM.Tools.Importer/MapXml/CodeGenContext.cs
+++ b/src/IKVM.Tools.Importer/MapXml/CodeGenContext.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Collections.Generic;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/ConditionalInstruction.cs b/src/IKVM.Tools.Importer/MapXml/ConditionalInstruction.cs
index ee4fb7d284..cb8100f9fa 100644
--- a/src/IKVM.Tools.Importer/MapXml/ConditionalInstruction.cs
+++ b/src/IKVM.Tools.Importer/MapXml/ConditionalInstruction.cs
@@ -26,7 +26,7 @@ Jeroen Frijters
using System.Linq;
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Constructor.cs b/src/IKVM.Tools.Importer/MapXml/Constructor.cs
index 121217834f..960f09aca6 100644
--- a/src/IKVM.Tools.Importer/MapXml/Constructor.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Constructor.cs
@@ -24,7 +24,6 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
diff --git a/src/IKVM.Tools.Importer/MapXml/EmitExceptionMapping.cs b/src/IKVM.Tools.Importer/MapXml/EmitExceptionMapping.cs
index 4ec630c3e3..e1ea480f7b 100644
--- a/src/IKVM.Tools.Importer/MapXml/EmitExceptionMapping.cs
+++ b/src/IKVM.Tools.Importer/MapXml/EmitExceptionMapping.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs b/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs
index c9556fbea4..5250df6c49 100644
--- a/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs
+++ b/src/IKVM.Tools.Importer/MapXml/ExceptionBlock.cs
@@ -24,9 +24,8 @@ Jeroen Frijters
using System.Linq;
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Instruction.cs b/src/IKVM.Tools.Importer/MapXml/Instruction.cs
index 1cf46bd2cf..1b3b09c37b 100644
--- a/src/IKVM.Tools.Importer/MapXml/Instruction.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Instruction.cs
@@ -3,7 +3,7 @@
using System.Reflection;
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/InstructionList.cs b/src/IKVM.Tools.Importer/MapXml/InstructionList.cs
index 6ffd10db88..d7fa4019d5 100644
--- a/src/IKVM.Tools.Importer/MapXml/InstructionList.cs
+++ b/src/IKVM.Tools.Importer/MapXml/InstructionList.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Linq;
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/IsInst.cs b/src/IKVM.Tools.Importer/MapXml/IsInst.cs
index 3d3f00fdca..feecfa389b 100644
--- a/src/IKVM.Tools.Importer/MapXml/IsInst.cs
+++ b/src/IKVM.Tools.Importer/MapXml/IsInst.cs
@@ -23,10 +23,9 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/LdArg_S.cs b/src/IKVM.Tools.Importer/MapXml/LdArg_S.cs
index 71a1ed4a3b..e597fc9c76 100644
--- a/src/IKVM.Tools.Importer/MapXml/LdArg_S.cs
+++ b/src/IKVM.Tools.Importer/MapXml/LdArg_S.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/LdArga.cs b/src/IKVM.Tools.Importer/MapXml/LdArga.cs
index c4fef0720d..c3d93989f9 100644
--- a/src/IKVM.Tools.Importer/MapXml/LdArga.cs
+++ b/src/IKVM.Tools.Importer/MapXml/LdArga.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/LdLoc.cs b/src/IKVM.Tools.Importer/MapXml/LdLoc.cs
index c0abf8f9c8..566a143103 100644
--- a/src/IKVM.Tools.Importer/MapXml/LdLoc.cs
+++ b/src/IKVM.Tools.Importer/MapXml/LdLoc.cs
@@ -23,10 +23,9 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldc_I4.cs b/src/IKVM.Tools.Importer/MapXml/Ldc_I4.cs
index 9fdbb23946..0c8930eed7 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldc_I4.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldc_I4.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldelema.cs b/src/IKVM.Tools.Importer/MapXml/Ldelema.cs
index d1bebcfc66..1b4688cdaa 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldelema.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldelema.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Reflection.Emit;
namespace IKVM.Tools.Importer.MapXml
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldfld.cs b/src/IKVM.Tools.Importer/MapXml/Ldfld.cs
index ae9dbb5682..e521facdec 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldfld.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldfld.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Reflection.Emit;
namespace IKVM.Tools.Importer.MapXml
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldflda.cs b/src/IKVM.Tools.Importer/MapXml/Ldflda.cs
index 4ddcf2db3c..ec778c47d5 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldflda.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldflda.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldlen.cs b/src/IKVM.Tools.Importer/MapXml/Ldlen.cs
index 2c1b6621a0..e134943bf2 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldlen.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldlen.cs
@@ -23,7 +23,6 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
using IKVM.Reflection.Emit;
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs b/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs
index 96ca7e9567..ecfca097fa 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldsfld.cs
@@ -24,9 +24,9 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldstr.cs b/src/IKVM.Tools.Importer/MapXml/Ldstr.cs
index b895fa4458..3cc6e13ce8 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldstr.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldstr.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs
index 430586cae7..a01013cca1 100644
--- a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs
@@ -24,11 +24,10 @@ Jeroen Frijters
using System;
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Leave.cs b/src/IKVM.Tools.Importer/MapXml/Leave.cs
index cbb87f7a15..c70a2a7bb6 100644
--- a/src/IKVM.Tools.Importer/MapXml/Leave.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Leave.cs
@@ -23,9 +23,8 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/MethodConstructorBase.cs b/src/IKVM.Tools.Importer/MapXml/MethodConstructorBase.cs
index dc576f7907..a9e0891eef 100644
--- a/src/IKVM.Tools.Importer/MapXml/MethodConstructorBase.cs
+++ b/src/IKVM.Tools.Importer/MapXml/MethodConstructorBase.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Linq;
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Newarr.cs b/src/IKVM.Tools.Importer/MapXml/Newarr.cs
index 44ec264757..5b3223adef 100644
--- a/src/IKVM.Tools.Importer/MapXml/Newarr.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Newarr.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
using IKVM.Reflection.Emit;
namespace IKVM.Tools.Importer.MapXml
diff --git a/src/IKVM.Tools.Importer/MapXml/Pop.cs b/src/IKVM.Tools.Importer/MapXml/Pop.cs
index 3768edcfe0..9a6ac80925 100644
--- a/src/IKVM.Tools.Importer/MapXml/Pop.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Pop.cs
@@ -23,10 +23,9 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Redirect.cs b/src/IKVM.Tools.Importer/MapXml/Redirect.cs
index b72769bc71..84df4136a1 100644
--- a/src/IKVM.Tools.Importer/MapXml/Redirect.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Redirect.cs
@@ -25,9 +25,9 @@ Jeroen Frijters
using System;
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs b/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs
index 5011c91e95..8b6a21f6c3 100644
--- a/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Rem_Un.cs
@@ -23,7 +23,6 @@ Jeroen Frijters
*/
using System.Xml.Linq;
-using System.Xml.Serialization;
using IKVM.Reflection.Emit;
diff --git a/src/IKVM.Tools.Importer/MapXml/RunClassInit.cs b/src/IKVM.Tools.Importer/MapXml/RunClassInit.cs
index 2f900dff42..0bea238ca4 100644
--- a/src/IKVM.Tools.Importer/MapXml/RunClassInit.cs
+++ b/src/IKVM.Tools.Importer/MapXml/RunClassInit.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Simple.cs b/src/IKVM.Tools.Importer/MapXml/Simple.cs
index 6e9f0ae44a..7d2a9db171 100644
--- a/src/IKVM.Tools.Importer/MapXml/Simple.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Simple.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/StLoc.cs b/src/IKVM.Tools.Importer/MapXml/StLoc.cs
index ec1fe3085c..f5bee5db70 100644
--- a/src/IKVM.Tools.Importer/MapXml/StLoc.cs
+++ b/src/IKVM.Tools.Importer/MapXml/StLoc.cs
@@ -25,8 +25,8 @@ Jeroen Frijters
using System.Diagnostics;
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Stfld.cs b/src/IKVM.Tools.Importer/MapXml/Stfld.cs
index 7adbecfd06..2f03472bde 100644
--- a/src/IKVM.Tools.Importer/MapXml/Stfld.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Stfld.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/Stsfld.cs b/src/IKVM.Tools.Importer/MapXml/Stsfld.cs
index ef37b37f96..c8a9791877 100644
--- a/src/IKVM.Tools.Importer/MapXml/Stsfld.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Stsfld.cs
@@ -24,8 +24,8 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs b/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs
index 3a04670656..e5f867038a 100644
--- a/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs
+++ b/src/IKVM.Tools.Importer/MapXml/TypeInstruction.cs
@@ -25,8 +25,8 @@ Jeroen Frijters
using System.Diagnostics;
using System.Xml.Linq;
-using IKVM.Internal;
using IKVM.Reflection.Emit;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs b/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs
index ec7583e744..defe7c2894 100644
--- a/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs
+++ b/src/IKVM.Tools.Importer/MapXml/TypeOrTypeWrapperInstruction.cs
@@ -25,7 +25,7 @@ Jeroen Frijters
using System.Diagnostics;
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
using Type = IKVM.Reflection.Type;
diff --git a/src/IKVM.Tools.Importer/MapXml/Unaligned.cs b/src/IKVM.Tools.Importer/MapXml/Unaligned.cs
index 1e84c35c1b..961cbc0aaa 100644
--- a/src/IKVM.Tools.Importer/MapXml/Unaligned.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Unaligned.cs
@@ -24,7 +24,7 @@ Jeroen Frijters
using System.Xml.Linq;
-using IKVM.Internal;
+using IKVM.Runtime;
namespace IKVM.Tools.Importer.MapXml
{
diff --git a/src/IKVM.Tools.Importer/Proxy.cs b/src/IKVM.Tools.Importer/Proxy.cs
index aec88fba97..495ace44e4 100644
--- a/src/IKVM.Tools.Importer/Proxy.cs
+++ b/src/IKVM.Tools.Importer/Proxy.cs
@@ -25,7 +25,6 @@ Jeroen Frijters
using System.Collections.Generic;
using IKVM.Attributes;
-using IKVM.Internal;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using IKVM.Runtime;
@@ -35,7 +34,7 @@ Jeroen Frijters
namespace IKVM.Tools.Importer
{
- static class ProxyGenerator
+ static class ProxyGenerator
{
private static readonly TypeWrapper proxyClass;