зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
57c81013a1
Коммит
9d6bf7d010
|
@ -484,11 +484,11 @@ class ClassFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string NetExpTypeAttribute
|
internal string NetExpAssemblyAttribute
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Attribute attr = GetAttribute("IK.VM.NET.Type");
|
Attribute attr = GetAttribute("IKVM.NET.Assembly");
|
||||||
if(attr != null)
|
if(attr != null)
|
||||||
{
|
{
|
||||||
return ((ConstantPoolItemUtf8)GetConstantPoolItem(attr.Data.ReadUInt16())).Value;
|
return ((ConstantPoolItemUtf8)GetConstantPoolItem(attr.Data.ReadUInt16())).Value;
|
||||||
|
|
|
@ -126,7 +126,7 @@ class ClassLoaderWrapper
|
||||||
this.javaClassLoader = javaClassLoader;
|
this.javaClassLoader = javaClassLoader;
|
||||||
if(javaClassLoader != null && loadClassDelegate == null)
|
if(javaClassLoader != null && loadClassDelegate == null)
|
||||||
{
|
{
|
||||||
loadClassDelegate = (LoadClassDelegate)Delegate.CreateDelegate(typeof(LoadClassDelegate), GetType("java.lang.VMClass"), "__loadClassHelper");
|
loadClassDelegate = (LoadClassDelegate)Delegate.CreateDelegate(typeof(LoadClassDelegate), GetType("java.lang.VMClass"), "loadClassHelper");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +141,11 @@ class ClassLoaderWrapper
|
||||||
return (TypeWrapper[])((ArrayList)ghosts[wrapper.Name]).ToArray(typeof(TypeWrapper));
|
return (TypeWrapper[])((ArrayList)ghosts[wrapper.Name]).ToArray(typeof(TypeWrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsRemappedType(Type type)
|
||||||
|
{
|
||||||
|
return typeToTypeWrapper[type] is RemappedTypeWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
internal void LoadRemappedTypes()
|
internal void LoadRemappedTypes()
|
||||||
{
|
{
|
||||||
nativeMethods = new Hashtable();
|
nativeMethods = new Hashtable();
|
||||||
|
@ -161,7 +166,9 @@ class ClassLoaderWrapper
|
||||||
baseWrapper = null;
|
baseWrapper = null;
|
||||||
}
|
}
|
||||||
TypeWrapper tw = new RemappedTypeWrapper(this, modifiers, name, type, new TypeWrapper[0], baseWrapper);
|
TypeWrapper tw = new RemappedTypeWrapper(this, modifiers, name, type, new TypeWrapper[0], baseWrapper);
|
||||||
|
Debug.Assert(!types.ContainsKey(name));
|
||||||
types.Add(name, tw);
|
types.Add(name, tw);
|
||||||
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(tw.Type));
|
||||||
typeToTypeWrapper.Add(tw.Type, tw);
|
typeToTypeWrapper.Add(tw.Type, tw);
|
||||||
}
|
}
|
||||||
// find the ghost interfaces
|
// find the ghost interfaces
|
||||||
|
@ -301,16 +308,44 @@ class ClassLoaderWrapper
|
||||||
Type t = Type.GetType(name);
|
Type t = Type.GetType(name);
|
||||||
if(t != null)
|
if(t != null)
|
||||||
{
|
{
|
||||||
return GetCompiledTypeWrapper(t);
|
if(t.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false))
|
||||||
|
{
|
||||||
|
return GetWrapperFromType(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// HACK weird way to load the .NET type wrapper that always works
|
||||||
|
// (for remapped types as well, because netexp uses this way of
|
||||||
|
// loading types, we need the remapped types to appear in their
|
||||||
|
// .NET "warped" form).
|
||||||
|
return LoadClassByDottedName(DotNetTypeWrapper.GetName(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO why is this check here and not at the top of the method?
|
||||||
if(name != "")
|
if(name != "")
|
||||||
{
|
{
|
||||||
type = GetBootstrapType(name);
|
Type t = GetBootstrapTypeRaw(name);
|
||||||
}
|
if(t != null)
|
||||||
if(type != null)
|
{
|
||||||
{
|
return GetWrapperFromBootstrapType(t);
|
||||||
return type;
|
}
|
||||||
|
type = DotNetTypeWrapper.LoadDotNetTypeWrapper(name);
|
||||||
|
if(type != null)
|
||||||
|
{
|
||||||
|
Debug.Assert(type.Name == name, type.Name + " != " + name);
|
||||||
|
Debug.Assert(!types.ContainsKey(name), name);
|
||||||
|
types.Add(name, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
// NOTE it is important that this is done last, because otherwise we will
|
||||||
|
// load the netexp generated fake types (e.g. delegate inner interface) instead
|
||||||
|
// of having DotNetTypeWrapper generating it.
|
||||||
|
type = GetTypeWrapperCompilerHook(name);
|
||||||
|
if(type != null)
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(javaClassLoader == null)
|
if(javaClassLoader == null)
|
||||||
{
|
{
|
||||||
|
@ -347,34 +382,45 @@ class ClassLoaderWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeWrapper GetCompiledTypeWrapper(Type type)
|
private TypeWrapper GetWrapperFromBootstrapType(Type type)
|
||||||
{
|
{
|
||||||
TypeWrapper.AssertFinished(type);
|
Debug.Assert(GetWrapperFromTypeFast(type) == null);
|
||||||
|
Debug.Assert(!type.IsArray);
|
||||||
|
Debug.Assert(!(type.Assembly is AssemblyBuilder));
|
||||||
// only the bootstrap classloader can own compiled types
|
// only the bootstrap classloader can own compiled types
|
||||||
Debug.Assert(this == GetBootstrapClassLoader());
|
Debug.Assert(this == GetBootstrapClassLoader());
|
||||||
string name = NativeCode.java.lang.VMClass.getName(type);
|
TypeWrapper wrapper = null;
|
||||||
TypeWrapper wrapper = (TypeWrapper)types[name];
|
if(type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false))
|
||||||
if(wrapper == null)
|
|
||||||
{
|
{
|
||||||
wrapper = new CompiledTypeWrapper(name, type);
|
string name = CompiledTypeWrapper.GetName(type);
|
||||||
types.Add(name, wrapper);
|
|
||||||
typeToTypeWrapper[type] = wrapper;
|
|
||||||
}
|
|
||||||
else if(wrapper is RemappedTypeWrapper)
|
|
||||||
{
|
|
||||||
// When remapped types are loaded by their original name (e.g. System.Object)
|
|
||||||
// we end up here, and we make a CompiledTypeWrapper for it that reflects on
|
|
||||||
// the original type (note that you can never encounter these types anywhere,
|
|
||||||
// except when explicitly loaded with Class.forName)
|
|
||||||
name = type.FullName;
|
|
||||||
wrapper = (TypeWrapper)types[name];
|
wrapper = (TypeWrapper)types[name];
|
||||||
if(wrapper == null)
|
if(wrapper == null)
|
||||||
{
|
{
|
||||||
// TODO instead of using CompiledTypeWrapper here, we probably should
|
// since this type was compiled from Java source, we have to look for our
|
||||||
// have a subclass that converts all instance methods to static methods (and
|
// attributes
|
||||||
// makes the class appear final with only a private constructor)
|
|
||||||
wrapper = new CompiledTypeWrapper(name, type);
|
wrapper = new CompiledTypeWrapper(name, type);
|
||||||
types.Add(name, wrapper);
|
Debug.Assert(wrapper.Name == name);
|
||||||
|
Debug.Assert(!types.ContainsKey(wrapper.Name), wrapper.Name);
|
||||||
|
types.Add(wrapper.Name, wrapper);
|
||||||
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
|
||||||
|
typeToTypeWrapper.Add(type, wrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string name = DotNetTypeWrapper.GetName(type);
|
||||||
|
wrapper = (TypeWrapper)types[name];
|
||||||
|
if(wrapper == null)
|
||||||
|
{
|
||||||
|
// since this type was not compiled from Java source, we don't need to
|
||||||
|
// look for our attributes, but we do need to filter unrepresentable
|
||||||
|
// stuff (and transform some other stuff)
|
||||||
|
wrapper = new DotNetTypeWrapper(type);
|
||||||
|
Debug.Assert(wrapper.Name == name);
|
||||||
|
Debug.Assert(!types.ContainsKey(wrapper.Name), wrapper.Name);
|
||||||
|
types.Add(wrapper.Name, wrapper);
|
||||||
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
|
||||||
|
typeToTypeWrapper.Add(type, wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -398,18 +444,11 @@ class ClassLoaderWrapper
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// HACK we also try mscorlib and this assembly (for the remapped types)
|
return null;
|
||||||
// TODO this should be fixed by making the map.xml type names for .NET types assembly qualified
|
|
||||||
return Type.GetType(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal virtual TypeWrapper GetBootstrapType(string name)
|
internal virtual TypeWrapper GetTypeWrapperCompilerHook(string name)
|
||||||
{
|
{
|
||||||
Type t = GetBootstrapTypeRaw(name);
|
|
||||||
if(t != null)
|
|
||||||
{
|
|
||||||
return GetCompiledTypeWrapper(t);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,10 +493,12 @@ class ClassLoaderWrapper
|
||||||
modifiers |= Modifiers.Public;
|
modifiers |= Modifiers.Public;
|
||||||
}
|
}
|
||||||
wrapper = new ArrayTypeWrapper(array, modifiers, name, this);
|
wrapper = new ArrayTypeWrapper(array, modifiers, name, this);
|
||||||
|
Debug.Assert(!types.ContainsKey(name));
|
||||||
types.Add(name, wrapper);
|
types.Add(name, wrapper);
|
||||||
if(!(elementType is TypeBuilder))
|
if(!(elementType is TypeBuilder))
|
||||||
{
|
{
|
||||||
typeToTypeWrapper[array] = wrapper;
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(array));
|
||||||
|
typeToTypeWrapper.Add(array, wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -510,14 +551,24 @@ class ClassLoaderWrapper
|
||||||
{
|
{
|
||||||
throw JavaException.IncompatibleClassChangeError("Class {0} has interface {1} as superclass", f.Name, baseType.Name);
|
throw JavaException.IncompatibleClassChangeError("Class {0} has interface {1} as superclass", f.Name, baseType.Name);
|
||||||
}
|
}
|
||||||
string dotnetType = f.NetExpTypeAttribute;
|
string dotnetAssembly = f.NetExpAssemblyAttribute;
|
||||||
if(dotnetType != null)
|
if(dotnetAssembly != null)
|
||||||
{
|
{
|
||||||
type = new NetExpTypeWrapper(f, dotnetType, baseType);
|
// The sole purpose of the netexp class is to let us load the assembly that the class lives in,
|
||||||
|
// once we've done that, all types in it become visible.
|
||||||
|
Assembly.Load(dotnetAssembly);
|
||||||
|
types.Remove(f.Name);
|
||||||
|
type = GetBootstrapClassLoader().LoadClassByDottedNameFast(f.Name);
|
||||||
|
if(type == null)
|
||||||
|
{
|
||||||
|
throw JavaException.NoClassDefFoundError("{0} (loaded through NetExp class)", f.Name);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = new DynamicTypeWrapper(f, this, nativeMethods);
|
type = new DynamicTypeWrapper(f, this, nativeMethods);
|
||||||
|
Debug.Assert(!dynamicTypes.ContainsKey(type.Type.FullName));
|
||||||
dynamicTypes.Add(type.Type.FullName, type);
|
dynamicTypes.Add(type.Type.FullName, type);
|
||||||
}
|
}
|
||||||
Debug.Assert(types[f.Name] == null);
|
Debug.Assert(types[f.Name] == null);
|
||||||
|
@ -856,7 +907,8 @@ class ClassLoaderWrapper
|
||||||
// if we found it, store it in the map
|
// if we found it, store it in the map
|
||||||
if(wrapper != null)
|
if(wrapper != null)
|
||||||
{
|
{
|
||||||
typeToTypeWrapper[type] = wrapper;
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
|
||||||
|
typeToTypeWrapper.Add(type, wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -880,58 +932,14 @@ class ClassLoaderWrapper
|
||||||
}
|
}
|
||||||
wrapper = GetWrapperFromType(elem);
|
wrapper = GetWrapperFromType(elem);
|
||||||
// HACK this is a lame way of creating the array wrapper
|
// HACK this is a lame way of creating the array wrapper
|
||||||
if(wrapper.IsPrimitive)
|
return wrapper.GetClassLoader().LoadClassByDottedName(new String('[', rank) + wrapper.SigName);
|
||||||
{
|
|
||||||
string elemType;
|
|
||||||
if(wrapper == PrimitiveTypeWrapper.BYTE)
|
|
||||||
{
|
|
||||||
elemType = "B";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.BOOLEAN)
|
|
||||||
{
|
|
||||||
elemType = "Z";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.SHORT)
|
|
||||||
{
|
|
||||||
elemType = "S";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.CHAR)
|
|
||||||
{
|
|
||||||
elemType = "C";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.INT)
|
|
||||||
{
|
|
||||||
elemType = "I";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.LONG)
|
|
||||||
{
|
|
||||||
elemType = "J";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.FLOAT)
|
|
||||||
{
|
|
||||||
elemType = "F";
|
|
||||||
}
|
|
||||||
else if(wrapper == PrimitiveTypeWrapper.DOUBLE)
|
|
||||||
{
|
|
||||||
elemType = "D";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
return wrapper.GetClassLoader().LoadClassByDottedName(new String('[', rank) + elemType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return wrapper.GetClassLoader().LoadClassByDottedName(new String('[', rank) + "L" + wrapper.Name + ";");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// if the wrapper doesn't already exist, that must mean that the type
|
// if the wrapper doesn't already exist, that must mean that the type
|
||||||
// is a .NET type (or a pre-compiled Java class), which means that it
|
// is a .NET type (or a pre-compiled Java class), which means that it
|
||||||
// was "loaded" by the bootstrap classloader
|
// was "loaded" by the bootstrap classloader
|
||||||
// TODO think up a scheme to deal with .NET types that have the same name. Since all .NET types
|
// TODO think up a scheme to deal with .NET types that have the same name. Since all .NET types
|
||||||
// appear in the boostrap classloader, we need to devise a scheme to mangle the class name
|
// appear in the boostrap classloader, we need to devise a scheme to mangle the class name
|
||||||
return GetBootstrapClassLoader().GetCompiledTypeWrapper(type);
|
return GetBootstrapClassLoader().GetWrapperFromBootstrapType(type);
|
||||||
}
|
}
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
@ -939,6 +947,7 @@ class ClassLoaderWrapper
|
||||||
internal static void SetWrapperForType(Type type, TypeWrapper wrapper)
|
internal static void SetWrapperForType(Type type, TypeWrapper wrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper.AssertFinished(type);
|
TypeWrapper.AssertFinished(type);
|
||||||
|
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
|
||||||
typeToTypeWrapper.Add(type, wrapper);
|
typeToTypeWrapper.Add(type, wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ public abstract class CodeEmitter
|
||||||
{
|
{
|
||||||
return new CodeEmitter.OpCodeEmitter(OpCodes.Ldnull);
|
return new CodeEmitter.OpCodeEmitter(OpCodes.Ldnull);
|
||||||
}
|
}
|
||||||
else if(constant is int || constant is uint ||
|
else if(constant is int ||
|
||||||
constant is short || constant is ushort ||
|
constant is short || constant is ushort ||
|
||||||
constant is byte || constant is sbyte ||
|
constant is byte || constant is sbyte ||
|
||||||
constant is char ||
|
constant is char ||
|
||||||
|
@ -159,6 +159,10 @@ public abstract class CodeEmitter
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||||
}
|
}
|
||||||
|
else if(constant is uint)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
|
||||||
|
}
|
||||||
else if(constant is string)
|
else if(constant is string)
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldstr, (string)constant);
|
return CodeEmitter.Create(OpCodes.Ldstr, (string)constant);
|
||||||
|
@ -171,17 +175,29 @@ public abstract class CodeEmitter
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldc_R8, (double)constant);
|
return CodeEmitter.Create(OpCodes.Ldc_R8, (double)constant);
|
||||||
}
|
}
|
||||||
else if(constant is long || constant is ulong)
|
else if(constant is long)
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldc_I8, (long)constant);
|
return CodeEmitter.Create(OpCodes.Ldc_I8, (long)constant);
|
||||||
}
|
}
|
||||||
|
else if(constant is ulong)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
|
||||||
|
}
|
||||||
else if(constant is Enum)
|
else if(constant is Enum)
|
||||||
{
|
{
|
||||||
Type underlying = Enum.GetUnderlyingType(constant.GetType());
|
Type underlying = Enum.GetUnderlyingType(constant.GetType());
|
||||||
if(underlying == typeof(long) || underlying == typeof(ulong))
|
if(underlying == typeof(long))
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldc_I8, ((IConvertible)constant).ToInt64(null));
|
return CodeEmitter.Create(OpCodes.Ldc_I8, ((IConvertible)constant).ToInt64(null));
|
||||||
}
|
}
|
||||||
|
if(underlying == typeof(ulong))
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I8, unchecked((long)((IConvertible)constant).ToUInt64(null)));
|
||||||
|
}
|
||||||
|
else if(underlying == typeof(uint))
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||||
|
|
|
@ -531,8 +531,9 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
internal readonly CodeEmitter EmitSet;
|
internal readonly CodeEmitter EmitSet;
|
||||||
private FieldInfo field;
|
private FieldInfo field;
|
||||||
private TypeWrapper fieldType;
|
private TypeWrapper fieldType;
|
||||||
|
private static System.Collections.Hashtable warnOnce;
|
||||||
|
|
||||||
private FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, CodeEmitter emitGet, CodeEmitter emitSet)
|
private FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, CodeEmitter emitGet, CodeEmitter emitSet)
|
||||||
: base(declaringType, modifiers, false)
|
: base(declaringType, modifiers, false)
|
||||||
{
|
{
|
||||||
Debug.Assert(fieldType != null);
|
Debug.Assert(fieldType != null);
|
||||||
|
@ -543,10 +544,48 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.sig = sig;
|
this.sig = sig;
|
||||||
this.fieldType = fieldType;
|
this.fieldType = fieldType;
|
||||||
|
this.field = field;
|
||||||
this.EmitGet = emitGet;
|
this.EmitGet = emitGet;
|
||||||
this.EmitSet = emitSet;
|
this.EmitSet = emitSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK used (indirectly thru NativeCode.java.lang.Field.getConstant) by netexp to find out if the
|
||||||
|
// field is a constant (and if it is its value)
|
||||||
|
internal object GetConstant()
|
||||||
|
{
|
||||||
|
// NOTE only pritimives and string can be literals in Java (because the other "primitives" (like uint),
|
||||||
|
// are treated as NonPrimitiveValueTypes)
|
||||||
|
TypeWrapper java_lang_String = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName("java.lang.String");
|
||||||
|
if(field != null && (fieldType.IsPrimitive || fieldType == java_lang_String) && field.IsLiteral)
|
||||||
|
{
|
||||||
|
// NOTE .NET BUG this causes the type initializer to run and we don't want that.
|
||||||
|
// TODO may need to find a workaround, for now we just spit out a warning (only shows up during netexp)
|
||||||
|
if(field.DeclaringType.TypeInitializer != null)
|
||||||
|
{
|
||||||
|
// HACK lame way to support a command line switch to suppress this warning
|
||||||
|
if(Environment.CommandLine.IndexOf("-noTypeInitWarning") == -1)
|
||||||
|
{
|
||||||
|
if(warnOnce == null)
|
||||||
|
{
|
||||||
|
warnOnce = new System.Collections.Hashtable();
|
||||||
|
}
|
||||||
|
if(!warnOnce.ContainsKey(field.DeclaringType.FullName))
|
||||||
|
{
|
||||||
|
warnOnce.Add(field.DeclaringType.FullName, null);
|
||||||
|
Console.WriteLine("Warning: Running type initializer for {0} due to .NET bug", field.DeclaringType.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object val = field.GetValue(null);
|
||||||
|
if(val != null && !(val is string))
|
||||||
|
{
|
||||||
|
return NativeCode.java.lang.reflect.JavaWrapper.Box(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
internal static FieldWrapper FromCookie(IntPtr cookie)
|
internal static FieldWrapper FromCookie(IntPtr cookie)
|
||||||
{
|
{
|
||||||
return (FieldWrapper)FromCookieImpl(cookie);
|
return (FieldWrapper)FromCookieImpl(cookie);
|
||||||
|
@ -679,9 +718,9 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, CodeEmitter getter, CodeEmitter setter)
|
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo fi, CodeEmitter getter, CodeEmitter setter)
|
||||||
{
|
{
|
||||||
return new FieldWrapper(declaringType, fieldType, name, sig, modifiers, getter, setter);
|
return new FieldWrapper(declaringType, fieldType, name, sig, modifiers, fi, getter, setter);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string sig, Modifiers modifiers)
|
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string sig, Modifiers modifiers)
|
||||||
|
@ -697,7 +736,7 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
emitGet += CodeEmitter.NoClassDefFoundError(fieldType.Name);
|
emitGet += CodeEmitter.NoClassDefFoundError(fieldType.Name);
|
||||||
emitSet += CodeEmitter.NoClassDefFoundError(fieldType.Name);
|
emitSet += CodeEmitter.NoClassDefFoundError(fieldType.Name);
|
||||||
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, emitGet, emitSet);
|
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, fi, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
if(fieldType.IsNonPrimitiveValueType)
|
if(fieldType.IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
|
@ -712,7 +751,7 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
// TODO shouldn't we use += here (for volatile fields inside of value types)?
|
// TODO shouldn't we use += here (for volatile fields inside of value types)?
|
||||||
emitGet = new VolatileLongDoubleGetter(fi);
|
emitGet = new VolatileLongDoubleGetter(fi);
|
||||||
emitSet = new VolatileLongDoubleSetter(fi);
|
emitSet = new VolatileLongDoubleSetter(fi);
|
||||||
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, emitGet, emitSet);
|
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, fi, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
emitGet += CodeEmitter.Volatile;
|
emitGet += CodeEmitter.Volatile;
|
||||||
emitSet += CodeEmitter.Volatile;
|
emitSet += CodeEmitter.Volatile;
|
||||||
|
@ -731,7 +770,7 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
emitGet += CodeEmitter.Create(OpCodes.Box, fieldType.Type);
|
emitGet += CodeEmitter.Create(OpCodes.Box, fieldType.Type);
|
||||||
}
|
}
|
||||||
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, emitGet, emitSet);
|
return new FieldWrapper(declaringType, fieldType, fi.Name, sig, modifiers, fi, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LookupField()
|
private void LookupField()
|
||||||
|
@ -751,7 +790,7 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
internal void SetValue(object obj, object val)
|
internal void SetValue(object obj, object val)
|
||||||
{
|
{
|
||||||
// TODO this is a broken implementation (for one thing, it needs to support redirection)
|
// TODO this is a broken implementation (for one thing, it needs to support redirection)
|
||||||
if(field == null)
|
if(field == null || field is FieldBuilder)
|
||||||
{
|
{
|
||||||
LookupField();
|
LookupField();
|
||||||
}
|
}
|
||||||
|
@ -761,7 +800,7 @@ sealed class FieldWrapper : MemberWrapper
|
||||||
internal object GetValue(object obj)
|
internal object GetValue(object obj)
|
||||||
{
|
{
|
||||||
// TODO this is a broken implementation (for one thing, it needs to support redirection)
|
// TODO this is a broken implementation (for one thing, it needs to support redirection)
|
||||||
if(field == null)
|
if(field == null || field is FieldBuilder)
|
||||||
{
|
{
|
||||||
LookupField();
|
LookupField();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ sealed class MethodDescriptor
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodDescriptor(ClassLoaderWrapper classLoader, string name, string sig, TypeWrapper[] args, TypeWrapper ret)
|
internal MethodDescriptor(ClassLoaderWrapper classLoader, string name, string sig, TypeWrapper[] args, TypeWrapper ret)
|
||||||
{
|
{
|
||||||
Debug.Assert(classLoader != null);
|
Debug.Assert(classLoader != null);
|
||||||
// class name in the sig should be dotted
|
// class name in the sig should be dotted
|
||||||
|
@ -178,6 +178,11 @@ sealed class MethodDescriptor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if(type.IsByRef)
|
||||||
|
{
|
||||||
|
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
|
||||||
|
// TODO test type for unsupported types
|
||||||
|
}
|
||||||
name = GetSigNameFromType(type);
|
name = GetSigNameFromType(type);
|
||||||
typeWrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
typeWrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +305,8 @@ sealed class MethodDescriptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO ensure that FromMethodBase is only used on statically compiled Java types, and
|
||||||
|
// remove support for ByRef
|
||||||
internal static MethodDescriptor FromMethodBase(MethodBase mb)
|
internal static MethodDescriptor FromMethodBase(MethodBase mb)
|
||||||
{
|
{
|
||||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||||
|
@ -348,6 +355,7 @@ class EmitHelper
|
||||||
|
|
||||||
internal static void RunClassConstructor(ILGenerator ilgen, Type type)
|
internal static void RunClassConstructor(ILGenerator ilgen, Type type)
|
||||||
{
|
{
|
||||||
|
// TODO RunClassConstructor requires full trust, so we need to use a different mechanism...
|
||||||
ilgen.Emit(OpCodes.Ldtoken, type);
|
ilgen.Emit(OpCodes.Ldtoken, type);
|
||||||
ilgen.Emit(OpCodes.Call, typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("RunClassConstructor"));
|
ilgen.Emit(OpCodes.Call, typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("RunClassConstructor"));
|
||||||
}
|
}
|
||||||
|
@ -436,7 +444,7 @@ class AttributeHelper
|
||||||
}
|
}
|
||||||
// NOTE Java doesn't support non-virtual methods, but we set the Final modifier for
|
// NOTE Java doesn't support non-virtual methods, but we set the Final modifier for
|
||||||
// non-virtual methods to approximate the semantics
|
// non-virtual methods to approximate the semantics
|
||||||
if(mb.IsFinal || (!mb.IsStatic && !mb.IsVirtual && !mb.IsConstructor))
|
if((mb.IsFinal || !mb.IsVirtual) && !mb.IsStatic && !mb.IsConstructor)
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Final;
|
modifiers |= Modifiers.Final;
|
||||||
}
|
}
|
||||||
|
@ -444,14 +452,20 @@ class AttributeHelper
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Abstract;
|
modifiers |= Modifiers.Abstract;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Some .NET interfaces (like System._AppDomain) have synchronized methods,
|
||||||
|
// Java doesn't allow synchronized on an abstract methods, so we ignore it for
|
||||||
|
// abstract methods.
|
||||||
|
if((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0)
|
||||||
|
{
|
||||||
|
modifiers |= Modifiers.Synchronized;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(mb.IsStatic)
|
if(mb.IsStatic)
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Static;
|
modifiers |= Modifiers.Static;
|
||||||
}
|
}
|
||||||
if((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0)
|
|
||||||
{
|
|
||||||
modifiers |= Modifiers.Synchronized;
|
|
||||||
}
|
|
||||||
if((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
|
if((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Native;
|
modifiers |= Modifiers.Native;
|
||||||
|
@ -597,6 +611,15 @@ class AttributeHelper
|
||||||
CustomAttributeBuilder attrib = new CustomAttributeBuilder(typeof(UnloadableTypeAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { name });
|
CustomAttributeBuilder attrib = new CustomAttributeBuilder(typeof(UnloadableTypeAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { name });
|
||||||
field.SetCustomAttribute(attrib);
|
field.SetCustomAttribute(attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void SetInnerClass(TypeBuilder typeBuilder, string innerClass, string outerClass, string name, Modifiers modifiers)
|
||||||
|
{
|
||||||
|
Type[] argTypes = new Type[] { typeof(string), typeof(string), typeof(string), typeof(Modifiers) };
|
||||||
|
object[] args = new object[] { innerClass, outerClass, name, modifiers };
|
||||||
|
ConstructorInfo ci = typeof(InnerClassAttribute).GetConstructor(argTypes);
|
||||||
|
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(ci, args);
|
||||||
|
typeBuilder.SetCustomAttribute(customAttributeBuilder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TypeWrapper
|
abstract class TypeWrapper
|
||||||
|
@ -861,6 +884,15 @@ abstract class TypeWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the name of the type as it appears in a Java signature string (e.g. "Ljava.lang.Object;" or "I")
|
||||||
|
internal virtual string SigName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "L" + this.Name + ";";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal string PackageName
|
internal string PackageName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -1361,22 +1393,32 @@ class UnloadableTypeWrapper : TypeWrapper
|
||||||
|
|
||||||
class PrimitiveTypeWrapper : TypeWrapper
|
class PrimitiveTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(sbyte));
|
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(sbyte), "B");
|
||||||
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(typeof(char));
|
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(typeof(char), "C");
|
||||||
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double));
|
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double), "D");
|
||||||
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float));
|
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float), "F");
|
||||||
internal static readonly PrimitiveTypeWrapper INT = new PrimitiveTypeWrapper(typeof(int));
|
internal static readonly PrimitiveTypeWrapper INT = new PrimitiveTypeWrapper(typeof(int), "I");
|
||||||
internal static readonly PrimitiveTypeWrapper LONG = new PrimitiveTypeWrapper(typeof(long));
|
internal static readonly PrimitiveTypeWrapper LONG = new PrimitiveTypeWrapper(typeof(long), "J");
|
||||||
internal static readonly PrimitiveTypeWrapper SHORT = new PrimitiveTypeWrapper(typeof(short));
|
internal static readonly PrimitiveTypeWrapper SHORT = new PrimitiveTypeWrapper(typeof(short), "S");
|
||||||
internal static readonly PrimitiveTypeWrapper BOOLEAN = new PrimitiveTypeWrapper(typeof(bool));
|
internal static readonly PrimitiveTypeWrapper BOOLEAN = new PrimitiveTypeWrapper(typeof(bool), "Z");
|
||||||
internal static readonly PrimitiveTypeWrapper VOID = new PrimitiveTypeWrapper(typeof(void));
|
internal static readonly PrimitiveTypeWrapper VOID = new PrimitiveTypeWrapper(typeof(void), "V");
|
||||||
|
|
||||||
private readonly Type type;
|
private readonly Type type;
|
||||||
|
private readonly string sigName;
|
||||||
|
|
||||||
private PrimitiveTypeWrapper(Type type)
|
private PrimitiveTypeWrapper(Type type, string sigName)
|
||||||
: base(Modifiers.Public | Modifiers.Abstract | Modifiers.Final, null, null, null)
|
: base(Modifiers.Public | Modifiers.Abstract | Modifiers.Final, null, null, null)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.sigName = sigName;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override string SigName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return sigName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override ClassLoaderWrapper GetClassLoader()
|
internal override ClassLoaderWrapper GetClassLoader()
|
||||||
|
@ -1721,16 +1763,11 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass, wrapper.GetClassLoader());
|
declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass, wrapper.GetClassLoader());
|
||||||
reflectiveModifiers = innerclasses[i].accessFlags;
|
reflectiveModifiers = innerclasses[i].accessFlags;
|
||||||
Type[] argTypes = new Type[] { typeof(string), typeof(string), typeof(string), typeof(Modifiers) };
|
AttributeHelper.SetInnerClass(typeBuilder,
|
||||||
object[] args = new object[] {
|
|
||||||
classFile.GetConstantPoolClass(innerclasses[i].innerClass),
|
classFile.GetConstantPoolClass(innerclasses[i].innerClass),
|
||||||
classFile.GetConstantPoolClass(innerclasses[i].outerClass),
|
classFile.GetConstantPoolClass(innerclasses[i].outerClass),
|
||||||
innerclasses[i].name == 0 ? null : classFile.GetConstantPoolUtf8String(innerclasses[i].name),
|
innerclasses[i].name == 0 ? null : classFile.GetConstantPoolUtf8String(innerclasses[i].name),
|
||||||
reflectiveModifiers
|
reflectiveModifiers);
|
||||||
};
|
|
||||||
ConstructorInfo ci = typeof(InnerClassAttribute).GetConstructor(argTypes);
|
|
||||||
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(ci, args);
|
|
||||||
typeBuilder.SetCustomAttribute(customAttributeBuilder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2227,7 +2264,7 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
// when non-blank final fields are updated, the JIT normally doesn't see that (because the
|
// when non-blank final fields are updated, the JIT normally doesn't see that (because the
|
||||||
// constant value is inlined), so we emulate that behavior by emitting a Pop
|
// constant value is inlined), so we emulate that behavior by emitting a Pop
|
||||||
CodeEmitter emitSet = CodeEmitter.Pop;
|
CodeEmitter emitSet = CodeEmitter.Pop;
|
||||||
fields[i] = FieldWrapper.Create(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, emitGet, emitSet);
|
fields[i] = FieldWrapper.Create(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, field, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2292,7 +2329,7 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
emitSet += CodeEmitter.Create(OpCodes.Stfld, field);
|
emitSet += CodeEmitter.Create(OpCodes.Stfld, field);
|
||||||
}
|
}
|
||||||
fields[i] = FieldWrapper.Create(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, emitGet, emitSet);
|
fields[i] = FieldWrapper.Create(wrapper, fld.GetFieldType(wrapper.GetClassLoader()), fld.Name, fld.Signature, fld.Modifiers, field, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3232,7 +3269,7 @@ class RemappedTypeWrapper : TypeWrapper
|
||||||
}
|
}
|
||||||
CodeEmitter setter = CodeEmitter.Throw("java.lang.IllegalAccessError", "Redirected field " + this.Name + "." + fieldName + " is read-only");
|
CodeEmitter setter = CodeEmitter.Throw("java.lang.IllegalAccessError", "Redirected field " + this.Name + "." + fieldName + " is read-only");
|
||||||
// HACK we abuse RetTypeWrapperFromSig
|
// HACK we abuse RetTypeWrapperFromSig
|
||||||
FieldWrapper fw = FieldWrapper.Create(this, GetClassLoader().RetTypeWrapperFromSig("()" + fieldSig), fieldName, fieldSig, modifiers, getter, setter);
|
FieldWrapper fw = FieldWrapper.Create(this, GetClassLoader().RetTypeWrapperFromSig("()" + fieldSig), fieldName, fieldSig, modifiers, null, getter, setter);
|
||||||
AddField(fw);
|
AddField(fw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3515,199 +3552,31 @@ class RemappedTypeWrapper : TypeWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetExpTypeWrapper : TypeWrapper
|
// TODO CompiledTypeWrapper & DotNetTypeWrapper should have a common base class
|
||||||
{
|
|
||||||
private readonly ClassFile classFile;
|
|
||||||
private readonly Type type;
|
|
||||||
|
|
||||||
// TODO consider constructing modifiers from .NET type instead of the netexp class
|
|
||||||
public NetExpTypeWrapper(ClassFile f, string dotnetType, TypeWrapper baseType)
|
|
||||||
: base(f.Modifiers, f.Name, baseType, ClassLoaderWrapper.GetBootstrapClassLoader())
|
|
||||||
{
|
|
||||||
this.classFile = f;
|
|
||||||
// TODO if the type isn't found, it should be handled differently
|
|
||||||
type = Type.GetType(dotnetType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeWrapper[] Interfaces
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// TODO resolve the interfaces!
|
|
||||||
return TypeWrapper.EmptyArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeWrapper[] InnerClasses
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// TODO resolve the inner classes!
|
|
||||||
return TypeWrapper.EmptyArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeWrapper DeclaringTypeWrapper
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// TODO resolve the outer class!
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override FieldWrapper GetFieldImpl(string fieldName)
|
|
||||||
{
|
|
||||||
// HACK this is a totally broken quick & dirty implementation
|
|
||||||
// TODO clean this up, add error checking and whatnot
|
|
||||||
FieldInfo field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
|
||||||
if(!AttributeHelper.IsHideFromReflection(field))
|
|
||||||
{
|
|
||||||
return FieldWrapper.Create(this, ClassLoaderWrapper.GetWrapperFromType(field.FieldType), field, MethodDescriptor.GetFieldSigName(field), AttributeHelper.GetModifiers(field));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DelegateConstructorEmitter : CodeEmitter
|
|
||||||
{
|
|
||||||
private ConstructorInfo delegateConstructor;
|
|
||||||
private MethodInfo method;
|
|
||||||
|
|
||||||
internal DelegateConstructorEmitter(ConstructorInfo delegateConstructor, MethodInfo method)
|
|
||||||
{
|
|
||||||
this.delegateConstructor = delegateConstructor;
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void Emit(ILGenerator ilgen)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Dup);
|
|
||||||
ilgen.Emit(OpCodes.Ldvirtftn, method);
|
|
||||||
ilgen.Emit(OpCodes.Newobj, delegateConstructor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RefArgConverter : CodeEmitter
|
|
||||||
{
|
|
||||||
private Type[] args;
|
|
||||||
|
|
||||||
internal RefArgConverter(Type[] args)
|
|
||||||
{
|
|
||||||
this.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void Emit(ILGenerator ilgen)
|
|
||||||
{
|
|
||||||
LocalBuilder[] locals = new LocalBuilder[args.Length];
|
|
||||||
for(int i = args.Length - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
Type type = args[i];
|
|
||||||
if(type.IsByRef)
|
|
||||||
{
|
|
||||||
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
|
|
||||||
}
|
|
||||||
locals[i] = ilgen.DeclareLocal(type);
|
|
||||||
ilgen.Emit(OpCodes.Stloc, locals[i]);
|
|
||||||
}
|
|
||||||
for(int i = 0; i < args.Length; i++)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Ldloc, locals[i]);
|
|
||||||
if(args[i].IsByRef)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Ldc_I4_0);
|
|
||||||
ilgen.Emit(OpCodes.Ldelema, args[i].GetElementType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override MethodWrapper GetMethodImpl(MethodDescriptor md)
|
|
||||||
{
|
|
||||||
// special case for delegate constructors!
|
|
||||||
if(md.Name == "<init>" && type.IsSubclassOf(typeof(MulticastDelegate)))
|
|
||||||
{
|
|
||||||
// TODO set method flags
|
|
||||||
MethodWrapper method = new MethodWrapper(this, md, null, null, Modifiers.Public, false);
|
|
||||||
// TODO what class loader should we use?
|
|
||||||
TypeWrapper iface = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(classFile.Name + "$Method");
|
|
||||||
iface.Finish();
|
|
||||||
method.EmitNewobj = new DelegateConstructorEmitter(type.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }), iface.Type.GetMethod("Invoke"));
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
// HACK this is a totally broken quick & dirty implementation
|
|
||||||
// TODO clean this up, add error checking and whatnot
|
|
||||||
ClassFile.Method[] methods = classFile.Methods;
|
|
||||||
for(int i = 0; i < methods.Length; i++)
|
|
||||||
{
|
|
||||||
if(methods[i].Name == md.Name && methods[i].Signature == md.Signature)
|
|
||||||
{
|
|
||||||
bool hasByRefArgs = false;
|
|
||||||
Type[] args;
|
|
||||||
string[] sig = methods[i].NetExpSigAttribute;
|
|
||||||
if(sig == null)
|
|
||||||
{
|
|
||||||
args = md.ArgTypes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
args = new Type[sig.Length];
|
|
||||||
for(int j = 0; j < sig.Length; j++)
|
|
||||||
{
|
|
||||||
args[j] = Type.GetType(sig[j], true);
|
|
||||||
if(args[j].IsByRef)
|
|
||||||
{
|
|
||||||
hasByRefArgs = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MethodBase method;
|
|
||||||
if(md.Name == "<init>")
|
|
||||||
{
|
|
||||||
method = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, args, null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
method = type.GetMethod(md.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, null, CallingConventions.Standard, args, null);
|
|
||||||
}
|
|
||||||
if(method != null)
|
|
||||||
{
|
|
||||||
// TODO we can decode the actual method attributes, or we can use them from the NetExp class, what is
|
|
||||||
// preferred?
|
|
||||||
MethodWrapper mw = MethodWrapper.Create(this, md, method, method, AttributeHelper.GetModifiers(method), AttributeHelper.IsHideFromReflection(method));
|
|
||||||
if(hasByRefArgs)
|
|
||||||
{
|
|
||||||
mw.EmitCall = new RefArgConverter(args) + mw.EmitCall;
|
|
||||||
mw.EmitCallvirt = new RefArgConverter(args) + mw.EmitCallvirt;
|
|
||||||
mw.EmitNewobj = new RefArgConverter(args) + mw.EmitNewobj;
|
|
||||||
}
|
|
||||||
return mw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Type Type
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Finish()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CompiledTypeWrapper : TypeWrapper
|
class CompiledTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
private readonly Type type;
|
private readonly Type type;
|
||||||
private TypeWrapper[] interfaces;
|
private TypeWrapper[] interfaces;
|
||||||
private TypeWrapper[] innerclasses;
|
private TypeWrapper[] innerclasses;
|
||||||
|
|
||||||
|
internal static string GetName(Type type)
|
||||||
|
{
|
||||||
|
Debug.Assert(type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false));
|
||||||
|
if(type.IsDefined(typeof(HideFromReflectionAttribute), false))
|
||||||
|
{
|
||||||
|
return ClassLoaderWrapper.GetWrapperFromType(type.BaseType).Name;
|
||||||
|
}
|
||||||
|
// look for our custom attribute, that contains the real name of the type (for inner classes)
|
||||||
|
Object[] attribs = type.GetCustomAttributes(typeof(InnerClassAttribute), false);
|
||||||
|
if(attribs.Length == 1)
|
||||||
|
{
|
||||||
|
return ((InnerClassAttribute)attribs[0]).InnerClassName;
|
||||||
|
}
|
||||||
|
return type.FullName;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO consider resolving the baseType lazily
|
// TODO consider resolving the baseType lazily
|
||||||
private static TypeWrapper GetBaseTypeWrapper(Type type)
|
internal static TypeWrapper GetBaseTypeWrapper(Type type)
|
||||||
{
|
{
|
||||||
if(type.IsInterface)
|
if(type.IsInterface)
|
||||||
{
|
{
|
||||||
|
@ -3727,12 +3596,15 @@ class CompiledTypeWrapper : TypeWrapper
|
||||||
internal CompiledTypeWrapper(string name, Type type)
|
internal CompiledTypeWrapper(string name, Type type)
|
||||||
: base(GetModifiers(type), name, GetBaseTypeWrapper(type), ClassLoaderWrapper.GetBootstrapClassLoader())
|
: base(GetModifiers(type), name, GetBaseTypeWrapper(type), ClassLoaderWrapper.GetBootstrapClassLoader())
|
||||||
{
|
{
|
||||||
|
Debug.Assert(!type.IsDefined(typeof(HideFromReflectionAttribute), false));
|
||||||
Debug.Assert(!(type is TypeBuilder));
|
Debug.Assert(!(type is TypeBuilder));
|
||||||
Debug.Assert(!type.IsArray);
|
Debug.Assert(!type.IsArray);
|
||||||
|
Debug.Assert(!ClassLoaderWrapper.IsRemappedType(type));
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Modifiers GetModifiers(Type type)
|
internal static Modifiers GetModifiers(Type type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -3922,7 +3794,7 @@ class CompiledTypeWrapper : TypeWrapper
|
||||||
emitSet = CodeEmitter.Nop;
|
emitSet = CodeEmitter.Nop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FieldWrapper.Create(this, ClassLoaderWrapper.GetWrapperFromType(fieldType), name, MethodDescriptor.GetFieldSigName(field), modifiers, emitGet, emitSet);
|
return FieldWrapper.Create(this, ClassLoaderWrapper.GetWrapperFromType(fieldType), name, MethodDescriptor.GetFieldSigName(field), modifiers, field, emitGet, emitSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override FieldWrapper GetFieldImpl(string fieldName)
|
protected override FieldWrapper GetFieldImpl(string fieldName)
|
||||||
|
@ -4071,6 +3943,555 @@ class CompiledTypeWrapper : TypeWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DotNetTypeWrapper : TypeWrapper
|
||||||
|
{
|
||||||
|
private const string NamePrefix = "cli.";
|
||||||
|
private const string DelegateInterfaceSuffix = "$Method";
|
||||||
|
private readonly Type type;
|
||||||
|
private bool membersPublished;
|
||||||
|
private TypeWrapper[] innerClasses;
|
||||||
|
private TypeWrapper outerClass;
|
||||||
|
|
||||||
|
private static Modifiers GetModifiers(Type type)
|
||||||
|
{
|
||||||
|
Modifiers mods = CompiledTypeWrapper.GetModifiers(type);
|
||||||
|
if(ClassLoaderWrapper.IsRemappedType(type) && !type.IsInterface)
|
||||||
|
{
|
||||||
|
mods |= Modifiers.Final;
|
||||||
|
}
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE when this is called on a remapped type, the "warped" underlying type name is returned.
|
||||||
|
// E.g. GetName(typeof(object)) returns "cli.System.Object".
|
||||||
|
internal static string GetName(Type type)
|
||||||
|
{
|
||||||
|
Debug.Assert(!type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false), type.FullName);
|
||||||
|
|
||||||
|
// TODO a fully reversible name mangling should be used (all characters not supported by Java should be escaped)
|
||||||
|
return NamePrefix + type.FullName.Replace('+', '$');
|
||||||
|
}
|
||||||
|
|
||||||
|
// this method should only be called once for each name, it doesn't do any caching or duplicate prevention
|
||||||
|
internal static TypeWrapper LoadDotNetTypeWrapper(string name)
|
||||||
|
{
|
||||||
|
if(name.StartsWith(NamePrefix))
|
||||||
|
{
|
||||||
|
name = name.Substring(NamePrefix.Length);
|
||||||
|
Type type = LoadTypeFromLoadedAssemblies(name);
|
||||||
|
if(type != null)
|
||||||
|
{
|
||||||
|
return new DotNetTypeWrapper(type);
|
||||||
|
}
|
||||||
|
if(name.EndsWith(DelegateInterfaceSuffix))
|
||||||
|
{
|
||||||
|
Type delegateType = LoadTypeFromLoadedAssemblies(name.Substring(0, name.Length - DelegateInterfaceSuffix.Length));
|
||||||
|
if(delegateType.IsSubclassOf(typeof(Delegate)))
|
||||||
|
{
|
||||||
|
ModuleBuilder moduleBuilder = ClassLoaderWrapper.GetBootstrapClassLoader().ModuleBuilder;
|
||||||
|
TypeBuilder typeBuilder = moduleBuilder.DefineType(NamePrefix + name, TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract);
|
||||||
|
AttributeHelper.SetInnerClass(typeBuilder, NamePrefix + name, NamePrefix + delegateType.FullName, "Method", Modifiers.Public | Modifiers.Interface | Modifiers.Static | Modifiers.Abstract);
|
||||||
|
MethodInfo invoke = delegateType.GetMethod("Invoke");
|
||||||
|
if(invoke != null)
|
||||||
|
{
|
||||||
|
ParameterInfo[] parameters = invoke.GetParameters();
|
||||||
|
Type[] args = new Type[parameters.Length];
|
||||||
|
for(int i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
// HACK if the delegate has pointer args, we cannot handle them, but it is already
|
||||||
|
// to late to refuse to load the class, so we replace pointers with IntPtr.
|
||||||
|
// This is not a solution, because if the delegate would be instantiated the generated
|
||||||
|
// code would be invalid.
|
||||||
|
if(parameters[i].ParameterType.IsPointer)
|
||||||
|
{
|
||||||
|
args[i] = typeof(IntPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args[i] = parameters[i].ParameterType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, CallingConventions.Standard, invoke.ReturnType, args);
|
||||||
|
return new CompiledTypeWrapper(NamePrefix + name, typeBuilder.CreateType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type LoadTypeFromLoadedAssemblies(string name)
|
||||||
|
{
|
||||||
|
foreach(Assembly a in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
// HACK we also look inside Java assemblies, because precompiled delegate interfaces might have ended up there
|
||||||
|
if(!(a is AssemblyBuilder))
|
||||||
|
{
|
||||||
|
Type t = a.GetType(name);
|
||||||
|
if(t != null)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
// HACK we might be looking for an inner classes
|
||||||
|
t = a.GetType(name.Replace('$', '+'));
|
||||||
|
if(t != null)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DotNetTypeWrapper(Type type)
|
||||||
|
: base(GetModifiers(type), GetName(type), CompiledTypeWrapper.GetBaseTypeWrapper(type), ClassLoaderWrapper.GetBootstrapClassLoader())
|
||||||
|
{
|
||||||
|
Debug.Assert(!(type.IsByRef), type.FullName);
|
||||||
|
Debug.Assert(!(type.IsPointer), type.FullName);
|
||||||
|
Debug.Assert(!(type.IsArray), type.FullName);
|
||||||
|
Debug.Assert(!(type is TypeBuilder), type.FullName);
|
||||||
|
Debug.Assert(!(type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false)));
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LazyPublishMembers()
|
||||||
|
{
|
||||||
|
// special support for enums
|
||||||
|
if(type.IsEnum)
|
||||||
|
{
|
||||||
|
// TODO handle unsigned underlying type
|
||||||
|
TypeWrapper fieldType = ClassLoaderWrapper.GetWrapperFromType(Enum.GetUnderlyingType(type));
|
||||||
|
FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
|
||||||
|
for(int i = 0; i < fields.Length; i++)
|
||||||
|
{
|
||||||
|
if(fields[i].FieldType == type)
|
||||||
|
{
|
||||||
|
// TODO handle name/signature clash
|
||||||
|
AddField(FieldWrapper.Create(this, fieldType, fields[i].Name, fieldType.SigName, Modifiers.Public | Modifiers.Static | Modifiers.Final, fields[i], CodeEmitter.CreateLoadConstant(fields[i].GetValue(null)), CodeEmitter.Pop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CodeEmitter getter = CodeEmitter.Create(OpCodes.Unbox, type) + CodeEmitter.Create(OpCodes.Ldobj, type);
|
||||||
|
CodeEmitter setter = CodeEmitter.Pop + CodeEmitter.Pop;
|
||||||
|
FieldWrapper fw = FieldWrapper.Create(this, fieldType, "Value", fieldType.SigName, Modifiers.Public | Modifiers.Final, null, getter, setter);
|
||||||
|
AddField(fw);
|
||||||
|
MethodWrapper mw = new MethodWrapper(this, MethodDescriptor.FromNameSig(GetClassLoader(), "wrap", "(" + fieldType.SigName + ")" + this.SigName), null, null, Modifiers.Static | Modifiers.Public, false);
|
||||||
|
mw.EmitCall = CodeEmitter.Create(OpCodes.Box, type);
|
||||||
|
AddMethod(mw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool isRemapped = ClassLoaderWrapper.IsRemappedType(type) && !type.IsInterface;
|
||||||
|
|
||||||
|
FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
for(int i = 0; i < fields.Length; i++)
|
||||||
|
{
|
||||||
|
// TODO for remapped types, instance fields need to be converted to static getter/setter methods
|
||||||
|
if(fields[i].FieldType.IsPointer)
|
||||||
|
{
|
||||||
|
// skip, pointer fields are not supported
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO handle name/signature clash
|
||||||
|
AddField(CreateFieldWrapper(AttributeHelper.GetModifiers(fields[i]), fields[i].Name, fields[i].FieldType, fields[i], null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case for delegate constructors!
|
||||||
|
if(!type.IsAbstract && type.IsSubclassOf(typeof(Delegate)))
|
||||||
|
{
|
||||||
|
TypeWrapper iface = GetClassLoader().LoadClassByDottedName(this.Name + DelegateInterfaceSuffix);
|
||||||
|
Debug.Assert(iface is CompiledTypeWrapper);
|
||||||
|
iface.Finish();
|
||||||
|
MethodDescriptor md = MethodDescriptor.FromNameSig(GetClassLoader(), "<init>", "(" + iface.SigName + ")V");
|
||||||
|
// TODO set method flags
|
||||||
|
MethodWrapper method = new MethodWrapper(this, md, null, null, Modifiers.Public, false);
|
||||||
|
method.EmitNewobj = new DelegateConstructorEmitter(type.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }), iface.Type.GetMethod("Invoke"));
|
||||||
|
AddMethod(method);
|
||||||
|
innerClasses = new TypeWrapper[] { iface };
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
for(int i = 0; i < constructors.Length; i++)
|
||||||
|
{
|
||||||
|
MethodDescriptor md = MakeMethodDescriptor(constructors[i], isRemapped);
|
||||||
|
if(md != null)
|
||||||
|
{
|
||||||
|
// TODO handle name/signature clash
|
||||||
|
AddMethod(CreateMethodWrapper(md, constructors[i], isRemapped));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
for(int i = 0; i < methods.Length; i++)
|
||||||
|
{
|
||||||
|
MethodDescriptor md = MakeMethodDescriptor(methods[i], isRemapped);
|
||||||
|
if(md != null)
|
||||||
|
{
|
||||||
|
// TODO handle name/signature clash
|
||||||
|
AddMethod(CreateMethodWrapper(md, methods[i], isRemapped));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodDescriptor MakeMethodDescriptor(MethodBase mb, bool isRemapped)
|
||||||
|
{
|
||||||
|
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||||
|
sb.Append('(');
|
||||||
|
ParameterInfo[] parameters = mb.GetParameters();
|
||||||
|
int bias = (isRemapped && !mb.IsStatic && !mb.IsConstructor) ? 1 : 0;
|
||||||
|
TypeWrapper[] args = new TypeWrapper[parameters.Length + bias];
|
||||||
|
if(bias == 1)
|
||||||
|
{
|
||||||
|
args[0] = ClassLoaderWrapper.GetWrapperFromType(mb.DeclaringType);
|
||||||
|
sb.Append(args[0].SigName);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
Type type = parameters[i].ParameterType;
|
||||||
|
if(type.IsPointer)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(type.IsByRef)
|
||||||
|
{
|
||||||
|
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
|
||||||
|
}
|
||||||
|
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(type);
|
||||||
|
args[i + bias] = tw;
|
||||||
|
sb.Append(tw.SigName);
|
||||||
|
}
|
||||||
|
sb.Append(')');
|
||||||
|
if(mb is ConstructorInfo)
|
||||||
|
{
|
||||||
|
TypeWrapper ret = PrimitiveTypeWrapper.VOID;
|
||||||
|
string name;
|
||||||
|
if(mb.IsStatic)
|
||||||
|
{
|
||||||
|
name = "<clinit>";
|
||||||
|
}
|
||||||
|
else if(isRemapped)
|
||||||
|
{
|
||||||
|
name = "__new";
|
||||||
|
ret = ClassLoaderWrapper.GetWrapperFromType(mb.DeclaringType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = "<init>";
|
||||||
|
}
|
||||||
|
sb.Append(ret.SigName);
|
||||||
|
return new MethodDescriptor(GetClassLoader(), name, sb.ToString(), args, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Type type = ((MethodInfo)mb).ReturnType;
|
||||||
|
if(type.IsPointer)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TypeWrapper ret = ClassLoaderWrapper.GetWrapperFromType(type);
|
||||||
|
sb.Append(ret.SigName);
|
||||||
|
return new MethodDescriptor(GetClassLoader(), mb.Name, sb.ToString(), args, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeWrapper[] Interfaces
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// remapped type cannot be instantiated, so it wouldn't make sense to implement
|
||||||
|
// interfaces
|
||||||
|
if(ClassLoaderWrapper.IsRemappedType(Type) && !Type.IsInterface)
|
||||||
|
{
|
||||||
|
return TypeWrapper.EmptyArray;
|
||||||
|
}
|
||||||
|
Type[] interfaces = type.GetInterfaces();
|
||||||
|
TypeWrapper[] interfaceWrappers = new TypeWrapper[interfaces.Length];
|
||||||
|
for(int i = 0; i < interfaces.Length; i++)
|
||||||
|
{
|
||||||
|
interfaceWrappers[i] = ClassLoaderWrapper.GetWrapperFromType(interfaces[i]);
|
||||||
|
}
|
||||||
|
return interfaceWrappers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeWrapper[] InnerClasses
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock(this)
|
||||||
|
{
|
||||||
|
if(innerClasses == null)
|
||||||
|
{
|
||||||
|
Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
innerClasses = new TypeWrapper[nestedTypes.Length];
|
||||||
|
for(int i = 0; i < nestedTypes.Length; i++)
|
||||||
|
{
|
||||||
|
innerClasses[i] = ClassLoaderWrapper.GetWrapperFromType(nestedTypes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return innerClasses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeWrapper DeclaringTypeWrapper
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(outerClass == null)
|
||||||
|
{
|
||||||
|
Type outer = type.DeclaringType;
|
||||||
|
if(outer != null)
|
||||||
|
{
|
||||||
|
outerClass = ClassLoaderWrapper.GetWrapperFromType(outer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outerClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override Modifiers ReflectiveModifiers
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(DeclaringTypeWrapper != null)
|
||||||
|
{
|
||||||
|
return Modifiers | Modifiers.Static;
|
||||||
|
}
|
||||||
|
return Modifiers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO support NonPrimitiveValueTypes
|
||||||
|
// TODO why doesn't this use the standard FieldWrapper.Create?
|
||||||
|
private FieldWrapper CreateFieldWrapper(Modifiers modifiers, string name, Type fieldType, FieldInfo field, MethodInfo getter)
|
||||||
|
{
|
||||||
|
CodeEmitter emitGet;
|
||||||
|
CodeEmitter emitSet;
|
||||||
|
if((modifiers & Modifiers.Static) != 0)
|
||||||
|
{
|
||||||
|
if(getter != null)
|
||||||
|
{
|
||||||
|
emitGet = CodeEmitter.Create(OpCodes.Call, getter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if field is a literal, we must emit an ldc instead of a ldsfld
|
||||||
|
if(field.IsLiteral)
|
||||||
|
{
|
||||||
|
emitGet = CodeEmitter.CreateLoadConstant(field.GetValue(null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emitGet = CodeEmitter.Create(OpCodes.Ldsfld, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(field != null && !field.IsLiteral)
|
||||||
|
{
|
||||||
|
emitSet = CodeEmitter.Create(OpCodes.Stsfld, field);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO what happens when you try to set a final field?
|
||||||
|
// through reflection: java.lang.IllegalAccessException: Field is final
|
||||||
|
// through code: java.lang.IllegalAccessError: Field <class>.<field> is final
|
||||||
|
emitSet = CodeEmitter.Nop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(getter != null)
|
||||||
|
{
|
||||||
|
emitGet = CodeEmitter.Create(OpCodes.Callvirt, getter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO is it possible to have literal instance fields?
|
||||||
|
emitGet = CodeEmitter.Create(OpCodes.Ldfld, field);
|
||||||
|
}
|
||||||
|
if(field != null)
|
||||||
|
{
|
||||||
|
emitSet = CodeEmitter.Create(OpCodes.Stfld, field);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO what happens when you try to set a final field through reflection?
|
||||||
|
// see above
|
||||||
|
emitSet = CodeEmitter.Nop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FieldWrapper.Create(this, ClassLoaderWrapper.GetWrapperFromType(fieldType), name, MethodDescriptor.GetFieldSigName(field), modifiers, field, emitGet, emitSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO why doesn't this use the standard MethodWrapper.Create?
|
||||||
|
private MethodWrapper CreateMethodWrapper(MethodDescriptor md, MethodBase mb, bool isRemapped)
|
||||||
|
{
|
||||||
|
ParameterInfo[] parameters = mb.GetParameters();
|
||||||
|
Type[] args = new Type[parameters.Length];
|
||||||
|
bool hasByRefArgs = false;
|
||||||
|
for(int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
args[i] = parameters[i].ParameterType;
|
||||||
|
if(parameters[i].ParameterType.IsByRef)
|
||||||
|
{
|
||||||
|
hasByRefArgs = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Modifiers mods = AttributeHelper.GetModifiers(mb);
|
||||||
|
if(isRemapped)
|
||||||
|
{
|
||||||
|
// all methods are static and final doesn't make sense
|
||||||
|
mods |= Modifiers.Static;
|
||||||
|
mods &= ~Modifiers.Final;
|
||||||
|
}
|
||||||
|
MethodWrapper method = new MethodWrapper(this, md, mb, null, mods, false);
|
||||||
|
if(mb is ConstructorInfo)
|
||||||
|
{
|
||||||
|
if(isRemapped)
|
||||||
|
{
|
||||||
|
method.EmitCall = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)mb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
method.EmitCall = CodeEmitter.Create(OpCodes.Call, (ConstructorInfo)mb);
|
||||||
|
method.EmitNewobj = CodeEmitter.Create(OpCodes.Newobj, (ConstructorInfo)mb);
|
||||||
|
if(this.IsNonPrimitiveValueType)
|
||||||
|
{
|
||||||
|
method.EmitNewobj += CodeEmitter.Create(OpCodes.Box, this.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool nonPrimitiveValueType = md.RetTypeWrapper.IsNonPrimitiveValueType;
|
||||||
|
method.EmitCall = CodeEmitter.Create(OpCodes.Call, (MethodInfo)mb);
|
||||||
|
if(nonPrimitiveValueType)
|
||||||
|
{
|
||||||
|
method.EmitCall += CodeEmitter.Create(OpCodes.Box, md.RetTypeWrapper.Type);
|
||||||
|
}
|
||||||
|
if(!mb.IsStatic)
|
||||||
|
{
|
||||||
|
method.EmitCallvirt = CodeEmitter.Create(OpCodes.Callvirt, (MethodInfo)mb);
|
||||||
|
if(nonPrimitiveValueType)
|
||||||
|
{
|
||||||
|
method.EmitCallvirt += CodeEmitter.Create(OpCodes.Box, md.RetTypeWrapper.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasByRefArgs)
|
||||||
|
{
|
||||||
|
method.EmitCall = new RefArgConverter(args) + method.EmitCall;
|
||||||
|
method.EmitCallvirt = new RefArgConverter(args) + method.EmitCallvirt;
|
||||||
|
method.EmitNewobj = new RefArgConverter(args) + method.EmitNewobj;
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DelegateConstructorEmitter : CodeEmitter
|
||||||
|
{
|
||||||
|
private ConstructorInfo delegateConstructor;
|
||||||
|
private MethodInfo method;
|
||||||
|
|
||||||
|
internal DelegateConstructorEmitter(ConstructorInfo delegateConstructor, MethodInfo method)
|
||||||
|
{
|
||||||
|
this.delegateConstructor = delegateConstructor;
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Emit(ILGenerator ilgen)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Dup);
|
||||||
|
ilgen.Emit(OpCodes.Ldvirtftn, method);
|
||||||
|
ilgen.Emit(OpCodes.Newobj, delegateConstructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RefArgConverter : CodeEmitter
|
||||||
|
{
|
||||||
|
private Type[] args;
|
||||||
|
|
||||||
|
internal RefArgConverter(Type[] args)
|
||||||
|
{
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void Emit(ILGenerator ilgen)
|
||||||
|
{
|
||||||
|
LocalBuilder[] locals = new LocalBuilder[args.Length];
|
||||||
|
for(int i = args.Length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Type type = args[i];
|
||||||
|
if(type.IsByRef)
|
||||||
|
{
|
||||||
|
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
|
||||||
|
}
|
||||||
|
locals[i] = ilgen.DeclareLocal(type);
|
||||||
|
ilgen.Emit(OpCodes.Stloc, locals[i]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Ldloc, locals[i]);
|
||||||
|
if(args[i].IsByRef)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Ldc_I4_0);
|
||||||
|
ilgen.Emit(OpCodes.Ldelema, args[i].GetElementType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override FieldWrapper GetFieldImpl(string fieldName)
|
||||||
|
{
|
||||||
|
lock(this)
|
||||||
|
{
|
||||||
|
if(!membersPublished)
|
||||||
|
{
|
||||||
|
membersPublished = true;
|
||||||
|
LazyPublishMembers();
|
||||||
|
return GetFieldWrapper(fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MethodWrapper GetMethodImpl(MethodDescriptor md)
|
||||||
|
{
|
||||||
|
lock(this)
|
||||||
|
{
|
||||||
|
if(!membersPublished)
|
||||||
|
{
|
||||||
|
membersPublished = true;
|
||||||
|
LazyPublishMembers();
|
||||||
|
return GetMethodWrapper(md, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Type Type
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Finish()
|
||||||
|
{
|
||||||
|
lock(this)
|
||||||
|
{
|
||||||
|
if(!membersPublished)
|
||||||
|
{
|
||||||
|
membersPublished = true;
|
||||||
|
LazyPublishMembers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ArrayTypeWrapper : TypeWrapper
|
class ArrayTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
private static TypeWrapper[] interfaces;
|
private static TypeWrapper[] interfaces;
|
||||||
|
@ -4101,6 +4522,15 @@ class ArrayTypeWrapper : TypeWrapper
|
||||||
AddMethod(mw);
|
AddMethod(mw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal override string SigName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// for arrays the signature name is the same as the normal name
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override TypeWrapper[] Interfaces
|
public override TypeWrapper[] Interfaces
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -179,6 +179,10 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Byte, new object[] { o });
|
return Activator.CreateInstance(java_lang_Byte, new object[] { o });
|
||||||
}
|
}
|
||||||
|
else if(o is byte)
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance(java_lang_Byte, new object[] { (sbyte)(byte)o });
|
||||||
|
}
|
||||||
else if(o is bool)
|
else if(o is bool)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Boolean, new object[] { o });
|
return Activator.CreateInstance(java_lang_Boolean, new object[] { o });
|
||||||
|
@ -187,6 +191,10 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Short, new object[] { o });
|
return Activator.CreateInstance(java_lang_Short, new object[] { o });
|
||||||
}
|
}
|
||||||
|
else if(o is ushort)
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance(java_lang_Short, new object[] { (short)(ushort)o });
|
||||||
|
}
|
||||||
else if(o is char)
|
else if(o is char)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Character, new object[] { o });
|
return Activator.CreateInstance(java_lang_Character, new object[] { o });
|
||||||
|
@ -195,10 +203,18 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Integer, new object[] { o });
|
return Activator.CreateInstance(java_lang_Integer, new object[] { o });
|
||||||
}
|
}
|
||||||
|
else if(o is uint)
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance(java_lang_Integer, new object[] { (int)(uint)o });
|
||||||
|
}
|
||||||
else if(o is long)
|
else if(o is long)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Long, new object[] { o });
|
return Activator.CreateInstance(java_lang_Long, new object[] { o });
|
||||||
}
|
}
|
||||||
|
else if(o is ulong)
|
||||||
|
{
|
||||||
|
return Activator.CreateInstance(java_lang_Long, new object[] { (long)(ulong)o });
|
||||||
|
}
|
||||||
else if(o is float)
|
else if(o is float)
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Float, new object[] { o });
|
return Activator.CreateInstance(java_lang_Float, new object[] { o });
|
||||||
|
@ -207,6 +223,38 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return Activator.CreateInstance(java_lang_Double, new object[] { o });
|
return Activator.CreateInstance(java_lang_Double, new object[] { o });
|
||||||
}
|
}
|
||||||
|
else if(o is Enum)
|
||||||
|
{
|
||||||
|
Type enumType = Enum.GetUnderlyingType(o.GetType());
|
||||||
|
if(enumType == typeof(byte) || enumType == typeof(sbyte))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box((sbyte)((IConvertible)o).ToInt32(null));
|
||||||
|
}
|
||||||
|
else if(enumType == typeof(short) || enumType == typeof(ushort))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box((short)((IConvertible)o).ToInt32(null));
|
||||||
|
}
|
||||||
|
else if(enumType == typeof(int))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box(((IConvertible)o).ToInt32(null));
|
||||||
|
}
|
||||||
|
else if(enumType == typeof(uint))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box(unchecked((int)((IConvertible)o).ToUInt32(null)));
|
||||||
|
}
|
||||||
|
else if(enumType == typeof(long))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box(((IConvertible)o).ToInt64(null));
|
||||||
|
}
|
||||||
|
else if(enumType == typeof(ulong))
|
||||||
|
{
|
||||||
|
return JavaWrapper.Box(unchecked((long)((IConvertible)o).ToUInt64(null)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new NotImplementedException(o.GetType().FullName);
|
throw new NotImplementedException(o.GetType().FullName);
|
||||||
|
@ -327,6 +375,14 @@ namespace NativeCode.java
|
||||||
|
|
||||||
public class Field
|
public class Field
|
||||||
{
|
{
|
||||||
|
// HACK this is used by netexp to query the constant value of a field
|
||||||
|
public static object getConstant(object field)
|
||||||
|
{
|
||||||
|
// HACK we use reflection to extract the fieldCookie from the java.lang.reflect.Field object
|
||||||
|
FieldWrapper wrapper = (FieldWrapper)field.GetType().GetField("fieldCookie", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(field);
|
||||||
|
return wrapper.GetConstant();
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetName(object fieldCookie)
|
public static string GetName(object fieldCookie)
|
||||||
{
|
{
|
||||||
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
|
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
|
||||||
|
@ -951,28 +1007,28 @@ namespace NativeCode.java
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type getPrimitiveType(char type)
|
public static object getPrimitiveClass(char type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'Z':
|
case 'Z':
|
||||||
return typeof(bool);
|
return VMClass.getClassFromType(typeof(bool));
|
||||||
case 'B':
|
case 'B':
|
||||||
return typeof(sbyte);
|
return VMClass.getClassFromType(typeof(sbyte));
|
||||||
case 'C':
|
case 'C':
|
||||||
return typeof(char);
|
return VMClass.getClassFromType(typeof(char));
|
||||||
case 'D':
|
case 'D':
|
||||||
return typeof(double);
|
return VMClass.getClassFromType(typeof(double));
|
||||||
case 'F':
|
case 'F':
|
||||||
return typeof(float);
|
return VMClass.getClassFromType(typeof(float));
|
||||||
case 'I':
|
case 'I':
|
||||||
return typeof(int);
|
return VMClass.getClassFromType(typeof(int));
|
||||||
case 'J':
|
case 'J':
|
||||||
return typeof(long);
|
return VMClass.getClassFromType(typeof(long));
|
||||||
case 'S':
|
case 'S':
|
||||||
return typeof(short);
|
return VMClass.getClassFromType(typeof(short));
|
||||||
case 'V':
|
case 'V':
|
||||||
return typeof(void);
|
return VMClass.getClassFromType(typeof(void));
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
@ -990,7 +1046,7 @@ namespace NativeCode.java
|
||||||
throw JavaException.NoClassDefFoundError("{0} (wrong name: {1})", name, classFile.Name);
|
throw JavaException.NoClassDefFoundError("{0} (wrong name: {1})", name, classFile.Name);
|
||||||
}
|
}
|
||||||
TypeWrapper type = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader).DefineClass(classFile);
|
TypeWrapper type = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader).DefineClass(classFile);
|
||||||
object clazz = VMClass.CreateInstance(null, type);
|
object clazz = VMClass.CreateClassInstance(type);
|
||||||
if(protectionDomain != null)
|
if(protectionDomain != null)
|
||||||
{
|
{
|
||||||
// TODO cache the FieldInfo
|
// TODO cache the FieldInfo
|
||||||
|
@ -1008,8 +1064,9 @@ namespace NativeCode.java
|
||||||
public class VMClass
|
public class VMClass
|
||||||
{
|
{
|
||||||
private static Hashtable map = new Hashtable();
|
private static Hashtable map = new Hashtable();
|
||||||
private static MethodInfo createClass;
|
private delegate object CreateClassDelegate(object typeWrapper);
|
||||||
private static MethodInfo getTypeMethod;
|
private static CreateClassDelegate CreateClass;
|
||||||
|
private static MethodInfo getWrapper;
|
||||||
|
|
||||||
public static void throwException(Exception e)
|
public static void throwException(Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1038,20 +1095,27 @@ namespace NativeCode.java
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static object CreateInstance(Type type, TypeWrapper wrapper)
|
internal static object CreateClassInstance(TypeWrapper wrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper.AssertFinished(type);
|
if(CreateClass == null)
|
||||||
if(createClass == null)
|
|
||||||
{
|
{
|
||||||
createClass = ClassLoaderWrapper.GetType("java.lang.VMClass").GetMethod("createClass", BindingFlags.Static | BindingFlags.NonPublic);
|
CreateClass = (CreateClassDelegate)Delegate.CreateDelegate(typeof(CreateClassDelegate), ClassLoaderWrapper.GetType("java.lang.VMClass").GetMethod("createClass", BindingFlags.Static | BindingFlags.Public));
|
||||||
|
// HACK to make sure we don't run into any problems creating class objects for classes that
|
||||||
|
// participate in the VMClass static initialization, we first do a bogus call to initialize
|
||||||
|
// the machinery (I ran into this when running netexp on classpath.dll)
|
||||||
|
CreateClass(null);
|
||||||
|
lock(map.SyncRoot)
|
||||||
|
{
|
||||||
|
object o = map[wrapper];
|
||||||
|
if(o != null)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
object clazz = createClass.Invoke(null, new object[] { type, wrapper });
|
object clazz = CreateClass(wrapper);
|
||||||
lock(map.SyncRoot)
|
lock(map.SyncRoot)
|
||||||
{
|
{
|
||||||
if(type != null)
|
|
||||||
{
|
|
||||||
map.Add(type, clazz);
|
|
||||||
}
|
|
||||||
if(wrapper != null)
|
if(wrapper != null)
|
||||||
{
|
{
|
||||||
map.Add(wrapper, clazz);
|
map.Add(wrapper, clazz);
|
||||||
|
@ -1060,11 +1124,21 @@ namespace NativeCode.java
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsAssignableFrom(Object w1, Object w2)
|
public static bool IsAssignableFrom(object w1, object w2)
|
||||||
{
|
{
|
||||||
return ((TypeWrapper)w2).IsAssignableTo((TypeWrapper)w1);
|
return ((TypeWrapper)w2).IsAssignableTo((TypeWrapper)w1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsInterface(object wrapper)
|
||||||
|
{
|
||||||
|
return ((TypeWrapper)wrapper).IsInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsArray(object wrapper)
|
||||||
|
{
|
||||||
|
return ((TypeWrapper)wrapper).IsArray;
|
||||||
|
}
|
||||||
|
|
||||||
public static object GetSuperClassFromWrapper(object wrapper)
|
public static object GetSuperClassFromWrapper(object wrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper baseWrapper = ((TypeWrapper)wrapper).BaseTypeWrapper;
|
TypeWrapper baseWrapper = ((TypeWrapper)wrapper).BaseTypeWrapper;
|
||||||
|
@ -1093,13 +1167,6 @@ namespace NativeCode.java
|
||||||
((TypeWrapper)wrapper).Finish();
|
((TypeWrapper)wrapper).Finish();
|
||||||
Type type = ((TypeWrapper)wrapper).Type;
|
Type type = ((TypeWrapper)wrapper).Type;
|
||||||
TypeWrapper.AssertFinished(type);
|
TypeWrapper.AssertFinished(type);
|
||||||
lock(map.SyncRoot)
|
|
||||||
{
|
|
||||||
// NOTE since this method can be called multiple times (or after getClassFromType has added
|
|
||||||
// the Class to the map), we don't use Add() here, but the indexer because that can handle
|
|
||||||
// "overwriting" the existing association (which should always be the same as the new one)
|
|
||||||
map[type] = clazz;
|
|
||||||
}
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,11 +1177,13 @@ namespace NativeCode.java
|
||||||
|
|
||||||
public static Type getType(object clazz)
|
public static Type getType(object clazz)
|
||||||
{
|
{
|
||||||
if(getTypeMethod == null)
|
if(getWrapper == null)
|
||||||
{
|
{
|
||||||
getTypeMethod = ClassLoaderWrapper.GetType("java.lang.VMClass").GetMethod("getTypeFromClass", BindingFlags.NonPublic | BindingFlags.Static);
|
getWrapper = ClassLoaderWrapper.GetType("java.lang.VMClass").GetMethod("getWrapperFromClass", BindingFlags.NonPublic | BindingFlags.Static);
|
||||||
}
|
}
|
||||||
return (Type)getTypeMethod.Invoke(null, new object[] { clazz });
|
TypeWrapper wrapper = (TypeWrapper)getWrapper.Invoke(null, new object[] { clazz });
|
||||||
|
wrapper.Finish();
|
||||||
|
return wrapper.Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static object getClassFromWrapper(TypeWrapper wrapper)
|
internal static object getClassFromWrapper(TypeWrapper wrapper)
|
||||||
|
@ -1124,12 +1193,7 @@ namespace NativeCode.java
|
||||||
object clazz = map[wrapper];
|
object clazz = map[wrapper];
|
||||||
if(clazz == null)
|
if(clazz == null)
|
||||||
{
|
{
|
||||||
// Maybe the Class object was already constructed from the type
|
clazz = CreateClassInstance(wrapper);
|
||||||
clazz = map[wrapper.Type];
|
|
||||||
if(clazz == null)
|
|
||||||
{
|
|
||||||
clazz = CreateInstance(null, wrapper);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
@ -1142,71 +1206,61 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
lock(map.SyncRoot)
|
return getClassFromWrapper(ClassLoaderWrapper.GetWrapperFromType(type));
|
||||||
{
|
|
||||||
object clazz = map[type];
|
|
||||||
if(clazz == null)
|
|
||||||
{
|
|
||||||
// maybe the Class object was constructed from the wrapper
|
|
||||||
TypeWrapper wrapper = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
|
|
||||||
if(wrapper != null)
|
|
||||||
{
|
|
||||||
clazz = map[wrapper];
|
|
||||||
if(clazz != null)
|
|
||||||
{
|
|
||||||
map.Add(type, clazz);
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// NOTE we need to get the bootstrap classloader to trigger its construction (if it
|
|
||||||
// hasn't been created yet), because otherwise CreateInstance will do that and this
|
|
||||||
// causes the same class object to be created multiple times)
|
|
||||||
ClassLoaderWrapper.GetBootstrapClassLoader();
|
|
||||||
clazz = map[type];
|
|
||||||
if(clazz == null)
|
|
||||||
{
|
|
||||||
// if this type is an override stub (e.g. java.lang.Object), we need to return the
|
|
||||||
// class object for the parent type
|
|
||||||
// NOTE we first check if type isn't an array, because Type.IsDefined throws an exception
|
|
||||||
// when called on an array type (?)
|
|
||||||
if(!type.IsArray && type.IsDefined(typeof(HideFromReflectionAttribute), false))
|
|
||||||
{
|
|
||||||
clazz = getClassFromType(type.BaseType);
|
|
||||||
map.Add(type, clazz);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO should we specify the wrapper?
|
|
||||||
// NOTE CreateInstance adds the Class to the "map"
|
|
||||||
clazz = CreateInstance(type, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string getName(Type type)
|
public static string GetName(object wrapper)
|
||||||
{
|
{
|
||||||
return GetName(type, null);
|
TypeWrapper typeWrapper = (TypeWrapper)wrapper;
|
||||||
|
if(typeWrapper.IsPrimitive)
|
||||||
|
{
|
||||||
|
if(typeWrapper == PrimitiveTypeWrapper.VOID)
|
||||||
|
{
|
||||||
|
return "void";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.BYTE)
|
||||||
|
{
|
||||||
|
return "byte";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.BOOLEAN)
|
||||||
|
{
|
||||||
|
return "boolean";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.SHORT)
|
||||||
|
{
|
||||||
|
return "short";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.CHAR)
|
||||||
|
{
|
||||||
|
return "char";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.INT)
|
||||||
|
{
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.LONG)
|
||||||
|
{
|
||||||
|
return "long";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.FLOAT)
|
||||||
|
{
|
||||||
|
return "float";
|
||||||
|
}
|
||||||
|
else if(typeWrapper == PrimitiveTypeWrapper.DOUBLE)
|
||||||
|
{
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeWrapper.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetName(Type type, object wrapperType)
|
internal static string getName(Type type)
|
||||||
{
|
{
|
||||||
if(type == null)
|
TypeWrapper wrapperType = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
|
||||||
{
|
|
||||||
string name = ((TypeWrapper)wrapperType).Name;
|
|
||||||
// HACK name is null for primitives
|
|
||||||
if(name != null)
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
type = ((TypeWrapper)wrapperType).Type;
|
|
||||||
}
|
|
||||||
if(wrapperType == null)
|
|
||||||
{
|
|
||||||
wrapperType = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
|
|
||||||
}
|
|
||||||
if(wrapperType != null)
|
if(wrapperType != null)
|
||||||
{
|
{
|
||||||
string name = ((TypeWrapper)wrapperType).Name;
|
string name = ((TypeWrapper)wrapperType).Name;
|
||||||
|
@ -1256,7 +1310,8 @@ namespace NativeCode.java
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return type.FullName;
|
// HACK we're assuming for the time being that Java code cannot define new value types
|
||||||
|
return DotNetTypeWrapper.GetName(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(type.IsArray)
|
else if(type.IsArray)
|
||||||
|
@ -1307,12 +1362,13 @@ namespace NativeCode.java
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.Append(type.FullName);
|
// HACK we're assuming for the time being that Java code cannot define new value types
|
||||||
|
sb.Append(DotNetTypeWrapper.GetName(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.Append('L').Append(GetName(type, null)).Append(';');
|
sb.Append('L').Append(getName(type)).Append(';');
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
@ -1333,32 +1389,38 @@ namespace NativeCode.java
|
||||||
{
|
{
|
||||||
return ((InnerClassAttribute)attribs[0]).InnerClassName;
|
return ((InnerClassAttribute)attribs[0]).InnerClassName;
|
||||||
}
|
}
|
||||||
return type.FullName;
|
if(type.Assembly is System.Reflection.Emit.AssemblyBuilder || type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false))
|
||||||
|
{
|
||||||
|
return type.FullName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DotNetTypeWrapper.GetName(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StackTraceInfo(Hidden = true)]
|
[StackTraceInfo(Hidden = true)]
|
||||||
public static void initializeType(Type type)
|
public static void initialize(object cwrapper)
|
||||||
{
|
{
|
||||||
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
}
|
wrapper.Finish();
|
||||||
|
RuntimeHelpers.RunClassConstructor(wrapper.Type.TypeHandle);
|
||||||
public static object getClassLoader0(Type type, object wrapper)
|
}
|
||||||
{
|
|
||||||
if(wrapper != null)
|
public static object getClassLoader0(object wrapper)
|
||||||
{
|
{
|
||||||
return ((TypeWrapper)wrapper).GetClassLoader().GetJavaClassLoader();
|
return ((TypeWrapper)wrapper).GetClassLoader().GetJavaClassLoader();
|
||||||
}
|
}
|
||||||
return ClassLoaderWrapper.GetClassLoader(type).GetJavaClassLoader();
|
|
||||||
}
|
public static object getClassLoaderFromType(Type type)
|
||||||
|
{
|
||||||
public static object[] GetDeclaredMethods(Type type, object cwrapper, bool getMethods, bool publicOnly)
|
return ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader().GetJavaClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object[] GetDeclaredMethods(object cwrapper, bool getMethods, bool publicOnly)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// we need to finish the type otherwise all methods will not be in the method map yet
|
// we need to finish the type otherwise all methods will not be in the method map yet
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
// we need to look through the array for unloadable types, because we may not let them
|
// we need to look through the array for unloadable types, because we may not let them
|
||||||
|
@ -1400,13 +1462,9 @@ namespace NativeCode.java
|
||||||
return (MethodWrapper[])list.ToArray(typeof(MethodWrapper));
|
return (MethodWrapper[])list.ToArray(typeof(MethodWrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object[] GetDeclaredFields(Type type, object cwrapper, bool publicOnly)
|
public static object[] GetDeclaredFields(object cwrapper, bool publicOnly)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// we need to finish the type otherwise all fields will not be in the field map yet
|
// we need to finish the type otherwise all fields will not be in the field map yet
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
// we need to look through the array for unloadable types, because we may not let them
|
// we need to look through the array for unloadable types, because we may not let them
|
||||||
|
@ -1434,13 +1492,9 @@ namespace NativeCode.java
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object[] GetDeclaredClasses(Type type, object cwrapper, bool publicOnly)
|
public static object[] GetDeclaredClasses(object cwrapper, bool publicOnly)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// NOTE to get at the InnerClasses we need to finish the type
|
// NOTE to get at the InnerClasses we need to finish the type
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
TypeWrapper[] wrappers = wrapper.InnerClasses;
|
TypeWrapper[] wrappers = wrapper.InnerClasses;
|
||||||
|
@ -1476,13 +1530,9 @@ namespace NativeCode.java
|
||||||
return innerclasses;
|
return innerclasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object GetDeclaringClass(Type type, object cwrapper)
|
public static object GetDeclaringClass(object cwrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// before we can call DeclaringTypeWrapper, we need to finish the type
|
// before we can call DeclaringTypeWrapper, we need to finish the type
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
TypeWrapper declaring = wrapper.DeclaringTypeWrapper;
|
TypeWrapper declaring = wrapper.DeclaringTypeWrapper;
|
||||||
|
@ -1497,14 +1547,11 @@ namespace NativeCode.java
|
||||||
return getClassFromWrapper(declaring);
|
return getClassFromWrapper(declaring);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object[] GetInterfaces(Type type, object cwrapper)
|
public static object[] GetInterfaces(object cwrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// we need to finish the type otherwise all fields will not be in the field map yet
|
// we need to finish the type otherwise all fields will not be in the field map yet
|
||||||
|
// TODO this should not be needed (make sure it isn't and remove)
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
TypeWrapper[] interfaceWrappers = wrapper.Interfaces;
|
TypeWrapper[] interfaceWrappers = wrapper.Interfaces;
|
||||||
object[] interfaces = new object[interfaceWrappers.Length];
|
object[] interfaces = new object[interfaceWrappers.Length];
|
||||||
|
@ -1515,13 +1562,9 @@ namespace NativeCode.java
|
||||||
return interfaces;
|
return interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetModifiers(Type type, Object cwrapper)
|
public static int GetModifiers(Object cwrapper)
|
||||||
{
|
{
|
||||||
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
TypeWrapper wrapper = (TypeWrapper)cwrapper;
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
|
||||||
}
|
|
||||||
// NOTE ReflectiveModifiers is only available for finished types
|
// NOTE ReflectiveModifiers is only available for finished types
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
// NOTE we don't return the modifiers from the TypeWrapper, because for inner classes
|
// NOTE we don't return the modifiers from the TypeWrapper, because for inner classes
|
||||||
|
|
|
@ -960,7 +960,7 @@ class Compiler
|
||||||
if(instr.NormalizedOpCode == NormalizedByteCode.__invokespecial && cpi.Name == "<init>" && VerifierTypeWrapper.IsNew(type))
|
if(instr.NormalizedOpCode == NormalizedByteCode.__invokespecial && cpi.Name == "<init>" && VerifierTypeWrapper.IsNew(type))
|
||||||
{
|
{
|
||||||
TypeWrapper[] args = cpi.GetArgTypes(classLoader);
|
TypeWrapper[] args = cpi.GetArgTypes(classLoader);
|
||||||
CastInterfaceArgs(args, i, true, false);
|
CastInterfaceArgs(args, i, false, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,23 +27,22 @@
|
||||||
<class name="java.lang.Object" type="System.Object" modifiers="public">
|
<class name="java.lang.Object" type="System.Object" modifiers="public">
|
||||||
<constructor sig="()V" modifiers="public" />
|
<constructor sig="()V" modifiers="public" />
|
||||||
<method name="notifyAll" sig="()V" modifiers="public final">
|
<method name="notifyAll" sig="()V" modifiers="public final">
|
||||||
<redirect class="System.Threading.Monitor" name="PulseAll" sig="(Ljava.lang.Object;)V" type="static" />
|
<redirect class="System.Threading.Monitor, mscorlib" name="PulseAll" sig="(Ljava.lang.Object;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method name="notify" sig="()V" modifiers="public final">
|
<method name="notify" sig="()V" modifiers="public final">
|
||||||
<redirect class="System.Threading.Monitor" name="Pulse" sig="(Ljava.lang.Object;)V" type="static" />
|
<redirect class="System.Threading.Monitor, mscorlib" name="Pulse" sig="(Ljava.lang.Object;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method name="wait" sig="()V" modifiers="public final">
|
<method name="wait" sig="()V" modifiers="public final">
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<call type="System.Threading.Monitor" name="Wait" sig="(Ljava.lang.Object;)Z" />
|
<call type="System.Threading.Monitor, mscorlib" name="Wait" sig="(Ljava.lang.Object;)Z" />
|
||||||
<!-- For some reason, Wait returns a boolean -->
|
<!-- For some reason, Wait returns a boolean -->
|
||||||
<pop />
|
<pop />
|
||||||
</invokespecial>
|
</invokespecial>
|
||||||
<invokevirtual>
|
<invokevirtual>
|
||||||
<call type="System.Threading.Monitor" name="Wait" sig="(Ljava.lang.Object;)Z" />
|
<call type="System.Threading.Monitor, mscorlib" name="Wait" sig="(Ljava.lang.Object;)Z" />
|
||||||
<!-- For some reason, Wait returns a boolean -->
|
<!-- For some reason, Wait returns a boolean -->
|
||||||
<pop />
|
<pop />
|
||||||
</invokevirtual>
|
</invokevirtual>
|
||||||
<!--redirect class="System.Threading.Monitor" name="Wait" sig="(Ljava.lang.Object;)V" type="static" /-->
|
|
||||||
</method>
|
</method>
|
||||||
<method name="wait" sig="(J)V" modifiers="public final">
|
<method name="wait" sig="(J)V" modifiers="public final">
|
||||||
<redirect class="java.lang.ObjectHelper" name="wait" sig="(Ljava.lang.Object;J)V" type="static" />
|
<redirect class="java.lang.ObjectHelper" name="wait" sig="(Ljava.lang.Object;J)V" type="static" />
|
||||||
|
@ -68,7 +67,7 @@
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<!-- TODO if we already know statically that the type implements java.lang.Cloneable this check can be omitted -->
|
<!-- TODO if we already know statically that the type implements java.lang.Cloneable this check can be omitted -->
|
||||||
<dup />
|
<dup />
|
||||||
<isinst type="java.lang.Cloneable" />
|
<isinst class="java.lang.Cloneable" />
|
||||||
<brtrue name="ok" />
|
<brtrue name="ok" />
|
||||||
<newobj class="java.lang.CloneNotSupportedException" name="<init>" sig="()V" />
|
<newobj class="java.lang.CloneNotSupportedException" name="<init>" sig="()V" />
|
||||||
<throw />
|
<throw />
|
||||||
|
@ -104,9 +103,9 @@
|
||||||
<override name="GetHashCode" />
|
<override name="GetHashCode" />
|
||||||
<invokevirtual>
|
<invokevirtual>
|
||||||
<dup />
|
<dup />
|
||||||
<isinst type="System.String" />
|
<isinst type="System.String, mscorlib" />
|
||||||
<brfalse name="skip" />
|
<brfalse name="skip" />
|
||||||
<castclass type="System.String" />
|
<castclass type="System.String, mscorlib" />
|
||||||
<call class="java.lang.StringHelper" name="hashCode" sig="(Ljava.lang.String;)I" />
|
<call class="java.lang.StringHelper" name="hashCode" sig="(Ljava.lang.String;)I" />
|
||||||
<br name="end" />
|
<br name="end" />
|
||||||
<label name="skip" />
|
<label name="skip" />
|
||||||
|
@ -121,7 +120,7 @@
|
||||||
<override name="Finalize" />
|
<override name="Finalize" />
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
<class name="java.lang.String" type="System.String" modifiers="public final">
|
<class name="java.lang.String" type="System.String, mscorlib" modifiers="public final">
|
||||||
<implements class="java.lang.Comparable" />
|
<implements class="java.lang.Comparable" />
|
||||||
<implements class="java.lang.CharSequence" />
|
<implements class="java.lang.CharSequence" />
|
||||||
<implements class="java.io.Serializable" />
|
<implements class="java.io.Serializable" />
|
||||||
|
@ -129,7 +128,7 @@
|
||||||
<!-- TODO -->
|
<!-- TODO -->
|
||||||
<newobj>
|
<newobj>
|
||||||
<ldstr value="" />
|
<ldstr value="" />
|
||||||
<call type="System.String" name="Copy" />
|
<call type="System.String, mscorlib" name="Copy" />
|
||||||
</newobj>
|
</newobj>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor sig="([C)V" modifiers="public" />
|
<constructor sig="([C)V" modifiers="public" />
|
||||||
|
@ -139,7 +138,7 @@
|
||||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([CIIZ)Ljava.lang.String;" />
|
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([CIIZ)Ljava.lang.String;" />
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor sig="(Ljava.lang.String;)V" modifiers="public">
|
<constructor sig="(Ljava.lang.String;)V" modifiers="public">
|
||||||
<redirect class="System.String" name="Copy" type="static" sig="(Ljava.lang.String;)Ljava.lang.String;" />
|
<redirect class="System.String, mscorlib" name="Copy" type="static" sig="(Ljava.lang.String;)Ljava.lang.String;" />
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor sig="(Ljava.lang.StringBuffer;)V" modifiers="public">
|
<constructor sig="(Ljava.lang.StringBuffer;)V" modifiers="public">
|
||||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
|
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
|
||||||
|
@ -299,12 +298,12 @@
|
||||||
</method>
|
</method>
|
||||||
<method name="copyValueOf" sig="([C)Ljava.lang.String;" modifiers="public static">
|
<method name="copyValueOf" sig="([C)Ljava.lang.String;" modifiers="public static">
|
||||||
<invokestatic>
|
<invokestatic>
|
||||||
<newobj type="System.String" name=".ctor" sig="([C)V" />
|
<newobj type="System.String, mscorlib" name=".ctor" sig="([C)V" />
|
||||||
</invokestatic>
|
</invokestatic>
|
||||||
</method>
|
</method>
|
||||||
<method name="copyValueOf" sig="([CII)Ljava.lang.String;" modifiers="public static">
|
<method name="copyValueOf" sig="([CII)Ljava.lang.String;" modifiers="public static">
|
||||||
<invokestatic>
|
<invokestatic>
|
||||||
<newobj type="System.String" name=".ctor" sig="([CII)V" />
|
<newobj type="System.String, mscorlib" name=".ctor" sig="([CII)V" />
|
||||||
</invokestatic>
|
</invokestatic>
|
||||||
</method>
|
</method>
|
||||||
<field name="CASE_INSENSITIVE_ORDER" sig="Ljava.util.Comparator;" modifiers="public static final">
|
<field name="CASE_INSENSITIVE_ORDER" sig="Ljava.util.Comparator;" modifiers="public static final">
|
||||||
|
@ -335,20 +334,20 @@
|
||||||
<implements class="java.io.Serializable" />
|
<implements class="java.io.Serializable" />
|
||||||
<constructor sig="()V" modifiers="public">
|
<constructor sig="()V" modifiers="public">
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<call type="ExceptionHelper" name="get_NullString" />
|
<call type="ExceptionHelper, ik.vm.net" name="get_NullString" />
|
||||||
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;)V" />
|
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;)V" />
|
||||||
</invokespecial>
|
</invokespecial>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor sig="(Ljava.lang.String;)V" modifiers="public">
|
<constructor sig="(Ljava.lang.String;)V" modifiers="public">
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<call type="ExceptionHelper" name="FilterMessage" />
|
<call type="ExceptionHelper, ik.vm.net" name="FilterMessage" />
|
||||||
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;)V" />
|
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;)V" />
|
||||||
</invokespecial>
|
</invokespecial>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" modifiers="public">
|
<constructor sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" modifiers="public">
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<stloc name="x" type="System.Exception" />
|
<stloc name="x" type="System.Exception" />
|
||||||
<call type="ExceptionHelper" name="FilterMessage" />
|
<call type="ExceptionHelper, ik.vm.net" name="FilterMessage" />
|
||||||
<ldloc name="x" />
|
<ldloc name="x" />
|
||||||
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
|
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
|
||||||
</invokespecial>
|
</invokespecial>
|
||||||
|
@ -357,47 +356,47 @@
|
||||||
<invokespecial>
|
<invokespecial>
|
||||||
<stloc name="x" type="System.Exception" />
|
<stloc name="x" type="System.Exception" />
|
||||||
<ldloc name="x" />
|
<ldloc name="x" />
|
||||||
<call type="ExceptionHelper" name="GetMessageFromCause" />
|
<call type="ExceptionHelper, ik.vm.net" name="GetMessageFromCause" />
|
||||||
<ldloc name="x" />
|
<ldloc name="x" />
|
||||||
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
|
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
|
||||||
</invokespecial>
|
</invokespecial>
|
||||||
</constructor>
|
</constructor>
|
||||||
<method type="virtual" name="printStackTrace" sig="()V" modifiers="public">
|
<method type="virtual" name="printStackTrace" sig="()V" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)V" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="printStackTrace" sig="(Ljava.io.PrintStream;)V" modifiers="public">
|
<method type="virtual" name="printStackTrace" sig="(Ljava.io.PrintStream;)V" modifiers="public">
|
||||||
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
|
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
|
||||||
to the same method, this is not a bug -->
|
to the same method, this is not a bug -->
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;Ljava.lang.Object;)V" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;Ljava.lang.Object;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="printStackTrace" sig="(Ljava.io.PrintWriter;)V" modifiers="public">
|
<method type="virtual" name="printStackTrace" sig="(Ljava.io.PrintWriter;)V" modifiers="public">
|
||||||
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
|
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
|
||||||
to the same method, this is not a bug -->
|
to the same method, this is not a bug -->
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;Ljava.lang.Object;)V" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;Ljava.lang.Object;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="getMessage" sig="()Ljava.lang.String;" modifiers="public">
|
<method type="virtual" name="getMessage" sig="()Ljava.lang.String;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="getLocalizedMessage" sig="()Ljava.lang.String;" modifiers="public">
|
<method type="virtual" name="getLocalizedMessage" sig="()Ljava.lang.String;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="fillInStackTrace" sig="()Ljava.lang.Throwable;" modifiers="public">
|
<method type="virtual" name="fillInStackTrace" sig="()Ljava.lang.Throwable;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="initCause" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" modifiers="public">
|
<method type="virtual" name="initCause" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="getCause" sig="()Ljava.lang.Throwable;" modifiers="public">
|
<method type="virtual" name="getCause" sig="()Ljava.lang.Throwable;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)Ljava.lang.Throwable;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="getStackTrace" sig="()[Ljava.lang.StackTraceElement;" modifiers="public">
|
<method type="virtual" name="getStackTrace" sig="()[Ljava.lang.StackTraceElement;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)[Ljava.lang.StackTraceElement;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)[Ljava.lang.StackTraceElement;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="setStackTrace" sig="([Ljava.lang.StackTraceElement;)V" modifiers="public">
|
<method type="virtual" name="setStackTrace" sig="([Ljava.lang.StackTraceElement;)V" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;[Ljava.lang.StackTraceElement;)V" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;[Ljava.lang.StackTraceElement;)V" type="static" />
|
||||||
</method>
|
</method>
|
||||||
<method type="virtual" name="toString" sig="()Ljava.lang.String;" modifiers="public">
|
<method type="virtual" name="toString" sig="()Ljava.lang.String;" modifiers="public">
|
||||||
<redirect class="ExceptionHelper" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
<redirect class="ExceptionHelper, ik.vm.net" sig="(Ljava.lang.Throwable;)Ljava.lang.String;" type="static" />
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
<class name="java.lang.Comparable" type="System.IComparable" modifiers="public interface">
|
<class name="java.lang.Comparable" type="System.IComparable" modifiers="public interface">
|
||||||
|
@ -449,5 +448,15 @@
|
||||||
<ret />
|
<ret />
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</class>
|
||||||
|
<class name="ikvm.lang.ByteArrayHack">
|
||||||
|
<method name="cast" sig="([B)[Lcli.System.Byte;">
|
||||||
|
<ldarg_0 />
|
||||||
|
<ret />
|
||||||
|
</method>
|
||||||
|
<method name="cast" sig="([Lcli.System.Byte;)[B">
|
||||||
|
<ldarg_0 />
|
||||||
|
<ret />
|
||||||
|
</method>
|
||||||
|
</class>
|
||||||
</nativeMethods>
|
</nativeMethods>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -20,7 +20,7 @@ obj11.Name = "notifyAll";
|
||||||
obj11.Sig = "()V";
|
obj11.Sig = "()V";
|
||||||
obj11.Modifiers = (MapXml.MapModifiers)17;
|
obj11.Modifiers = (MapXml.MapModifiers)17;
|
||||||
MapXml.Redirect obj15 = new MapXml.Redirect();
|
MapXml.Redirect obj15 = new MapXml.Redirect();
|
||||||
obj15.Class = "System.Threading.Monitor";
|
obj15.Class = "System.Threading.Monitor, mscorlib";
|
||||||
obj15.Name = "PulseAll";
|
obj15.Name = "PulseAll";
|
||||||
obj15.Sig = "(Ljava.lang.Object;)V";
|
obj15.Sig = "(Ljava.lang.Object;)V";
|
||||||
obj15.Type = "static";
|
obj15.Type = "static";
|
||||||
|
@ -31,7 +31,7 @@ obj20.Name = "notify";
|
||||||
obj20.Sig = "()V";
|
obj20.Sig = "()V";
|
||||||
obj20.Modifiers = (MapXml.MapModifiers)17;
|
obj20.Modifiers = (MapXml.MapModifiers)17;
|
||||||
MapXml.Redirect obj24 = new MapXml.Redirect();
|
MapXml.Redirect obj24 = new MapXml.Redirect();
|
||||||
obj24.Class = "System.Threading.Monitor";
|
obj24.Class = "System.Threading.Monitor, mscorlib";
|
||||||
obj24.Name = "Pulse";
|
obj24.Name = "Pulse";
|
||||||
obj24.Sig = "(Ljava.lang.Object;)V";
|
obj24.Sig = "(Ljava.lang.Object;)V";
|
||||||
obj24.Type = "static";
|
obj24.Type = "static";
|
||||||
|
@ -44,7 +44,7 @@ obj29.Modifiers = (MapXml.MapModifiers)17;
|
||||||
MapXml.InstructionList obj33 = new MapXml.InstructionList();
|
MapXml.InstructionList obj33 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj34 = new MapXml.Instruction[2];
|
MapXml.Instruction[] obj34 = new MapXml.Instruction[2];
|
||||||
MapXml.Call obj35 = new MapXml.Call();
|
MapXml.Call obj35 = new MapXml.Call();
|
||||||
obj35.type = "System.Threading.Monitor";
|
obj35.type = "System.Threading.Monitor, mscorlib";
|
||||||
obj35.Name = "Wait";
|
obj35.Name = "Wait";
|
||||||
obj35.Sig = "(Ljava.lang.Object;)Z";
|
obj35.Sig = "(Ljava.lang.Object;)Z";
|
||||||
obj34[0] = obj35;
|
obj34[0] = obj35;
|
||||||
|
@ -55,7 +55,7 @@ obj29.invokevirtual = obj33;
|
||||||
MapXml.InstructionList obj40 = new MapXml.InstructionList();
|
MapXml.InstructionList obj40 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj41 = new MapXml.Instruction[2];
|
MapXml.Instruction[] obj41 = new MapXml.Instruction[2];
|
||||||
MapXml.Call obj42 = new MapXml.Call();
|
MapXml.Call obj42 = new MapXml.Call();
|
||||||
obj42.type = "System.Threading.Monitor";
|
obj42.type = "System.Threading.Monitor, mscorlib";
|
||||||
obj42.Name = "Wait";
|
obj42.Name = "Wait";
|
||||||
obj42.Sig = "(Ljava.lang.Object;)Z";
|
obj42.Sig = "(Ljava.lang.Object;)Z";
|
||||||
obj41[0] = obj42;
|
obj41[0] = obj42;
|
||||||
|
@ -138,7 +138,7 @@ MapXml.Instruction[] obj99 = new MapXml.Instruction[7];
|
||||||
MapXml.Dup obj100 = new MapXml.Dup();
|
MapXml.Dup obj100 = new MapXml.Dup();
|
||||||
obj99[0] = obj100;
|
obj99[0] = obj100;
|
||||||
MapXml.IsInst obj101 = new MapXml.IsInst();
|
MapXml.IsInst obj101 = new MapXml.IsInst();
|
||||||
obj101.type = "java.lang.Cloneable";
|
obj101.Class = "java.lang.Cloneable";
|
||||||
obj99[1] = obj101;
|
obj99[1] = obj101;
|
||||||
MapXml.BrTrue obj103 = new MapXml.BrTrue();
|
MapXml.BrTrue obj103 = new MapXml.BrTrue();
|
||||||
obj103.Name = "ok";
|
obj103.Name = "ok";
|
||||||
|
@ -216,13 +216,13 @@ MapXml.Instruction[] obj152 = new MapXml.Instruction[9];
|
||||||
MapXml.Dup obj153 = new MapXml.Dup();
|
MapXml.Dup obj153 = new MapXml.Dup();
|
||||||
obj152[0] = obj153;
|
obj152[0] = obj153;
|
||||||
MapXml.IsInst obj154 = new MapXml.IsInst();
|
MapXml.IsInst obj154 = new MapXml.IsInst();
|
||||||
obj154.type = "System.String";
|
obj154.type = "System.String, mscorlib";
|
||||||
obj152[1] = obj154;
|
obj152[1] = obj154;
|
||||||
MapXml.BrFalse obj156 = new MapXml.BrFalse();
|
MapXml.BrFalse obj156 = new MapXml.BrFalse();
|
||||||
obj156.Name = "skip";
|
obj156.Name = "skip";
|
||||||
obj152[2] = obj156;
|
obj152[2] = obj156;
|
||||||
MapXml.Castclass obj158 = new MapXml.Castclass();
|
MapXml.Castclass obj158 = new MapXml.Castclass();
|
||||||
obj158.type = "System.String";
|
obj158.type = "System.String, mscorlib";
|
||||||
obj152[3] = obj158;
|
obj152[3] = obj158;
|
||||||
MapXml.Call obj160 = new MapXml.Call();
|
MapXml.Call obj160 = new MapXml.Call();
|
||||||
obj160.Class = "java.lang.StringHelper";
|
obj160.Class = "java.lang.StringHelper";
|
||||||
|
@ -268,7 +268,7 @@ obj2.Methods = obj10;
|
||||||
obj1[0] = obj2;
|
obj1[0] = obj2;
|
||||||
MapXml.Class obj187 = new MapXml.Class();
|
MapXml.Class obj187 = new MapXml.Class();
|
||||||
obj187.Name = "java.lang.String";
|
obj187.Name = "java.lang.String";
|
||||||
obj187.Type = "System.String";
|
obj187.Type = "System.String, mscorlib";
|
||||||
obj187.Modifiers = (MapXml.MapModifiers)17;
|
obj187.Modifiers = (MapXml.MapModifiers)17;
|
||||||
MapXml.Constructor[] obj191 = new MapXml.Constructor[12];
|
MapXml.Constructor[] obj191 = new MapXml.Constructor[12];
|
||||||
MapXml.Constructor obj192 = new MapXml.Constructor();
|
MapXml.Constructor obj192 = new MapXml.Constructor();
|
||||||
|
@ -280,7 +280,7 @@ MapXml.Ldstr obj197 = new MapXml.Ldstr();
|
||||||
obj197.Value = "";
|
obj197.Value = "";
|
||||||
obj196[0] = obj197;
|
obj196[0] = obj197;
|
||||||
MapXml.Call obj199 = new MapXml.Call();
|
MapXml.Call obj199 = new MapXml.Call();
|
||||||
obj199.type = "System.String";
|
obj199.type = "System.String, mscorlib";
|
||||||
obj199.Name = "Copy";
|
obj199.Name = "Copy";
|
||||||
obj196[1] = obj199;
|
obj196[1] = obj199;
|
||||||
obj195.invoke = obj196;
|
obj195.invoke = obj196;
|
||||||
|
@ -308,7 +308,7 @@ MapXml.Constructor obj216 = new MapXml.Constructor();
|
||||||
obj216.Sig = "(Ljava.lang.String;)V";
|
obj216.Sig = "(Ljava.lang.String;)V";
|
||||||
obj216.Modifiers = (MapXml.MapModifiers)1;
|
obj216.Modifiers = (MapXml.MapModifiers)1;
|
||||||
MapXml.Redirect obj219 = new MapXml.Redirect();
|
MapXml.Redirect obj219 = new MapXml.Redirect();
|
||||||
obj219.Class = "System.String";
|
obj219.Class = "System.String, mscorlib";
|
||||||
obj219.Name = "Copy";
|
obj219.Name = "Copy";
|
||||||
obj219.Sig = "(Ljava.lang.String;)Ljava.lang.String;";
|
obj219.Sig = "(Ljava.lang.String;)Ljava.lang.String;";
|
||||||
obj219.Type = "static";
|
obj219.Type = "static";
|
||||||
|
@ -808,7 +808,7 @@ obj606.Modifiers = (MapXml.MapModifiers)9;
|
||||||
MapXml.InstructionList obj610 = new MapXml.InstructionList();
|
MapXml.InstructionList obj610 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj611 = new MapXml.Instruction[1];
|
MapXml.Instruction[] obj611 = new MapXml.Instruction[1];
|
||||||
MapXml.NewObj obj612 = new MapXml.NewObj();
|
MapXml.NewObj obj612 = new MapXml.NewObj();
|
||||||
obj612.type = "System.String";
|
obj612.type = "System.String, mscorlib";
|
||||||
obj612.Name = ".ctor";
|
obj612.Name = ".ctor";
|
||||||
obj612.Sig = "([C)V";
|
obj612.Sig = "([C)V";
|
||||||
obj611[0] = obj612;
|
obj611[0] = obj612;
|
||||||
|
@ -822,7 +822,7 @@ obj616.Modifiers = (MapXml.MapModifiers)9;
|
||||||
MapXml.InstructionList obj620 = new MapXml.InstructionList();
|
MapXml.InstructionList obj620 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj621 = new MapXml.Instruction[1];
|
MapXml.Instruction[] obj621 = new MapXml.Instruction[1];
|
||||||
MapXml.NewObj obj622 = new MapXml.NewObj();
|
MapXml.NewObj obj622 = new MapXml.NewObj();
|
||||||
obj622.type = "System.String";
|
obj622.type = "System.String, mscorlib";
|
||||||
obj622.Name = ".ctor";
|
obj622.Name = ".ctor";
|
||||||
obj622.Sig = "([CII)V";
|
obj622.Sig = "([CII)V";
|
||||||
obj621[0] = obj622;
|
obj621[0] = obj622;
|
||||||
|
@ -908,7 +908,7 @@ obj682.Modifiers = (MapXml.MapModifiers)1;
|
||||||
MapXml.InstructionList obj685 = new MapXml.InstructionList();
|
MapXml.InstructionList obj685 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj686 = new MapXml.Instruction[2];
|
MapXml.Instruction[] obj686 = new MapXml.Instruction[2];
|
||||||
MapXml.Call obj687 = new MapXml.Call();
|
MapXml.Call obj687 = new MapXml.Call();
|
||||||
obj687.type = "ExceptionHelper";
|
obj687.type = "ExceptionHelper, ik.vm.net";
|
||||||
obj687.Name = "get_NullString";
|
obj687.Name = "get_NullString";
|
||||||
obj686[0] = obj687;
|
obj686[0] = obj687;
|
||||||
MapXml.Call obj690 = new MapXml.Call();
|
MapXml.Call obj690 = new MapXml.Call();
|
||||||
|
@ -925,7 +925,7 @@ obj694.Modifiers = (MapXml.MapModifiers)1;
|
||||||
MapXml.InstructionList obj697 = new MapXml.InstructionList();
|
MapXml.InstructionList obj697 = new MapXml.InstructionList();
|
||||||
MapXml.Instruction[] obj698 = new MapXml.Instruction[2];
|
MapXml.Instruction[] obj698 = new MapXml.Instruction[2];
|
||||||
MapXml.Call obj699 = new MapXml.Call();
|
MapXml.Call obj699 = new MapXml.Call();
|
||||||
obj699.type = "ExceptionHelper";
|
obj699.type = "ExceptionHelper, ik.vm.net";
|
||||||
obj699.Name = "FilterMessage";
|
obj699.Name = "FilterMessage";
|
||||||
obj698[0] = obj699;
|
obj698[0] = obj699;
|
||||||
MapXml.Call obj702 = new MapXml.Call();
|
MapXml.Call obj702 = new MapXml.Call();
|
||||||
|
@ -946,7 +946,7 @@ obj711.Name = "x";
|
||||||
obj711.type = "System.Exception";
|
obj711.type = "System.Exception";
|
||||||
obj710[0] = obj711;
|
obj710[0] = obj711;
|
||||||
MapXml.Call obj714 = new MapXml.Call();
|
MapXml.Call obj714 = new MapXml.Call();
|
||||||
obj714.type = "ExceptionHelper";
|
obj714.type = "ExceptionHelper, ik.vm.net";
|
||||||
obj714.Name = "FilterMessage";
|
obj714.Name = "FilterMessage";
|
||||||
obj710[1] = obj714;
|
obj710[1] = obj714;
|
||||||
MapXml.LdLoc obj717 = new MapXml.LdLoc();
|
MapXml.LdLoc obj717 = new MapXml.LdLoc();
|
||||||
|
@ -973,7 +973,7 @@ MapXml.LdLoc obj731 = new MapXml.LdLoc();
|
||||||
obj731.Name = "x";
|
obj731.Name = "x";
|
||||||
obj727[1] = obj731;
|
obj727[1] = obj731;
|
||||||
MapXml.Call obj733 = new MapXml.Call();
|
MapXml.Call obj733 = new MapXml.Call();
|
||||||
obj733.type = "ExceptionHelper";
|
obj733.type = "ExceptionHelper, ik.vm.net";
|
||||||
obj733.Name = "GetMessageFromCause";
|
obj733.Name = "GetMessageFromCause";
|
||||||
obj727[2] = obj733;
|
obj727[2] = obj733;
|
||||||
MapXml.LdLoc obj736 = new MapXml.LdLoc();
|
MapXml.LdLoc obj736 = new MapXml.LdLoc();
|
||||||
|
@ -995,7 +995,7 @@ obj743.Sig = "()V";
|
||||||
obj743.Modifiers = (MapXml.MapModifiers)1;
|
obj743.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj743.Type = "virtual";
|
obj743.Type = "virtual";
|
||||||
MapXml.Redirect obj748 = new MapXml.Redirect();
|
MapXml.Redirect obj748 = new MapXml.Redirect();
|
||||||
obj748.Class = "ExceptionHelper";
|
obj748.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj748.Sig = "(Ljava.lang.Throwable;)V";
|
obj748.Sig = "(Ljava.lang.Throwable;)V";
|
||||||
obj748.Type = "static";
|
obj748.Type = "static";
|
||||||
obj743.redirect = obj748;
|
obj743.redirect = obj748;
|
||||||
|
@ -1006,7 +1006,7 @@ obj752.Sig = "(Ljava.io.PrintStream;)V";
|
||||||
obj752.Modifiers = (MapXml.MapModifiers)1;
|
obj752.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj752.Type = "virtual";
|
obj752.Type = "virtual";
|
||||||
MapXml.Redirect obj757 = new MapXml.Redirect();
|
MapXml.Redirect obj757 = new MapXml.Redirect();
|
||||||
obj757.Class = "ExceptionHelper";
|
obj757.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj757.Sig = "(Ljava.lang.Throwable;Ljava.lang.Object;)V";
|
obj757.Sig = "(Ljava.lang.Throwable;Ljava.lang.Object;)V";
|
||||||
obj757.Type = "static";
|
obj757.Type = "static";
|
||||||
obj752.redirect = obj757;
|
obj752.redirect = obj757;
|
||||||
|
@ -1017,7 +1017,7 @@ obj761.Sig = "(Ljava.io.PrintWriter;)V";
|
||||||
obj761.Modifiers = (MapXml.MapModifiers)1;
|
obj761.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj761.Type = "virtual";
|
obj761.Type = "virtual";
|
||||||
MapXml.Redirect obj766 = new MapXml.Redirect();
|
MapXml.Redirect obj766 = new MapXml.Redirect();
|
||||||
obj766.Class = "ExceptionHelper";
|
obj766.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj766.Sig = "(Ljava.lang.Throwable;Ljava.lang.Object;)V";
|
obj766.Sig = "(Ljava.lang.Throwable;Ljava.lang.Object;)V";
|
||||||
obj766.Type = "static";
|
obj766.Type = "static";
|
||||||
obj761.redirect = obj766;
|
obj761.redirect = obj766;
|
||||||
|
@ -1028,7 +1028,7 @@ obj770.Sig = "()Ljava.lang.String;";
|
||||||
obj770.Modifiers = (MapXml.MapModifiers)1;
|
obj770.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj770.Type = "virtual";
|
obj770.Type = "virtual";
|
||||||
MapXml.Redirect obj775 = new MapXml.Redirect();
|
MapXml.Redirect obj775 = new MapXml.Redirect();
|
||||||
obj775.Class = "ExceptionHelper";
|
obj775.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj775.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
obj775.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
||||||
obj775.Type = "static";
|
obj775.Type = "static";
|
||||||
obj770.redirect = obj775;
|
obj770.redirect = obj775;
|
||||||
|
@ -1039,7 +1039,7 @@ obj779.Sig = "()Ljava.lang.String;";
|
||||||
obj779.Modifiers = (MapXml.MapModifiers)1;
|
obj779.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj779.Type = "virtual";
|
obj779.Type = "virtual";
|
||||||
MapXml.Redirect obj784 = new MapXml.Redirect();
|
MapXml.Redirect obj784 = new MapXml.Redirect();
|
||||||
obj784.Class = "ExceptionHelper";
|
obj784.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj784.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
obj784.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
||||||
obj784.Type = "static";
|
obj784.Type = "static";
|
||||||
obj779.redirect = obj784;
|
obj779.redirect = obj784;
|
||||||
|
@ -1050,7 +1050,7 @@ obj788.Sig = "()Ljava.lang.Throwable;";
|
||||||
obj788.Modifiers = (MapXml.MapModifiers)1;
|
obj788.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj788.Type = "virtual";
|
obj788.Type = "virtual";
|
||||||
MapXml.Redirect obj793 = new MapXml.Redirect();
|
MapXml.Redirect obj793 = new MapXml.Redirect();
|
||||||
obj793.Class = "ExceptionHelper";
|
obj793.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj793.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
obj793.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
||||||
obj793.Type = "static";
|
obj793.Type = "static";
|
||||||
obj788.redirect = obj793;
|
obj788.redirect = obj793;
|
||||||
|
@ -1061,7 +1061,7 @@ obj797.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
||||||
obj797.Modifiers = (MapXml.MapModifiers)1;
|
obj797.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj797.Type = "virtual";
|
obj797.Type = "virtual";
|
||||||
MapXml.Redirect obj802 = new MapXml.Redirect();
|
MapXml.Redirect obj802 = new MapXml.Redirect();
|
||||||
obj802.Class = "ExceptionHelper";
|
obj802.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj802.Sig = "(Ljava.lang.Throwable;Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
obj802.Sig = "(Ljava.lang.Throwable;Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
||||||
obj802.Type = "static";
|
obj802.Type = "static";
|
||||||
obj797.redirect = obj802;
|
obj797.redirect = obj802;
|
||||||
|
@ -1072,7 +1072,7 @@ obj806.Sig = "()Ljava.lang.Throwable;";
|
||||||
obj806.Modifiers = (MapXml.MapModifiers)1;
|
obj806.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj806.Type = "virtual";
|
obj806.Type = "virtual";
|
||||||
MapXml.Redirect obj811 = new MapXml.Redirect();
|
MapXml.Redirect obj811 = new MapXml.Redirect();
|
||||||
obj811.Class = "ExceptionHelper";
|
obj811.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj811.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
obj811.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
|
||||||
obj811.Type = "static";
|
obj811.Type = "static";
|
||||||
obj806.redirect = obj811;
|
obj806.redirect = obj811;
|
||||||
|
@ -1083,7 +1083,7 @@ obj815.Sig = "()[Ljava.lang.StackTraceElement;";
|
||||||
obj815.Modifiers = (MapXml.MapModifiers)1;
|
obj815.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj815.Type = "virtual";
|
obj815.Type = "virtual";
|
||||||
MapXml.Redirect obj820 = new MapXml.Redirect();
|
MapXml.Redirect obj820 = new MapXml.Redirect();
|
||||||
obj820.Class = "ExceptionHelper";
|
obj820.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj820.Sig = "(Ljava.lang.Throwable;)[Ljava.lang.StackTraceElement;";
|
obj820.Sig = "(Ljava.lang.Throwable;)[Ljava.lang.StackTraceElement;";
|
||||||
obj820.Type = "static";
|
obj820.Type = "static";
|
||||||
obj815.redirect = obj820;
|
obj815.redirect = obj820;
|
||||||
|
@ -1094,7 +1094,7 @@ obj824.Sig = "([Ljava.lang.StackTraceElement;)V";
|
||||||
obj824.Modifiers = (MapXml.MapModifiers)1;
|
obj824.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj824.Type = "virtual";
|
obj824.Type = "virtual";
|
||||||
MapXml.Redirect obj829 = new MapXml.Redirect();
|
MapXml.Redirect obj829 = new MapXml.Redirect();
|
||||||
obj829.Class = "ExceptionHelper";
|
obj829.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj829.Sig = "(Ljava.lang.Throwable;[Ljava.lang.StackTraceElement;)V";
|
obj829.Sig = "(Ljava.lang.Throwable;[Ljava.lang.StackTraceElement;)V";
|
||||||
obj829.Type = "static";
|
obj829.Type = "static";
|
||||||
obj824.redirect = obj829;
|
obj824.redirect = obj829;
|
||||||
|
@ -1105,7 +1105,7 @@ obj833.Sig = "()Ljava.lang.String;";
|
||||||
obj833.Modifiers = (MapXml.MapModifiers)1;
|
obj833.Modifiers = (MapXml.MapModifiers)1;
|
||||||
obj833.Type = "virtual";
|
obj833.Type = "virtual";
|
||||||
MapXml.Redirect obj838 = new MapXml.Redirect();
|
MapXml.Redirect obj838 = new MapXml.Redirect();
|
||||||
obj838.Class = "ExceptionHelper";
|
obj838.Class = "ExceptionHelper, ik.vm.net";
|
||||||
obj838.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
obj838.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
|
||||||
obj838.Type = "static";
|
obj838.Type = "static";
|
||||||
obj833.redirect = obj838;
|
obj833.redirect = obj838;
|
||||||
|
@ -1189,7 +1189,7 @@ obj860[7] = obj893;
|
||||||
obj856.Methods = obj860;
|
obj856.Methods = obj860;
|
||||||
obj1[4] = obj856;
|
obj1[4] = obj856;
|
||||||
obj0.remappings = obj1;
|
obj0.remappings = obj1;
|
||||||
MapXml.Class[] obj899 = new MapXml.Class[3];
|
MapXml.Class[] obj899 = new MapXml.Class[4];
|
||||||
MapXml.Class obj900 = new MapXml.Class();
|
MapXml.Class obj900 = new MapXml.Class();
|
||||||
obj900.Name = "java.lang.Runtime";
|
obj900.Name = "java.lang.Runtime";
|
||||||
obj900.Modifiers = (MapXml.MapModifiers)0;
|
obj900.Modifiers = (MapXml.MapModifiers)0;
|
||||||
|
@ -1260,6 +1260,34 @@ obj936.invoke = obj940;
|
||||||
obj935[0] = obj936;
|
obj935[0] = obj936;
|
||||||
obj932.Methods = obj935;
|
obj932.Methods = obj935;
|
||||||
obj899[2] = obj932;
|
obj899[2] = obj932;
|
||||||
|
MapXml.Class obj946 = new MapXml.Class();
|
||||||
|
obj946.Name = "ikvm.lang.ByteArrayHack";
|
||||||
|
obj946.Modifiers = (MapXml.MapModifiers)0;
|
||||||
|
MapXml.Method[] obj949 = new MapXml.Method[2];
|
||||||
|
MapXml.Method obj950 = new MapXml.Method();
|
||||||
|
obj950.Name = "cast";
|
||||||
|
obj950.Sig = "([B)[Lcli.System.Byte;";
|
||||||
|
obj950.Modifiers = (MapXml.MapModifiers)0;
|
||||||
|
MapXml.Instruction[] obj954 = new MapXml.Instruction[2];
|
||||||
|
MapXml.LdArg_0 obj955 = new MapXml.LdArg_0();
|
||||||
|
obj954[0] = obj955;
|
||||||
|
MapXml.Ret obj956 = new MapXml.Ret();
|
||||||
|
obj954[1] = obj956;
|
||||||
|
obj950.invoke = obj954;
|
||||||
|
obj949[0] = obj950;
|
||||||
|
MapXml.Method obj957 = new MapXml.Method();
|
||||||
|
obj957.Name = "cast";
|
||||||
|
obj957.Sig = "([Lcli.System.Byte;)[B";
|
||||||
|
obj957.Modifiers = (MapXml.MapModifiers)0;
|
||||||
|
MapXml.Instruction[] obj961 = new MapXml.Instruction[2];
|
||||||
|
MapXml.LdArg_0 obj962 = new MapXml.LdArg_0();
|
||||||
|
obj961[0] = obj962;
|
||||||
|
MapXml.Ret obj963 = new MapXml.Ret();
|
||||||
|
obj961[1] = obj963;
|
||||||
|
obj957.invoke = obj961;
|
||||||
|
obj949[1] = obj957;
|
||||||
|
obj946.Methods = obj949;
|
||||||
|
obj899[3] = obj946;
|
||||||
obj0.nativeMethods = obj899;
|
obj0.nativeMethods = obj899;
|
||||||
return obj0;
|
return obj0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace MapXml
|
||||||
{
|
{
|
||||||
Debug.Assert(Class == null && type != null);
|
Debug.Assert(Class == null && type != null);
|
||||||
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
|
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
|
||||||
emitter = CodeEmitter.Create(opcode, ClassLoaderWrapper.GetType(type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null));
|
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -77,11 +77,11 @@ namespace MapXml
|
||||||
if(Sig != null)
|
if(Sig != null)
|
||||||
{
|
{
|
||||||
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
|
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
|
||||||
emitter = CodeEmitter.Create(opcode, ClassLoaderWrapper.GetType(type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null));
|
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emitter = CodeEmitter.Create(opcode, ClassLoaderWrapper.GetType(type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static));
|
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ namespace MapXml
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typeType = ClassLoaderWrapper.GetType(type);
|
typeType = Type.GetType(type, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ilgen.Emit(opcode, typeType != null ? typeType : typeWrapper.Type);
|
ilgen.Emit(opcode, typeType != null ? typeType : typeWrapper.Type);
|
||||||
|
@ -296,7 +296,7 @@ namespace MapXml
|
||||||
Debug.Assert(Class == null ^ type == null);
|
Debug.Assert(Class == null ^ type == null);
|
||||||
if(type != null)
|
if(type != null)
|
||||||
{
|
{
|
||||||
typeType = ClassLoaderWrapper.GetType(type);
|
typeType = Type.GetType(type, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System.Collections;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using OpenSystem.Java;
|
using OpenSystem.Java;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
public class JVM
|
public class JVM
|
||||||
{
|
{
|
||||||
|
@ -145,7 +146,6 @@ public class JVM
|
||||||
private string assembly;
|
private string assembly;
|
||||||
private string path;
|
private string path;
|
||||||
private AssemblyBuilder assemblyBuilder;
|
private AssemblyBuilder assemblyBuilder;
|
||||||
private ModuleBuilder moduleBuilder;
|
|
||||||
|
|
||||||
internal CompilerClassLoader(string path, string assembly, Hashtable classes)
|
internal CompilerClassLoader(string path, string assembly, Hashtable classes)
|
||||||
: base(null)
|
: base(null)
|
||||||
|
@ -157,26 +157,23 @@ public class JVM
|
||||||
|
|
||||||
protected override ModuleBuilder CreateModuleBuilder()
|
protected override ModuleBuilder CreateModuleBuilder()
|
||||||
{
|
{
|
||||||
if(moduleBuilder == null)
|
AssemblyName name = new AssemblyName();
|
||||||
|
name.Name = assembly;
|
||||||
|
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
|
||||||
|
CustomAttributeBuilder ikvmAssemblyAttr = new CustomAttributeBuilder(typeof(JavaAssemblyAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
|
||||||
|
assemblyBuilder.SetCustomAttribute(ikvmAssemblyAttr);
|
||||||
|
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(path, JVM.Debug);
|
||||||
|
if(JVM.Debug)
|
||||||
{
|
{
|
||||||
AssemblyName name = new AssemblyName();
|
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, true });
|
||||||
name.Name = assembly;
|
moduleBuilder.SetCustomAttribute(debugAttr);
|
||||||
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
|
|
||||||
CustomAttributeBuilder ikvmAssemblyAttr = new CustomAttributeBuilder(typeof(JavaAssemblyAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
|
|
||||||
assemblyBuilder.SetCustomAttribute(ikvmAssemblyAttr);
|
|
||||||
moduleBuilder = assemblyBuilder.DefineDynamicModule(path, JVM.Debug);
|
|
||||||
if(JVM.Debug)
|
|
||||||
{
|
|
||||||
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, true });
|
|
||||||
moduleBuilder.SetCustomAttribute(debugAttr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return moduleBuilder;
|
return moduleBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override TypeWrapper GetBootstrapType(string name)
|
internal override TypeWrapper GetTypeWrapperCompilerHook(string name)
|
||||||
{
|
{
|
||||||
TypeWrapper type = base.GetBootstrapType(name);
|
TypeWrapper type = base.GetTypeWrapperCompilerHook(name);
|
||||||
if(type == null)
|
if(type == null)
|
||||||
{
|
{
|
||||||
ClassFile f = (ClassFile)classes[name];
|
ClassFile f = (ClassFile)classes[name];
|
||||||
|
@ -201,11 +198,7 @@ public class JVM
|
||||||
|
|
||||||
internal void AddResources(Hashtable resources)
|
internal void AddResources(Hashtable resources)
|
||||||
{
|
{
|
||||||
if(moduleBuilder == null)
|
ModuleBuilder moduleBuilder = this.ModuleBuilder;
|
||||||
{
|
|
||||||
// this happens if the module contains no clases
|
|
||||||
CreateModuleBuilder();
|
|
||||||
}
|
|
||||||
foreach(DictionaryEntry d in resources)
|
foreach(DictionaryEntry d in resources)
|
||||||
{
|
{
|
||||||
byte[] buf = (byte[])d.Value;
|
byte[] buf = (byte[])d.Value;
|
||||||
|
@ -218,7 +211,7 @@ public class JVM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Compile(string path, string assembly, string mainClass, PEFileKinds target, byte[][] classes, string[] references, bool nojni, Hashtable resources)
|
public static void Compile(string path, string assembly, string mainClass, PEFileKinds target, byte[][] classes, string[] references, bool nojni, Hashtable resources, string[] classesToExclude)
|
||||||
{
|
{
|
||||||
isStaticCompiler = true;
|
isStaticCompiler = true;
|
||||||
noJniStubs = nojni;
|
noJniStubs = nojni;
|
||||||
|
@ -232,12 +225,29 @@ public class JVM
|
||||||
{
|
{
|
||||||
ClassFile f = new ClassFile(classes[i], 0, classes[i].Length, null);
|
ClassFile f = new ClassFile(classes[i], 0, classes[i].Length, null);
|
||||||
string name = f.Name;
|
string name = f.Name;
|
||||||
|
bool excluded = false;
|
||||||
|
for(int j = 0; j < classesToExclude.Length; j++)
|
||||||
|
{
|
||||||
|
if(Regex.IsMatch(name, classesToExclude[j]))
|
||||||
|
{
|
||||||
|
excluded = true;
|
||||||
|
//Console.WriteLine("Excluding: {0} on rule {1}", name, (String)classesToExclude[j]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (!excluded)
|
||||||
|
// Console.WriteLine("Adding: {0}", name);
|
||||||
|
// else
|
||||||
|
// Console.WriteLine("Not Adding: {0}", name);
|
||||||
if(h.ContainsKey(name))
|
if(h.ContainsKey(name))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Duplicate class name: {0}", name);
|
Console.Error.WriteLine("Duplicate class name: {0}", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
h[name] = f;
|
if(!excluded)
|
||||||
|
{
|
||||||
|
h[name] = f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure all inner classes have a reference to their outer class
|
// make sure all inner classes have a reference to their outer class
|
||||||
|
@ -246,7 +256,7 @@ public class JVM
|
||||||
foreach(ClassFile classFile in h.Values)
|
foreach(ClassFile classFile in h.Values)
|
||||||
{
|
{
|
||||||
// don't handle inner classes for NetExp types
|
// don't handle inner classes for NetExp types
|
||||||
if(classFile.NetExpTypeAttribute == null)
|
if(classFile.NetExpAssemblyAttribute == null)
|
||||||
{
|
{
|
||||||
ClassFile.InnerClass[] innerClasses = classFile.InnerClasses;
|
ClassFile.InnerClass[] innerClasses = classFile.InnerClasses;
|
||||||
if(innerClasses != null)
|
if(innerClasses != null)
|
||||||
|
|
Двоичные данные
classpath/System.Xml.jar
Двоичные данные
classpath/System.Xml.jar
Двоичный файл не отображается.
Двоичные данные
classpath/System.jar
Двоичные данные
classpath/System.jar
Двоичный файл не отображается.
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
package gnu.java.net.protocol.ikvmres;
|
package gnu.java.net.protocol.ikvmres;
|
||||||
|
|
||||||
import system.io.*;
|
import cli.System.IO.*;
|
||||||
import system.reflection.*;
|
import cli.System.Reflection.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -56,8 +56,8 @@ class IkvmresURLConnection extends URLConnection
|
||||||
{
|
{
|
||||||
throw new IOException("resource " + resource + " not found in assembly " + assembly);
|
throw new IOException("resource " + resource + " not found in assembly " + assembly);
|
||||||
}
|
}
|
||||||
byte[] b = new byte[system.runtime.interopservices.Marshal.SizeOf(fi.get_FieldType())];
|
byte[] b = new byte[cli.System.Runtime.InteropServices.Marshal.SizeOf(fi.get_FieldType())];
|
||||||
system.runtime.compilerservices.RuntimeHelpers.InitializeArray((system.Array)(Object)b, fi.get_FieldHandle());
|
cli.System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray((cli.System.Array)(Object)b, fi.get_FieldHandle());
|
||||||
inputStream = new ByteArrayInputStream(b);
|
inputStream = new ByteArrayInputStream(b);
|
||||||
connected = true;
|
connected = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package ikvm.lang;
|
||||||
|
|
||||||
|
public final class ByteArrayHack
|
||||||
|
{
|
||||||
|
private ByteArrayHack() {}
|
||||||
|
|
||||||
|
public static native cli.System.Byte[] cast(byte[] b);
|
||||||
|
public static native byte[] cast(cli.System.Byte[] b);
|
||||||
|
}
|
|
@ -26,14 +26,14 @@ package ikvm.lang;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import system.text.StringBuilder;
|
import cli.System.Text.StringBuilder;
|
||||||
import system.diagnostics.ProcessStartInfo;
|
import cli.System.Diagnostics.ProcessStartInfo;
|
||||||
|
|
||||||
public class DotNetProcess extends Process
|
public class DotNetProcess extends Process
|
||||||
{
|
{
|
||||||
private system.diagnostics.Process proc;
|
private cli.System.Diagnostics.Process proc;
|
||||||
|
|
||||||
private DotNetProcess(system.diagnostics.Process proc)
|
private DotNetProcess(cli.System.Diagnostics.Process proc)
|
||||||
{
|
{
|
||||||
this.proc = proc;
|
this.proc = proc;
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,10 @@ public class DotNetProcess extends Process
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.InvalidOperationException();
|
if(false) throw new cli.System.InvalidOperationException();
|
||||||
proc.Kill();
|
proc.Kill();
|
||||||
}
|
}
|
||||||
catch(system.InvalidOperationException x)
|
catch(cli.System.InvalidOperationException x)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,6 @@ public class DotNetProcess extends Process
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO map the exceptions
|
// TODO map the exceptions
|
||||||
return new DotNetProcess(system.diagnostics.Process.Start(si));
|
return new DotNetProcess(cli.System.Diagnostics.Process.Start(si));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,9 @@ exception statement from your version. */
|
||||||
|
|
||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
import system.Console;
|
import cli.System.Console;
|
||||||
import system.io.*;
|
import cli.System.IO.*;
|
||||||
|
import ikvm.lang.ByteArrayHack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents an opaque file handle as a Java class. It should
|
* This class represents an opaque file handle as a Java class. It should
|
||||||
|
@ -91,12 +92,12 @@ public final class FileDescriptor
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
stream.Flush();
|
stream.Flush();
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new SyncFailedException(x.get_Message());
|
throw new SyncFailedException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,11 +116,11 @@ public final class FileDescriptor
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
stream.Close();
|
stream.Close();
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stream = null;
|
stream = null;
|
||||||
|
@ -171,23 +172,23 @@ public final class FileDescriptor
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid mode value: " + mode);
|
throw new IllegalArgumentException("Invalid mode value: " + mode);
|
||||||
}
|
}
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
if(false) throw new system.security.SecurityException();
|
if(false) throw new cli.System.Security.SecurityException();
|
||||||
if(false) throw new system.UnauthorizedAccessException();
|
if(false) throw new cli.System.UnauthorizedAccessException();
|
||||||
stream = system.io.File.Open(demanglePath(path), fileMode, fileAccess, FileShare.ReadWrite);
|
stream = cli.System.IO.File.Open(demanglePath(path), FileMode.wrap(fileMode), FileAccess.wrap(fileAccess), FileShare.wrap(FileShare.ReadWrite));
|
||||||
}
|
}
|
||||||
catch(system.security.SecurityException x1)
|
catch(cli.System.Security.SecurityException x1)
|
||||||
{
|
{
|
||||||
throw new SecurityException(x1.get_Message());
|
throw new SecurityException(x1.getMessage());
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x2)
|
catch(cli.System.IO.IOException x2)
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException(x2.get_Message());
|
throw new FileNotFoundException(x2.getMessage());
|
||||||
}
|
}
|
||||||
catch(system.UnauthorizedAccessException x3)
|
catch(cli.System.UnauthorizedAccessException x3)
|
||||||
{
|
{
|
||||||
// this is caused by "name" being a directory instead of a file
|
// this is caused by "name" being a directory instead of a file
|
||||||
throw new FileNotFoundException(x3.get_Message());
|
throw new FileNotFoundException(x3.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -199,12 +200,12 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
return stream.get_Position();
|
return stream.get_Position();
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -216,12 +217,12 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
return stream.get_Length();
|
return stream.get_Length();
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -237,12 +238,12 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
stream.SetLength(len);
|
stream.SetLength(len);
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -257,17 +258,17 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
long newpos = stream.Seek(offset, whence);
|
long newpos = stream.Seek(offset, SeekOrigin.wrap(whence));
|
||||||
if(stopAtEof && newpos > stream.get_Length())
|
if(stopAtEof && newpos > stream.get_Length())
|
||||||
{
|
{
|
||||||
newpos = stream.Seek(0, SeekOrigin.End);
|
newpos = stream.Seek(0, SeekOrigin.wrap(SeekOrigin.End));
|
||||||
}
|
}
|
||||||
return newpos;
|
return newpos;
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -279,12 +280,12 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
return stream.ReadByte();
|
return stream.ReadByte();
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -305,37 +306,25 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
int count = stream.Read(buf, offset, len);
|
int count = stream.Read(ByteArrayHack.cast(buf), offset, len);
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
{
|
{
|
||||||
count = -1;
|
count = -1;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void write(int b) throws IOException
|
synchronized void write(int b) throws IOException
|
||||||
{
|
{
|
||||||
if(stream == null)
|
// HACK we can't call WriteByte because it takes a cli.System.Byte
|
||||||
{
|
write(new byte[] { (byte)b }, 0, 1);
|
||||||
throw new IOException("Invalid FileDescriptor");
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(false) throw new system.io.IOException();
|
|
||||||
stream.WriteByte((byte)b);
|
|
||||||
}
|
|
||||||
catch(system.io.IOException x)
|
|
||||||
{
|
|
||||||
throw new IOException(x.get_Message());
|
|
||||||
}
|
|
||||||
// TODO map al the other exceptions as well...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void write(byte[] buf, int offset, int len) throws IOException
|
synchronized void write(byte[] buf, int offset, int len) throws IOException
|
||||||
|
@ -354,12 +343,12 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
stream.Write(buf, offset, len);
|
stream.Write(ByteArrayHack.cast(buf), offset, len);
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
// TODO map al the other exceptions as well...
|
// TODO map al the other exceptions as well...
|
||||||
}
|
}
|
||||||
|
@ -371,17 +360,17 @@ public final class FileDescriptor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.io.IOException();
|
if(false) throw new cli.System.IO.IOException();
|
||||||
if(false) throw new system.NotSupportedException();
|
if(false) throw new cli.System.NotSupportedException();
|
||||||
if(stream.get_CanSeek())
|
if(stream.get_CanSeek())
|
||||||
return (int)Math.min(Integer.MAX_VALUE, Math.max(0, stream.get_Length() - stream.get_Position()));
|
return (int)Math.min(Integer.MAX_VALUE, Math.max(0, stream.get_Length() - stream.get_Position()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(system.io.IOException x)
|
catch(cli.System.IO.IOException x)
|
||||||
{
|
{
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
catch(system.NotSupportedException x1)
|
catch(cli.System.NotSupportedException x1)
|
||||||
{
|
{
|
||||||
// this means we have a broken Stream, because if CanSeek returns true, it must
|
// this means we have a broken Stream, because if CanSeek returns true, it must
|
||||||
// support Length and Position
|
// support Length and Position
|
||||||
|
|
|
@ -44,12 +44,12 @@ public class ObjectHelper
|
||||||
}
|
}
|
||||||
if(timeout == 0 && nanos == 0)
|
if(timeout == 0 && nanos == 0)
|
||||||
{
|
{
|
||||||
system.threading.Monitor.Wait(o);
|
cli.System.Threading.Monitor.Wait(o);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO handle time span calculation overflow
|
// TODO handle time span calculation overflow
|
||||||
system.threading.Monitor.Wait(o, new system.TimeSpan(timeout * 10000 + (nanos + 99) / 100));
|
cli.System.Threading.Monitor.Wait(o, new cli.System.TimeSpan(timeout * 10000 + (nanos + 99) / 100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,25 +293,24 @@ public final class StringHelper
|
||||||
|
|
||||||
public static String substring(String s, int off, int end)
|
public static String substring(String s, int off, int end)
|
||||||
{
|
{
|
||||||
return ((system.String)(Object)s).Substring(off, end - off);
|
return cli.System.String.Substring(s, off, end - off);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean startsWith(String si, String prefix, int toffset)
|
public static boolean startsWith(String s, String prefix, int toffset)
|
||||||
{
|
{
|
||||||
if(toffset < 0)
|
if(toffset < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
system.String s = (system.String)(Object)si;
|
s = cli.System.String.Substring(s, Math.min(s.length(), toffset));
|
||||||
s = (system.String)(Object)s.Substring(Math.min(s.get_Length(), toffset));
|
return cli.System.String.StartsWith(s, prefix);
|
||||||
return s.StartsWith(prefix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char charAt(String s, int index)
|
public static char charAt(String s, int index)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ((system.String)(Object)s).get_Chars(index);
|
return cli.System.String.get_Chars(s, index);
|
||||||
}
|
}
|
||||||
// NOTE the System.IndexOutOfRangeException thrown by get_Chars, is translated by our
|
// NOTE the System.IndexOutOfRangeException thrown by get_Chars, is translated by our
|
||||||
// exception handling code to an ArrayIndexOutOfBoundsException, so we catch that.
|
// exception handling code to an ArrayIndexOutOfBoundsException, so we catch that.
|
||||||
|
@ -323,7 +322,7 @@ public final class StringHelper
|
||||||
|
|
||||||
public static void getChars(String s, int srcBegin, int srcEnd, char[] dst, int dstBegin)
|
public static void getChars(String s, int srcBegin, int srcEnd, char[] dst, int dstBegin)
|
||||||
{
|
{
|
||||||
((system.String)(Object)s).CopyTo(srcBegin, dst, dstBegin, srcEnd - srcBegin);
|
cli.System.String.CopyTo(s, srcBegin, dst, dstBegin, srcEnd - srcBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this exposes the package accessible "count" field (for use by StringBuffer)
|
// this exposes the package accessible "count" field (for use by StringBuffer)
|
||||||
|
@ -344,31 +343,28 @@ public final class StringHelper
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int indexOf(String si, char ch, int fromIndex)
|
public static int indexOf(String s, char ch, int fromIndex)
|
||||||
{
|
{
|
||||||
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
system.String s = (system.String)(Object)si;
|
return cli.System.String.IndexOf(s, ch, Math.max(0, Math.min(s.length(), fromIndex)));
|
||||||
return s.IndexOf(ch, Math.max(0, Math.min(s.get_Length(), fromIndex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int indexOf(String si, String o, int fromIndex)
|
public static int indexOf(String s, String o, int fromIndex)
|
||||||
{
|
{
|
||||||
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
// Java allow fromIndex to both below zero or above the length of the string, .NET doesn't
|
||||||
system.String s = (system.String)(Object)si;
|
return cli.System.String.IndexOf(s, o, Math.max(0, Math.min(s.length(), fromIndex)));
|
||||||
return s.IndexOf(o, Math.max(0, Math.min(s.get_Length(), fromIndex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lastIndexOf(String si, char ch, int fromIndex)
|
public static int lastIndexOf(String s, char ch, int fromIndex)
|
||||||
{
|
{
|
||||||
system.String s = (system.String)(Object)si;
|
|
||||||
// start by dereferencing s, to make sure we throw a NullPointerException if s is null
|
// start by dereferencing s, to make sure we throw a NullPointerException if s is null
|
||||||
int len = s.get_Length();
|
int len = s.length();
|
||||||
if(fromIndex < 0)
|
if(fromIndex < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// Java allow fromIndex to be above the length of the string, .NET doesn't
|
// Java allow fromIndex to be above the length of the string, .NET doesn't
|
||||||
return s.LastIndexOf(ch, Math.min(len - 1, fromIndex));
|
return cli.System.String.LastIndexOf(s, ch, Math.min(len - 1, fromIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lastIndexOf(String s, String o)
|
public static int lastIndexOf(String s, String o)
|
||||||
|
@ -376,11 +372,10 @@ public final class StringHelper
|
||||||
return lastIndexOf(s, o, s.length());
|
return lastIndexOf(s, o, s.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int lastIndexOf(String si, String o, int fromIndex)
|
public static int lastIndexOf(String s, String o, int fromIndex)
|
||||||
{
|
{
|
||||||
system.String s = (system.String)(Object)si;
|
|
||||||
// start by dereferencing s, to make sure we throw a NullPointerException if s is null
|
// start by dereferencing s, to make sure we throw a NullPointerException if s is null
|
||||||
int len = s.get_Length();
|
int len = s.length();
|
||||||
if(fromIndex < 0)
|
if(fromIndex < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -390,7 +385,7 @@ public final class StringHelper
|
||||||
return Math.min(len, fromIndex);
|
return Math.min(len, fromIndex);
|
||||||
}
|
}
|
||||||
// Java allow fromIndex to be above the length of the string, .NET doesn't
|
// Java allow fromIndex to be above the length of the string, .NET doesn't
|
||||||
return s.LastIndexOf(o, Math.min(len - 1, fromIndex + o.length() - 1));
|
return cli.System.String.LastIndexOf(s, o, Math.min(len - 1, fromIndex + o.length() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String concat(String s1, String s2)
|
public static String concat(String s1, String s2)
|
||||||
|
@ -401,7 +396,7 @@ public final class StringHelper
|
||||||
{
|
{
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
return system.String.Concat(s1, s2);
|
return cli.System.String.Concat(s1, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getBytes(String s, int srcBegin, int srcEnd, byte dst[], int dstBegin)
|
public static void getBytes(String s, int srcBegin, int srcEnd, byte dst[], int dstBegin)
|
||||||
|
@ -501,7 +496,7 @@ public final class StringHelper
|
||||||
|
|
||||||
public static String valueOf(char c)
|
public static String valueOf(char c)
|
||||||
{
|
{
|
||||||
return new system.String(c, 1).ToString();
|
return cli.System.String.__new(c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String valueOf(float f)
|
public static String valueOf(float f)
|
||||||
|
@ -531,11 +526,11 @@ public final class StringHelper
|
||||||
|
|
||||||
public static int hashCode(String s)
|
public static int hashCode(String s)
|
||||||
{
|
{
|
||||||
system.String ns = (system.String)(Object)s;
|
|
||||||
int h = 0;
|
int h = 0;
|
||||||
for(int i = 0; i < ns.get_Length(); i++)
|
int len = s.length();
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
h = h *31 + ns.get_Chars(i);
|
h = h *31 + cli.System.String.get_Chars(s, i);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ package java.lang;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import system.*;
|
import cli.System.*;
|
||||||
import system.reflection.*;
|
import cli.System.Reflection.*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class is a reference version, mainly for compiling a class library
|
* This class is a reference version, mainly for compiling a class library
|
||||||
|
@ -57,366 +57,345 @@ import system.reflection.*;
|
||||||
*/
|
*/
|
||||||
final class VMClass
|
final class VMClass
|
||||||
{
|
{
|
||||||
/** The .NET type */
|
private Object wrapper; // the corresponding TypeWrapper
|
||||||
private Type type;
|
|
||||||
private Object wrapper;
|
|
||||||
private Class clazz;
|
private Class clazz;
|
||||||
|
|
||||||
public static native Class getClassFromType(Type t);
|
// NOTE this is used in classpath.cs to go from a Class object to a TypeWrapper
|
||||||
private static native Type getTypeFromWrapper(Object clazz, Object wrapper);
|
private static Object getWrapperFromClass(Class c)
|
||||||
private static native Object getWrapperFromType(Type t);
|
|
||||||
|
|
||||||
private static Type getTypeFromClass(Class c)
|
|
||||||
{
|
{
|
||||||
return c.vmClass.getType();
|
return c.vmClass.wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type getType()
|
private VMClass(Object wrapper)
|
||||||
{
|
{
|
||||||
if(type == null)
|
this.wrapper = wrapper;
|
||||||
{
|
}
|
||||||
type = getTypeFromWrapper(clazz, wrapper);
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
private Object getWrapper()
|
|
||||||
{
|
|
||||||
if(wrapper == null)
|
|
||||||
{
|
|
||||||
wrapper = getWrapperFromType(type);
|
|
||||||
}
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
private VMClass(Type type, Object wrapper)
|
// HACK public because we want to create a delegate to call it
|
||||||
{
|
public static Object createClass(Object wrapper)
|
||||||
this.type = type;
|
{
|
||||||
this.wrapper = wrapper;
|
VMClass vmClass = new VMClass(wrapper);
|
||||||
}
|
Class c = new Class(vmClass);
|
||||||
|
vmClass.clazz = c;
|
||||||
private static Class createClass(Type type, Object wrapper)
|
return c;
|
||||||
{
|
}
|
||||||
VMClass vmClass = new VMClass(type, wrapper);
|
|
||||||
Class c = new Class(vmClass);
|
|
||||||
vmClass.clazz = c;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK we need a way to call ClassLoader.loadClass() from C#, so we need this helper method
|
// HACK we need a way to call ClassLoader.loadClass() from C#, so we need this helper method
|
||||||
public static Object __loadClassHelper(Object loader, String name) throws java.lang.ClassNotFoundException
|
// and its public because we want to create a delegate to call it
|
||||||
|
public static Object loadClassHelper(Object loader, String name) throws java.lang.ClassNotFoundException
|
||||||
{
|
{
|
||||||
return ((ClassLoader)loader).loadClass(name).vmClass.getWrapper();
|
return ((ClassLoader)loader).loadClass(name).vmClass.wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discover whether an Object is an instance of this Class. Think of it
|
* Discover whether an Object is an instance of this Class. Think of it
|
||||||
* as almost like <code>o instanceof (this class)</code>.
|
* as almost like <code>o instanceof (this class)</code>.
|
||||||
*
|
*
|
||||||
* @param o the Object to check
|
* @param o the Object to check
|
||||||
* @return whether o is an instance of this class
|
* @return whether o is an instance of this class
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
boolean isInstance(Object o)
|
boolean isInstance(Object o)
|
||||||
{
|
{
|
||||||
// TODO this needs to be implemented by the "native" code, because
|
return o != null && clazz.isAssignableFrom(o.getClass());
|
||||||
// remapped types can appear to implement interfaces that they don't
|
}
|
||||||
// actually implement
|
|
||||||
return getType().IsInstanceOfType(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discover whether an instance of the Class parameter would be an
|
* Discover whether an instance of the Class parameter would be an
|
||||||
* instance of this Class as well. Think of doing
|
* instance of this Class as well. Think of doing
|
||||||
* <code>isInstance(c.newInstance())</code> or even
|
* <code>isInstance(c.newInstance())</code> or even
|
||||||
* <code>c.newInstance() instanceof (this class)</code>. While this
|
* <code>c.newInstance() instanceof (this class)</code>. While this
|
||||||
* checks widening conversions for objects, it must be exact for primitive
|
* checks widening conversions for objects, it must be exact for primitive
|
||||||
* types.
|
* types.
|
||||||
*
|
*
|
||||||
* @param c the class to check
|
* @param c the class to check
|
||||||
* @return whether an instance of c would be an instance of this class
|
* @return whether an instance of c would be an instance of this class
|
||||||
* as well
|
* as well
|
||||||
* @throws NullPointerException if c is null
|
* @throws NullPointerException if c is null
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
boolean isAssignableFrom(Class c)
|
boolean isAssignableFrom(Class c)
|
||||||
{
|
{
|
||||||
// this needs to be implemented by the "native" code, because
|
// this is implemented by the "native" code, because
|
||||||
// remapped types can appear to implement interfaces that they don't
|
// remapped types can appear to implement interfaces that they don't
|
||||||
// actually implement
|
// actually implement
|
||||||
return IsAssignableFrom(getWrapper(), c.vmClass.getWrapper());
|
return IsAssignableFrom(wrapper, c.vmClass.wrapper);
|
||||||
}
|
}
|
||||||
private static native boolean IsAssignableFrom(Object w1, Object w2);
|
private static native boolean IsAssignableFrom(Object w1, Object w2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether this class is an interface or not. Array types are not
|
* Check whether this class is an interface or not. Array types are not
|
||||||
* interfaces.
|
* interfaces.
|
||||||
*
|
*
|
||||||
* @return whether this class is an interface or not
|
* @return whether this class is an interface or not
|
||||||
*/
|
*/
|
||||||
boolean isInterface()
|
boolean isInterface()
|
||||||
{
|
{
|
||||||
return getType().get_IsInterface();
|
return IsInterface(wrapper);
|
||||||
}
|
}
|
||||||
|
private static native boolean IsInterface(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether this class is a primitive type. A primitive type class
|
* Return whether this class is a primitive type. A primitive type class
|
||||||
* is a class representing a kind of "placeholder" for the various
|
* is a class representing a kind of "placeholder" for the various
|
||||||
* primitive types, or void. You can access the various primitive type
|
* primitive types, or void. You can access the various primitive type
|
||||||
* classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
|
* classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
|
||||||
* or through boolean.class, int.class, etc.
|
* or through boolean.class, int.class, etc.
|
||||||
*
|
*
|
||||||
* @return whether this class is a primitive type
|
* @return whether this class is a primitive type
|
||||||
* @see Boolean#TYPE
|
* @see Boolean#TYPE
|
||||||
* @see Byte#TYPE
|
* @see Byte#TYPE
|
||||||
* @see Character#TYPE
|
* @see Character#TYPE
|
||||||
* @see Short#TYPE
|
* @see Short#TYPE
|
||||||
* @see Integer#TYPE
|
* @see Integer#TYPE
|
||||||
* @see Long#TYPE
|
* @see Long#TYPE
|
||||||
* @see Float#TYPE
|
* @see Float#TYPE
|
||||||
* @see Double#TYPE
|
* @see Double#TYPE
|
||||||
* @see Void#TYPE
|
* @see Void#TYPE
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
boolean isPrimitive()
|
boolean isPrimitive()
|
||||||
{
|
{
|
||||||
return clazz == boolean.class ||
|
return clazz == boolean.class ||
|
||||||
clazz == byte.class ||
|
clazz == byte.class ||
|
||||||
clazz == char.class ||
|
clazz == char.class ||
|
||||||
clazz == short.class ||
|
clazz == short.class ||
|
||||||
clazz == int.class ||
|
clazz == int.class ||
|
||||||
clazz == long.class ||
|
clazz == long.class ||
|
||||||
clazz == float.class ||
|
clazz == float.class ||
|
||||||
clazz == double.class ||
|
clazz == double.class ||
|
||||||
clazz == void.class;
|
clazz == void.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of this class, separated by dots for package separators.
|
* Get the name of this class, separated by dots for package separators.
|
||||||
* Primitive types and arrays are encoded as:
|
* Primitive types and arrays are encoded as:
|
||||||
* <pre>
|
* <pre>
|
||||||
* boolean Z
|
* boolean Z
|
||||||
* byte B
|
* byte B
|
||||||
* char C
|
* char C
|
||||||
* short S
|
* short S
|
||||||
* int I
|
* int I
|
||||||
* long J
|
* long J
|
||||||
* float F
|
* float F
|
||||||
* double D
|
* double D
|
||||||
* void V
|
* void V
|
||||||
* array type [<em>element type</em>
|
* array type [<em>element type</em>
|
||||||
* class or interface, alone: <dotted name>
|
* class or interface, alone: <dotted name>
|
||||||
* class or interface, as element type: L<dotted name>;
|
* class or interface, as element type: L<dotted name>;
|
||||||
*
|
*
|
||||||
* @return the name of this class
|
* @return the name of this class
|
||||||
*/
|
*/
|
||||||
String getName()
|
String getName()
|
||||||
{
|
{
|
||||||
// getName() is used by the classloader, so it shouldn't trigger a resolve of the class
|
// getName() is used by the classloader, so it shouldn't trigger a resolve of the class
|
||||||
return GetName(type, wrapper);
|
return GetName(wrapper);
|
||||||
}
|
}
|
||||||
private static native String GetName(Type type, Object wrapper);
|
private static native String GetName(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the direct superclass of this class. If this is an interface,
|
* Get the direct superclass of this class. If this is an interface,
|
||||||
* Object, a primitive type, or void, it will return null. If this is an
|
* Object, a primitive type, or void, it will return null. If this is an
|
||||||
* array type, it will return Object.
|
* array type, it will return Object.
|
||||||
*
|
*
|
||||||
* @return the direct superclass of this class
|
* @return the direct superclass of this class
|
||||||
*/
|
*/
|
||||||
Class getSuperclass()
|
Class getSuperclass()
|
||||||
{
|
{
|
||||||
return (Class)GetSuperClassFromWrapper(getWrapper());
|
return (Class)GetSuperClassFromWrapper(wrapper);
|
||||||
}
|
}
|
||||||
private native static Object GetSuperClassFromWrapper(Object wrapper);
|
private native static Object GetSuperClassFromWrapper(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the interfaces this class <EM>directly</EM> implements, in the
|
* Get the interfaces this class <EM>directly</EM> implements, in the
|
||||||
* order that they were declared. This returns an empty array, not null,
|
* order that they were declared. This returns an empty array, not null,
|
||||||
* for Object, primitives, void, and classes or interfaces with no direct
|
* for Object, primitives, void, and classes or interfaces with no direct
|
||||||
* superinterface. Array types return Cloneable and Serializable.
|
* superinterface. Array types return Cloneable and Serializable.
|
||||||
*
|
*
|
||||||
* @return the interfaces this class directly implements
|
* @return the interfaces this class directly implements
|
||||||
*/
|
*/
|
||||||
Class[] getInterfaces()
|
Class[] getInterfaces()
|
||||||
{
|
{
|
||||||
Object[] interfaces = GetInterfaces(type, wrapper);
|
Object[] interfaces = GetInterfaces(wrapper);
|
||||||
Class[] interfacesClass = new Class[interfaces.length];
|
Class[] interfacesClass = new Class[interfaces.length];
|
||||||
System.arraycopy(interfaces, 0, interfacesClass, 0, interfaces.length);
|
System.arraycopy(interfaces, 0, interfacesClass, 0, interfaces.length);
|
||||||
return interfacesClass;
|
return interfacesClass;
|
||||||
}
|
}
|
||||||
private static native Object[] GetInterfaces(Type type, Object wrapper);
|
private static native Object[] GetInterfaces(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is an array, get the Class representing the type of array.
|
* If this is an array, get the Class representing the type of array.
|
||||||
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
|
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
|
||||||
* calling getComponentType on that would give "java.lang.String". If
|
* calling getComponentType on that would give "java.lang.String". If
|
||||||
* this is not an array, returns null.
|
* this is not an array, returns null.
|
||||||
*
|
*
|
||||||
* @return the array type of this class, or null
|
* @return the array type of this class, or null
|
||||||
* @see Array
|
* @see Array
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
Class getComponentType()
|
Class getComponentType()
|
||||||
{
|
{
|
||||||
// .NET array types can have unfinished element types, but we don't
|
// .NET array types can have unfinished element types, but we don't
|
||||||
// want to expose those, so we may need to finish the type
|
// want to expose those, so we may need to finish the type
|
||||||
return (Class)getComponentClassFromWrapper(getWrapper());
|
return (Class)getComponentClassFromWrapper(wrapper);
|
||||||
}
|
}
|
||||||
private static native Object getComponentClassFromWrapper(Object wrapper);
|
private static native Object getComponentClassFromWrapper(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the modifiers of this class. These can be decoded using Modifier,
|
* Get the modifiers of this class. These can be decoded using Modifier,
|
||||||
* and is limited to one of public, protected, or private, and any of
|
* and is limited to one of public, protected, or private, and any of
|
||||||
* final, static, abstract, or interface. An array class has the same
|
* final, static, abstract, or interface. An array class has the same
|
||||||
* public, protected, or private modifier as its component type, and is
|
* public, protected, or private modifier as its component type, and is
|
||||||
* marked final but not an interface. Primitive types and void are marked
|
* marked final but not an interface. Primitive types and void are marked
|
||||||
* public and final, but not an interface.
|
* public and final, but not an interface.
|
||||||
*
|
*
|
||||||
* @return the modifiers of this class
|
* @return the modifiers of this class
|
||||||
* @see Modifer
|
* @see Modifer
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
int getModifiers()
|
int getModifiers()
|
||||||
{
|
{
|
||||||
return GetModifiers(type, wrapper);
|
return GetModifiers(wrapper);
|
||||||
}
|
}
|
||||||
private static native int GetModifiers(Type type, Object wrapper);
|
private static native int GetModifiers(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is a nested or inner class, return the class that declared it.
|
* If this is a nested or inner class, return the class that declared it.
|
||||||
* If not, return null.
|
* If not, return null.
|
||||||
*
|
*
|
||||||
* @return the declaring class of this class
|
* @return the declaring class of this class
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
Class getDeclaringClass()
|
Class getDeclaringClass()
|
||||||
{
|
{
|
||||||
return (Class)GetDeclaringClass(type, wrapper);
|
return (Class)GetDeclaringClass(wrapper);
|
||||||
}
|
}
|
||||||
private native static Object GetDeclaringClass(Type type, Object wrapper);
|
private native static Object GetDeclaringClass(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like <code>getDeclaredClasses()</code> but without the security checks.
|
* Like <code>getDeclaredClasses()</code> but without the security checks.
|
||||||
*
|
*
|
||||||
* @param pulicOnly Only public classes should be returned
|
* @param pulicOnly Only public classes should be returned
|
||||||
*/
|
*/
|
||||||
Class[] getDeclaredClasses(boolean publicOnly)
|
Class[] getDeclaredClasses(boolean publicOnly)
|
||||||
{
|
{
|
||||||
Object[] classes = GetDeclaredClasses(type, wrapper, publicOnly);
|
Object[] classes = GetDeclaredClasses(wrapper, publicOnly);
|
||||||
Class[] classesClass = new Class[classes.length];
|
Class[] classesClass = new Class[classes.length];
|
||||||
System.arraycopy(classes, 0, classesClass, 0, classes.length);
|
System.arraycopy(classes, 0, classesClass, 0, classes.length);
|
||||||
return classesClass;
|
return classesClass;
|
||||||
}
|
}
|
||||||
private static native Object[] GetDeclaredClasses(Type type, Object wrapper, boolean publicOnly);
|
private static native Object[] GetDeclaredClasses(Object wrapper, boolean publicOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like <code>getDeclaredFields()</code> but without the security checks.
|
* Like <code>getDeclaredFields()</code> but without the security checks.
|
||||||
*
|
*
|
||||||
* @param pulicOnly Only public fields should be returned
|
* @param pulicOnly Only public fields should be returned
|
||||||
*/
|
*/
|
||||||
Field[] getDeclaredFields(boolean publicOnly)
|
Field[] getDeclaredFields(boolean publicOnly)
|
||||||
|
{
|
||||||
|
Object[] fieldCookies = GetDeclaredFields(wrapper, publicOnly);
|
||||||
|
Field[] fields = new Field[fieldCookies.length];
|
||||||
|
for(int i = 0; i < fields.length; i++)
|
||||||
{
|
{
|
||||||
Object[] fieldCookies = GetDeclaredFields(type, wrapper, publicOnly);
|
fields[i] = new Field(clazz, fieldCookies[i]);
|
||||||
Field[] fields = new Field[fieldCookies.length];
|
|
||||||
for(int i = 0; i < fields.length; i++)
|
|
||||||
{
|
|
||||||
fields[i] = new Field(clazz, fieldCookies[i]);
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
}
|
||||||
private static native Object[] GetDeclaredFields(Type type, Object wrapper, boolean publicOnly);
|
return fields;
|
||||||
|
}
|
||||||
|
private static native Object[] GetDeclaredFields(Object wrapper, boolean publicOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like <code>getDeclaredMethods()</code> but without the security checks.
|
* Like <code>getDeclaredMethods()</code> but without the security checks.
|
||||||
*
|
*
|
||||||
* @param pulicOnly Only public methods should be returned
|
* @param pulicOnly Only public methods should be returned
|
||||||
*/
|
*/
|
||||||
Method[] getDeclaredMethods(boolean publicOnly)
|
Method[] getDeclaredMethods(boolean publicOnly)
|
||||||
|
{
|
||||||
|
Object[] methodCookies = GetDeclaredMethods(wrapper, true, publicOnly);
|
||||||
|
Method[] methods = new Method[methodCookies.length];
|
||||||
|
for(int i = 0; i < methodCookies.length; i++)
|
||||||
{
|
{
|
||||||
Object[] methodCookies = GetDeclaredMethods(type, wrapper, true, publicOnly);
|
methods[i] = new Method(clazz, methodCookies[i]);
|
||||||
Method[] methods = new Method[methodCookies.length];
|
|
||||||
for(int i = 0; i < methodCookies.length; i++)
|
|
||||||
{
|
|
||||||
methods[i] = new Method(clazz, methodCookies[i]);
|
|
||||||
}
|
|
||||||
return methods;
|
|
||||||
}
|
}
|
||||||
private static native Object[] GetDeclaredMethods(Type type, Object wrapper, boolean methods, boolean publicOnly);
|
return methods;
|
||||||
|
}
|
||||||
|
private static native Object[] GetDeclaredMethods(Object wrapper, boolean methods, boolean publicOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like <code>getDeclaredConstructors()</code> but without
|
* Like <code>getDeclaredConstructors()</code> but without
|
||||||
* the security checks.
|
* the security checks.
|
||||||
*
|
*
|
||||||
* @param pulicOnly Only public constructors should be returned
|
* @param pulicOnly Only public constructors should be returned
|
||||||
*/
|
*/
|
||||||
Constructor[] getDeclaredConstructors(boolean publicOnly)
|
Constructor[] getDeclaredConstructors(boolean publicOnly)
|
||||||
|
{
|
||||||
|
Object[] methodCookies = GetDeclaredMethods(wrapper, false, publicOnly);
|
||||||
|
Constructor[] constructors = new Constructor[methodCookies.length];
|
||||||
|
for(int i = 0; i < methodCookies.length; i++)
|
||||||
{
|
{
|
||||||
Object[] methodCookies = GetDeclaredMethods(type, wrapper, false, publicOnly);
|
constructors[i] = new Constructor(clazz, methodCookies[i]);
|
||||||
Constructor[] constructors = new Constructor[methodCookies.length];
|
|
||||||
for(int i = 0; i < methodCookies.length; i++)
|
|
||||||
{
|
|
||||||
constructors[i] = new Constructor(clazz, methodCookies[i]);
|
|
||||||
}
|
|
||||||
return constructors;
|
|
||||||
}
|
}
|
||||||
|
return constructors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the class loader of this class.
|
* Return the class loader of this class.
|
||||||
*
|
*
|
||||||
* @return the class loader
|
* @return the class loader
|
||||||
*/
|
*/
|
||||||
ClassLoader getClassLoader()
|
ClassLoader getClassLoader()
|
||||||
{
|
{
|
||||||
// getClassLoader() can be used by the classloader, so it shouldn't trigger a resolve of the class
|
// getClassLoader() can be used by the classloader, so it shouldn't trigger a resolve of the class
|
||||||
return getClassLoader0(type, wrapper);
|
return getClassLoader0(wrapper);
|
||||||
}
|
}
|
||||||
private static native ClassLoader getClassLoader0(Type type, Object wrapper);
|
private static native ClassLoader getClassLoader0(Object wrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VM implementors are free to make this method a noop if
|
* VM implementors are free to make this method a noop if
|
||||||
* the default implementation is acceptable.
|
* the default implementation is acceptable.
|
||||||
*
|
*
|
||||||
* @param name the name of the class to find
|
* @param name the name of the class to find
|
||||||
* @return the Class object representing the class or null for noop
|
* @return the Class object representing the class or null for noop
|
||||||
* @throws ClassNotFoundException if the class was not found by the
|
* @throws ClassNotFoundException if the class was not found by the
|
||||||
* classloader
|
* classloader
|
||||||
* @throws LinkageError if linking the class fails
|
* @throws LinkageError if linking the class fails
|
||||||
* @throws ExceptionInInitializerError if the class loads, but an exception
|
* @throws ExceptionInInitializerError if the class loads, but an exception
|
||||||
* occurs during initialization
|
* occurs during initialization
|
||||||
*/
|
*/
|
||||||
static Class forName(String name) throws ClassNotFoundException
|
static Class forName(String name) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
// if we ever get back to using a separate assembly for each class loader, it
|
||||||
|
// might be faster to use Assembly.GetCallingAssembly here...
|
||||||
|
cli.System.Diagnostics.StackFrame frame = new cli.System.Diagnostics.StackFrame(1);
|
||||||
|
// HACK a lame way to deal with potential inlining of this method (or Class.forName)
|
||||||
|
if(frame.GetMethod().get_Name().equals("forName"))
|
||||||
{
|
{
|
||||||
// if we ever get back to using a separate assembly for each class loader, it
|
frame = new cli.System.Diagnostics.StackFrame(2);
|
||||||
// might be faster to use Assembly.GetCallingAssembly here...
|
|
||||||
system.diagnostics.StackFrame frame = new system.diagnostics.StackFrame(1);
|
|
||||||
// HACK a lame way to deal with potential inlining of this method (or Class.forName)
|
|
||||||
if(frame.GetMethod().get_Name().equals("forName"))
|
|
||||||
{
|
|
||||||
frame = new system.diagnostics.StackFrame(2);
|
|
||||||
}
|
|
||||||
ClassLoader cl = getClassLoader0(frame.GetMethod().get_DeclaringType(), null);
|
|
||||||
return Class.forName(name, true, cl);
|
|
||||||
}
|
}
|
||||||
|
ClassLoader cl = getClassLoaderFromType(frame.GetMethod().get_DeclaringType());
|
||||||
|
return Class.forName(name, true, cl);
|
||||||
|
}
|
||||||
|
private static native ClassLoader getClassLoaderFromType(Type type);
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
initializeType(getType());
|
initialize(wrapper);
|
||||||
}
|
}
|
||||||
|
private static native void initialize(Object wrapper);
|
||||||
|
|
||||||
static native Class loadArrayClass(String name, Object classLoader);
|
static native Class loadArrayClass(String name, Object classLoader);
|
||||||
static native Class loadBootstrapClass(String name, boolean initialize);
|
static native Class loadBootstrapClass(String name, boolean initialize);
|
||||||
private static native void initializeType(Type type);
|
|
||||||
|
|
||||||
static native void throwException(Throwable t);
|
static native void throwException(Throwable t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether this class is an array type.
|
* Return whether this class is an array type.
|
||||||
*
|
*
|
||||||
* @return 1 if this class is an array type, 0 otherwise, -1 if unsupported
|
* @return 1 if this class is an array type, 0 otherwise, -1 if unsupported
|
||||||
* operation
|
* operation
|
||||||
*/
|
*/
|
||||||
int isArray()
|
int isArray()
|
||||||
{
|
{
|
||||||
return getType().get_IsArray() ? 1 : 0;
|
return IsArray(wrapper) ? 1 : 0;
|
||||||
}
|
}
|
||||||
} // class VMClass
|
private static native boolean IsArray(Object wrapper);
|
||||||
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import gnu.java.lang.SystemClassLoader;
|
import gnu.java.lang.SystemClassLoader;
|
||||||
import system.*;
|
import cli.System.*;
|
||||||
import system.reflection.*;
|
import cli.System.Reflection.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* java.lang.VMClassLoader is a package-private helper for VMs to implement
|
* java.lang.VMClassLoader is a package-private helper for VMs to implement
|
||||||
|
@ -217,12 +217,7 @@ final class VMClassLoader
|
||||||
* @param type the primitive type
|
* @param type the primitive type
|
||||||
* @return a "bogus" class representing the primitive type
|
* @return a "bogus" class representing the primitive type
|
||||||
*/
|
*/
|
||||||
static final Class getPrimitiveClass(char type)
|
static native Class getPrimitiveClass(char type);
|
||||||
{
|
|
||||||
return VMClass.getClassFromType(getPrimitiveType(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static native system.Type getPrimitiveType(char type);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The system default for assertion status. This is used for all system
|
* The system default for assertion status. This is used for all system
|
||||||
|
|
|
@ -28,7 +28,7 @@ final class VMDouble
|
||||||
{
|
{
|
||||||
static double longBitsToDouble(long v)
|
static double longBitsToDouble(long v)
|
||||||
{
|
{
|
||||||
return system.BitConverter.Int64BitsToDouble(v);
|
return cli.System.BitConverter.Int64BitsToDouble(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long doubleToLongBits(double v)
|
static long doubleToLongBits(double v)
|
||||||
|
@ -37,11 +37,11 @@ final class VMDouble
|
||||||
{
|
{
|
||||||
return 0x7ff8000000000000L;
|
return 0x7ff8000000000000L;
|
||||||
}
|
}
|
||||||
return system.BitConverter.DoubleToInt64Bits(v);
|
return cli.System.BitConverter.DoubleToInt64Bits(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long doubleToRawLongBits(double v)
|
static long doubleToRawLongBits(double v)
|
||||||
{
|
{
|
||||||
return system.BitConverter.DoubleToInt64Bits(v);
|
return cli.System.BitConverter.DoubleToInt64Bits(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ final class VMFloat
|
||||||
{
|
{
|
||||||
static float intBitsToFloat(int v)
|
static float intBitsToFloat(int v)
|
||||||
{
|
{
|
||||||
return system.BitConverter.ToSingle(system.BitConverter.GetBytes(v), 0);
|
return cli.System.BitConverter.ToSingle(cli.System.BitConverter.GetBytes(v), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int floatToIntBits(float v)
|
static int floatToIntBits(float v)
|
||||||
|
@ -37,11 +37,11 @@ final class VMFloat
|
||||||
{
|
{
|
||||||
return 0x7fc00000;
|
return 0x7fc00000;
|
||||||
}
|
}
|
||||||
return system.BitConverter.ToInt32(system.BitConverter.GetBytes(v), 0);
|
return cli.System.BitConverter.ToInt32(cli.System.BitConverter.GetBytes(v), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int floatToRawIntBits(float v)
|
static int floatToRawIntBits(float v)
|
||||||
{
|
{
|
||||||
return system.BitConverter.ToInt32(system.BitConverter.GetBytes(v), 0);
|
return cli.System.BitConverter.ToInt32(cli.System.BitConverter.GetBytes(v), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,21 +115,21 @@ final class VMThread
|
||||||
thread.stillborn = t;
|
thread.stillborn = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static system.LocalDataStoreSlot localDataStoreSlot = system.threading.Thread.AllocateDataSlot();
|
private static cli.System.LocalDataStoreSlot localDataStoreSlot = cli.System.Threading.Thread.AllocateDataSlot();
|
||||||
private system.threading.Thread nativeThread;
|
private cli.System.Threading.Thread nativeThread;
|
||||||
|
|
||||||
/*native*/ void start(long stacksize)
|
/*native*/ void start(long stacksize)
|
||||||
{
|
{
|
||||||
system.threading.ThreadStart starter = new system.threading.ThreadStart(
|
cli.System.Threading.ThreadStart starter = new cli.System.Threading.ThreadStart(
|
||||||
new system.threading.ThreadStart.Method()
|
new cli.System.Threading.ThreadStart.Method()
|
||||||
{
|
{
|
||||||
public void Invoke()
|
public void Invoke()
|
||||||
{
|
{
|
||||||
system.threading.Thread.SetData(localDataStoreSlot, thread);
|
cli.System.Threading.Thread.SetData(localDataStoreSlot, thread);
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nativeThread = new system.threading.Thread(starter);
|
nativeThread = new cli.System.Threading.Thread(starter);
|
||||||
nativeThread.set_Name(thread.name);
|
nativeThread.set_Name(thread.name);
|
||||||
nativeThread.set_IsBackground(thread.daemon);
|
nativeThread.set_IsBackground(thread.daemon);
|
||||||
nativeSetPriority(thread.priority);
|
nativeSetPriority(thread.priority);
|
||||||
|
@ -149,7 +149,7 @@ final class VMThread
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new InterruptedException();
|
if(false) throw new InterruptedException();
|
||||||
system.threading.Thread.Sleep(0);
|
cli.System.Threading.Thread.Sleep(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch(InterruptedException x)
|
catch(InterruptedException x)
|
||||||
|
@ -179,23 +179,23 @@ final class VMThread
|
||||||
{
|
{
|
||||||
if(priority == Thread.MIN_PRIORITY)
|
if(priority == Thread.MIN_PRIORITY)
|
||||||
{
|
{
|
||||||
nativeThread.set_Priority(system.threading.ThreadPriority.Lowest);
|
nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(cli.System.Threading.ThreadPriority.Lowest));
|
||||||
}
|
}
|
||||||
else if(priority > Thread.MIN_PRIORITY && priority < Thread.NORM_PRIORITY)
|
else if(priority > Thread.MIN_PRIORITY && priority < Thread.NORM_PRIORITY)
|
||||||
{
|
{
|
||||||
nativeThread.set_Priority(system.threading.ThreadPriority.BelowNormal);
|
nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(cli.System.Threading.ThreadPriority.BelowNormal));
|
||||||
}
|
}
|
||||||
else if(priority == Thread.NORM_PRIORITY)
|
else if(priority == Thread.NORM_PRIORITY)
|
||||||
{
|
{
|
||||||
nativeThread.set_Priority(system.threading.ThreadPriority.Normal);
|
nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(cli.System.Threading.ThreadPriority.Normal));
|
||||||
}
|
}
|
||||||
else if(priority > Thread.NORM_PRIORITY && priority < Thread.MAX_PRIORITY)
|
else if(priority > Thread.NORM_PRIORITY && priority < Thread.MAX_PRIORITY)
|
||||||
{
|
{
|
||||||
nativeThread.set_Priority(system.threading.ThreadPriority.AboveNormal);
|
nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(cli.System.Threading.ThreadPriority.AboveNormal));
|
||||||
}
|
}
|
||||||
else if(priority == Thread.MAX_PRIORITY)
|
else if(priority == Thread.MAX_PRIORITY)
|
||||||
{
|
{
|
||||||
nativeThread.set_Priority(system.threading.ThreadPriority.Highest);
|
nativeThread.set_Priority(cli.System.Threading.ThreadPriority.wrap(cli.System.Threading.ThreadPriority.Highest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,37 +206,37 @@ final class VMThread
|
||||||
|
|
||||||
/*native*/ static Thread currentThread()
|
/*native*/ static Thread currentThread()
|
||||||
{
|
{
|
||||||
Thread javaThread = (Thread)system.threading.Thread.GetData(localDataStoreSlot);
|
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
||||||
if(javaThread == null)
|
if(javaThread == null)
|
||||||
{
|
{
|
||||||
// threads created outside of Java always run in the root thread group
|
// threads created outside of Java always run in the root thread group
|
||||||
// TODO if the thread dies, it needs to be removed from the root ThreadGroup
|
// TODO if the thread dies, it needs to be removed from the root ThreadGroup
|
||||||
// and any other threads waiting to join it, should be released.
|
// and any other threads waiting to join it, should be released.
|
||||||
system.threading.Thread nativeThread = system.threading.Thread.get_CurrentThread();
|
cli.System.Threading.Thread nativeThread = cli.System.Threading.Thread.get_CurrentThread();
|
||||||
VMThread vmThread = new VMThread(null);
|
VMThread vmThread = new VMThread(null);
|
||||||
vmThread.nativeThread = nativeThread;
|
vmThread.nativeThread = nativeThread;
|
||||||
int priority = Thread.NORM_PRIORITY;
|
int priority = Thread.NORM_PRIORITY;
|
||||||
switch(nativeThread.get_Priority())
|
switch(nativeThread.get_Priority().Value)
|
||||||
{
|
{
|
||||||
case system.threading.ThreadPriority.Lowest:
|
case cli.System.Threading.ThreadPriority.Lowest:
|
||||||
priority = Thread.MIN_PRIORITY;
|
priority = Thread.MIN_PRIORITY;
|
||||||
break;
|
break;
|
||||||
case system.threading.ThreadPriority.BelowNormal:
|
case cli.System.Threading.ThreadPriority.BelowNormal:
|
||||||
priority = 3;
|
priority = 3;
|
||||||
break;
|
break;
|
||||||
case system.threading.ThreadPriority.Normal:
|
case cli.System.Threading.ThreadPriority.Normal:
|
||||||
priority = Thread.NORM_PRIORITY;
|
priority = Thread.NORM_PRIORITY;
|
||||||
break;
|
break;
|
||||||
case system.threading.ThreadPriority.AboveNormal:
|
case cli.System.Threading.ThreadPriority.AboveNormal:
|
||||||
priority = 7;
|
priority = 7;
|
||||||
break;
|
break;
|
||||||
case system.threading.ThreadPriority.Highest:
|
case cli.System.Threading.ThreadPriority.Highest:
|
||||||
priority = Thread.MAX_PRIORITY;
|
priority = Thread.MAX_PRIORITY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
||||||
vmThread.thread = javaThread;
|
vmThread.thread = javaThread;
|
||||||
system.threading.Thread.SetData(localDataStoreSlot, javaThread);
|
cli.System.Threading.Thread.SetData(localDataStoreSlot, javaThread);
|
||||||
javaThread.group = ThreadGroup.root;
|
javaThread.group = ThreadGroup.root;
|
||||||
javaThread.group.addThread(javaThread);
|
javaThread.group.addThread(javaThread);
|
||||||
InheritableThreadLocal.newChildThread(javaThread);
|
InheritableThreadLocal.newChildThread(javaThread);
|
||||||
|
@ -246,20 +246,20 @@ final class VMThread
|
||||||
|
|
||||||
static /*native*/ void yield()
|
static /*native*/ void yield()
|
||||||
{
|
{
|
||||||
system.threading.Thread.Sleep(0);
|
cli.System.Threading.Thread.Sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static /*native*/ void sleep(long ms, int ns) throws InterruptedException
|
static /*native*/ void sleep(long ms, int ns) throws InterruptedException
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.threading.ThreadInterruptedException();
|
if(false) throw new cli.System.Threading.ThreadInterruptedException();
|
||||||
// TODO guard against ms and ns overflowing
|
// TODO guard against ms and ns overflowing
|
||||||
system.threading.Thread.Sleep(new system.TimeSpan(ms * 10000 + (ns + 99) / 100));
|
cli.System.Threading.Thread.Sleep(new cli.System.TimeSpan(ms * 10000 + (ns + 99) / 100));
|
||||||
}
|
}
|
||||||
catch(system.threading.ThreadInterruptedException x)
|
catch(cli.System.Threading.ThreadInterruptedException x)
|
||||||
{
|
{
|
||||||
throw new InterruptedException(x.get_Message());
|
throw new InterruptedException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ final class VMThread
|
||||||
synchronized(currentThread())
|
synchronized(currentThread())
|
||||||
{
|
{
|
||||||
if(false) throw new InterruptedException();
|
if(false) throw new InterruptedException();
|
||||||
system.threading.Thread.Sleep(0);
|
cli.System.Threading.Thread.Sleep(0);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ final class VMThread
|
||||||
// NOTE Wait causes the lock to be released temporarily, which isn't what we want
|
// NOTE Wait causes the lock to be released temporarily, which isn't what we want
|
||||||
if(false) throw new IllegalMonitorStateException();
|
if(false) throw new IllegalMonitorStateException();
|
||||||
if(false) throw new InterruptedException();
|
if(false) throw new InterruptedException();
|
||||||
system.threading.Monitor.Wait(obj, 0);
|
cli.System.Threading.Monitor.Wait(obj, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch(IllegalMonitorStateException x)
|
catch(IllegalMonitorStateException x)
|
||||||
|
@ -302,7 +302,7 @@ final class VMThread
|
||||||
catch(InterruptedException x1)
|
catch(InterruptedException x1)
|
||||||
{
|
{
|
||||||
// Since we "consumed" the interrupt, we have to interrupt ourself again
|
// Since we "consumed" the interrupt, we have to interrupt ourself again
|
||||||
system.threading.Thread.get_CurrentThread().Interrupt();
|
cli.System.Threading.Thread.get_CurrentThread().Interrupt();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,6 @@ exception statement from your version. */
|
||||||
|
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import system.reflection.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Constructor class represents a constructor of a class. It also allows
|
* The Constructor class represents a constructor of a class. It also allows
|
||||||
* dynamic creation of an object, via reflection. Invocation on Constructor
|
* dynamic creation of an object, via reflection. Invocation on Constructor
|
||||||
|
@ -162,7 +160,7 @@ public final class Constructor
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
if(o instanceof ConstructorInfo)
|
if(o instanceof Constructor)
|
||||||
{
|
{
|
||||||
return methodCookie == ((Constructor)o).methodCookie;
|
return methodCookie == ((Constructor)o).methodCookie;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,6 @@ exception statement from your version. */
|
||||||
|
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import system.reflection.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Method class represents a member method of a class. It also allows
|
* The Method class represents a member method of a class. It also allows
|
||||||
* dynamic invocation, via reflection. This works for both static and
|
* dynamic invocation, via reflection. This works for both static and
|
||||||
|
|
|
@ -39,9 +39,10 @@ exception statement from your version. */
|
||||||
package java.net;
|
package java.net;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import system.net.*;
|
import cli.System.Net.*;
|
||||||
import system.net.sockets.*;
|
import cli.System.Net.Sockets.*;
|
||||||
import ikvm.lang.CIL;
|
import ikvm.lang.CIL;
|
||||||
|
import ikvm.lang.ByteArrayHack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the default socket implementation for datagram sockets.
|
* This is the default socket implementation for datagram sockets.
|
||||||
|
@ -70,12 +71,12 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
|
|
||||||
private static class MyUdpClient extends UdpClient
|
private static class MyUdpClient extends UdpClient
|
||||||
{
|
{
|
||||||
MyUdpClient(system.net.IPEndPoint ep)
|
MyUdpClient(cli.System.Net.IPEndPoint ep)
|
||||||
{
|
{
|
||||||
super(ep);
|
super(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
system.net.sockets.Socket getSocket()
|
cli.System.Net.Sockets.Socket getSocket()
|
||||||
{
|
{
|
||||||
return super.get_Client();
|
return super.get_Client();
|
||||||
}
|
}
|
||||||
|
@ -153,7 +154,7 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
int len = packet.getLength();
|
int len = packet.getLength();
|
||||||
if(socket.Send(packet.getData(), len, new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(packet.getAddress()), packet.getPort())) != len)
|
if(socket.Send(ByteArrayHack.cast(packet.getData()), len, new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(packet.getAddress()), packet.getPort())) != len)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
throw new IOException();
|
throw new IOException();
|
||||||
|
@ -183,13 +184,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
byte[] data = packet.getData();
|
byte[] data = packet.getData();
|
||||||
int length = packet.getLength();
|
int length = packet.getLength();
|
||||||
system.net.IPEndPoint[] remoteEP = new system.net.IPEndPoint[] {
|
cli.System.Net.IPEndPoint[] remoteEP = new cli.System.Net.IPEndPoint[] {
|
||||||
new system.net.IPEndPoint(0, 0)
|
new cli.System.Net.IPEndPoint(0, 0)
|
||||||
};
|
};
|
||||||
byte[] buf = socket.Receive(remoteEP);
|
byte[] buf = ByteArrayHack.cast(socket.Receive(remoteEP));
|
||||||
System.arraycopy(buf, 0, data, 0, Math.min(length, buf.length));
|
System.arraycopy(buf, 0, data, 0, Math.min(length, buf.length));
|
||||||
// I think the spec says that the Length property of DatagramPacket
|
// I think the spec says that the Length property of DatagramPacket
|
||||||
// contains the number of bytes in the network packet (even if
|
// contains the number of bytes in the network packet (even if
|
||||||
|
@ -201,10 +202,10 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
packet.setAddress(remoteAddress);
|
packet.setAddress(remoteAddress);
|
||||||
packet.setPort(remoteEP[0].get_Port());
|
packet.setPort(remoteEP[0].get_Port());
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,13 +222,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.JoinMulticastGroup(new system.net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
|
socket.JoinMulticastGroup(new cli.System.Net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,13 +245,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.DropMulticastGroup(new system.net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
|
socket.DropMulticastGroup(new cli.System.Net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,20 +336,20 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
switch(option_id)
|
switch(option_id)
|
||||||
{
|
{
|
||||||
case IP_TTL:
|
case IP_TTL:
|
||||||
return new Integer(CIL.unbox_int(socket.getSocket().GetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive)));
|
return new Integer(CIL.unbox_int(socket.getSocket().GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive))));
|
||||||
case SocketOptions.SO_TIMEOUT:
|
case SocketOptions.SO_TIMEOUT:
|
||||||
return new Integer(CIL.unbox_int(socket.getSocket().GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)));
|
return new Integer(CIL.unbox_int(socket.getSocket().GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout))));
|
||||||
default:
|
default:
|
||||||
throw new Error("getOption(" + option_id + ") not implemented");
|
throw new Error("getOption(" + option_id + ") not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
throw new SocketException(x.get_Message());
|
throw new SocketException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,26 +367,26 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
switch(option_id)
|
switch(option_id)
|
||||||
{
|
{
|
||||||
case IP_TTL:
|
case IP_TTL:
|
||||||
socket.getSocket().SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, ((Integer)val).intValue());
|
socket.getSocket().SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_TIMEOUT:
|
case SocketOptions.SO_TIMEOUT:
|
||||||
socket.getSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, ((Integer)val).intValue());
|
socket.getSocket().SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout), ((Integer)val).intValue());
|
||||||
socket.getSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, ((Integer)val).intValue());
|
socket.getSocket().SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendTimeout), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_REUSEADDR:
|
case SocketOptions.SO_REUSEADDR:
|
||||||
socket.getSocket().SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, ((Boolean)val).booleanValue() ? 1 : 0);
|
socket.getSocket().SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress), ((Boolean)val).booleanValue() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error("setOption(" + option_id + ") not implemented");
|
throw new Error("setOption(" + option_id + ") not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
throw new SocketException(x.get_Message());
|
throw new SocketException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,10 @@ package java.net;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import system.net.*;
|
import cli.System.Net.*;
|
||||||
import system.net.sockets.*;
|
import cli.System.Net.Sockets.*;
|
||||||
import ikvm.lang.CIL;
|
import ikvm.lang.CIL;
|
||||||
|
import ikvm.lang.ByteArrayHack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unless the application installs its own SocketImplFactory, this is the
|
* Unless the application installs its own SocketImplFactory, this is the
|
||||||
|
@ -60,7 +61,7 @@ class PlainSocketImpl extends SocketImpl
|
||||||
/**
|
/**
|
||||||
* This is the native file descriptor for this socket
|
* This is the native file descriptor for this socket
|
||||||
*/
|
*/
|
||||||
private system.net.sockets.Socket socket;
|
private cli.System.Net.Sockets.Socket socket;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,8 +81,8 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
system.net.sockets.Socket accept = socket.Accept();
|
cli.System.Net.Sockets.Socket accept = socket.Accept();
|
||||||
((PlainSocketImpl)impl).socket = accept;
|
((PlainSocketImpl)impl).socket = accept;
|
||||||
IPEndPoint remoteEndPoint = ((IPEndPoint)accept.get_RemoteEndPoint());
|
IPEndPoint remoteEndPoint = ((IPEndPoint)accept.get_RemoteEndPoint());
|
||||||
long remoteIP = remoteEndPoint.get_Address().get_Address();
|
long remoteIP = remoteEndPoint.get_Address().get_Address();
|
||||||
|
@ -90,10 +91,10 @@ class PlainSocketImpl extends SocketImpl
|
||||||
impl.port = remoteEndPoint.get_Port();
|
impl.port = remoteEndPoint.get_Port();
|
||||||
impl.localport = ((IPEndPoint)accept.get_LocalEndPoint()).get_Port();
|
impl.localport = ((IPEndPoint)accept.get_LocalEndPoint()).get_Port();
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,13 +110,13 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
return socket.get_Available();
|
return socket.get_Available();
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,14 +133,14 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.Bind(new IPEndPoint(getAddressFromInetAddress(addr), port));
|
socket.Bind(new IPEndPoint(getAddressFromInetAddress(addr), port));
|
||||||
this.address = addr;
|
this.address = addr;
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +163,13 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.Close();
|
socket.Close();
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,16 +185,16 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.Connect(new IPEndPoint(getAddressFromInetAddress(addr), port));
|
socket.Connect(new IPEndPoint(getAddressFromInetAddress(addr), port));
|
||||||
this.address = addr;
|
this.address = addr;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.localport = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
|
this.localport = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,13 +230,13 @@ class PlainSocketImpl extends SocketImpl
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket = new system.net.sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
socket = new cli.System.Net.Sockets.Socket(AddressFamily.wrap(AddressFamily.InterNetwork), SocketType.wrap(SocketType.Stream), ProtocolType.wrap(ProtocolType.Tcp));
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,14 +254,14 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.Listen(queuelen);
|
socket.Listen(queuelen);
|
||||||
localport = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
|
localport = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,13 +278,13 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
return socket.Receive(buf, offset, len, SocketFlags.None);
|
return socket.Receive(ByteArrayHack.cast(buf), offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,13 +299,13 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
socket.Send(buf, offset, len, SocketFlags.None);
|
socket.Send(ByteArrayHack.cast(buf), offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new IOException(x.get_Message());
|
throw new IOException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,56 +324,56 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
switch(option_id)
|
switch(option_id)
|
||||||
{
|
{
|
||||||
case SocketOptions.TCP_NODELAY:
|
case SocketOptions.TCP_NODELAY:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, ((Boolean)val).booleanValue() ? 1 : 0);
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Tcp), SocketOptionName.wrap(SocketOptionName.NoDelay), ((Boolean)val).booleanValue() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_KEEPALIVE:
|
case SocketOptions.SO_KEEPALIVE:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, ((Boolean)val).booleanValue() ? 1 : 0);
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.KeepAlive), ((Boolean)val).booleanValue() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_TIMEOUT:
|
case SocketOptions.SO_TIMEOUT:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, ((Integer)val).intValue());
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout), ((Integer)val).intValue());
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, ((Integer)val).intValue());
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendTimeout), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_LINGER:
|
case SocketOptions.SO_LINGER:
|
||||||
{
|
{
|
||||||
system.net.sockets.LingerOption linger;
|
cli.System.Net.Sockets.LingerOption linger;
|
||||||
if(val instanceof Boolean)
|
if(val instanceof Boolean)
|
||||||
{
|
{
|
||||||
linger = new system.net.sockets.LingerOption(false, 0);
|
linger = new cli.System.Net.Sockets.LingerOption(false, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linger = new system.net.sockets.LingerOption(true, ((Integer)val).intValue());
|
linger = new cli.System.Net.Sockets.LingerOption(true, ((Integer)val).intValue());
|
||||||
}
|
}
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, linger);
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Linger), linger);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SocketOptions.SO_OOBINLINE:
|
case SocketOptions.SO_OOBINLINE:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.OutOfBandInline, ((Boolean)val).booleanValue() ? 1 : 0);
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.OutOfBandInline), ((Boolean)val).booleanValue() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_SNDBUF:
|
case SocketOptions.SO_SNDBUF:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, ((Integer)val).intValue());
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendBuffer), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_RCVBUF:
|
case SocketOptions.SO_RCVBUF:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, ((Integer)val).intValue());
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveBuffer), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
case SocketOptions.SO_REUSEADDR:
|
case SocketOptions.SO_REUSEADDR:
|
||||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, ((Boolean)val).booleanValue() ? 1 : 0);
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress), ((Boolean)val).booleanValue() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case SocketOptions.IP_TOS:
|
case SocketOptions.IP_TOS:
|
||||||
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.TypeOfService, ((Integer)val).intValue());
|
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.TypeOfService), ((Integer)val).intValue());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error("Socket.setOption(" + option_id + ") not implemented");
|
throw new Error("Socket.setOption(" + option_id + ") not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new SocketException(x.get_Message());
|
throw new SocketException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +392,7 @@ class PlainSocketImpl extends SocketImpl
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new system.net.sockets.SocketException();
|
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||||
switch(option_id)
|
switch(option_id)
|
||||||
{
|
{
|
||||||
case SocketOptions.SO_BINDADDR:
|
case SocketOptions.SO_BINDADDR:
|
||||||
|
@ -404,14 +405,14 @@ class PlainSocketImpl extends SocketImpl
|
||||||
throw new SocketException(x.getMessage());
|
throw new SocketException(x.getMessage());
|
||||||
}
|
}
|
||||||
case SocketOptions.TCP_NODELAY:
|
case SocketOptions.TCP_NODELAY:
|
||||||
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay)) != 0);
|
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Tcp), SocketOptionName.wrap(SocketOptionName.NoDelay))) != 0);
|
||||||
case SocketOptions.SO_KEEPALIVE:
|
case SocketOptions.SO_KEEPALIVE:
|
||||||
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive)) != 0);
|
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.KeepAlive))) != 0);
|
||||||
case SocketOptions.SO_TIMEOUT:
|
case SocketOptions.SO_TIMEOUT:
|
||||||
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout)));
|
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout))));
|
||||||
case SocketOptions.SO_LINGER:
|
case SocketOptions.SO_LINGER:
|
||||||
{
|
{
|
||||||
system.net.sockets.LingerOption linger = (system.net.sockets.LingerOption)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger);
|
cli.System.Net.Sockets.LingerOption linger = (cli.System.Net.Sockets.LingerOption)socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Linger));
|
||||||
if(linger.get_Enabled())
|
if(linger.get_Enabled())
|
||||||
{
|
{
|
||||||
return new Integer(linger.get_LingerTime());
|
return new Integer(linger.get_LingerTime());
|
||||||
|
@ -419,29 +420,29 @@ class PlainSocketImpl extends SocketImpl
|
||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
case SocketOptions.SO_OOBINLINE:
|
case SocketOptions.SO_OOBINLINE:
|
||||||
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.OutOfBandInline)));
|
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.OutOfBandInline))));
|
||||||
case SocketOptions.SO_SNDBUF:
|
case SocketOptions.SO_SNDBUF:
|
||||||
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer)));
|
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendBuffer))));
|
||||||
case SocketOptions.SO_RCVBUF:
|
case SocketOptions.SO_RCVBUF:
|
||||||
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer)));
|
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveBuffer))));
|
||||||
case SocketOptions.SO_REUSEADDR:
|
case SocketOptions.SO_REUSEADDR:
|
||||||
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress)) != 0);
|
return new Boolean(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress))) != 0);
|
||||||
case SocketOptions.IP_TOS:
|
case SocketOptions.IP_TOS:
|
||||||
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.IP, SocketOptionName.TypeOfService)));
|
return new Integer(CIL.unbox_int(socket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.TypeOfService))));
|
||||||
default:
|
default:
|
||||||
throw new Error("Socket.getOption(" + option_id + ") not implemented");
|
throw new Error("Socket.getOption(" + option_id + ") not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(system.net.sockets.SocketException x)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
throw new SocketException(x.get_Message());
|
throw new SocketException(x.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] getLocalAddress(system.net.sockets.Socket socket)
|
private static byte[] getLocalAddress(cli.System.Net.Sockets.Socket socket)
|
||||||
{
|
{
|
||||||
int address = (int)((system.net.IPEndPoint)socket.get_LocalEndPoint()).get_Address().get_Address();
|
int address = (int)((cli.System.Net.IPEndPoint)socket.get_LocalEndPoint()).get_Address().get_Address();
|
||||||
return new byte[] { (byte)address, (byte)(address >> 8), (byte)(address >> 16), (byte)(address >> 24) };
|
return new byte[] { (byte)address, (byte)(address >> 8), (byte)(address >> 16), (byte)(address >> 24) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Двоичные данные
classpath/mscorlib.jar
Двоичные данные
classpath/mscorlib.jar
Двоичный файл не отображается.
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
package sun.misc;
|
package sun.misc;
|
||||||
|
|
||||||
import system.WeakReference;
|
import cli.System.WeakReference;
|
||||||
|
|
||||||
public abstract class Ref
|
public abstract class Ref
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
<nant buildfile="OpenSystem.Java/OpenSystem.Java.build" />
|
<nant buildfile="OpenSystem.Java/OpenSystem.Java.build" />
|
||||||
<nant buildfile="IK.VM.NET/ik.vm.net.build" />
|
<nant buildfile="IK.VM.NET/ik.vm.net.build" />
|
||||||
<nant buildfile="IK.VM.JNI/ik.vm.jni.build" />
|
<nant buildfile="IK.VM.JNI/ik.vm.jni.build" />
|
||||||
<nant buildfile="netexp/netexp.build" />
|
|
||||||
<nant buildfile="ikvmc/ikvmc.build" />
|
<nant buildfile="ikvmc/ikvmc.build" />
|
||||||
<nant buildfile="classpath/classpath.build" />
|
<nant buildfile="classpath/classpath.build" />
|
||||||
<nant buildfile="ikvm/ikvm.build" />
|
<nant buildfile="ikvm/ikvm.build" />
|
||||||
<nant buildfile="awt/awt.build" />
|
<nant buildfile="awt/awt.build" />
|
||||||
|
<nant buildfile="netexp/netexp.build" />
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -60,6 +60,7 @@ class Compiler
|
||||||
string outputfile = null;
|
string outputfile = null;
|
||||||
string main = null;
|
string main = null;
|
||||||
bool nojni = false;
|
bool nojni = false;
|
||||||
|
ArrayList classesToExclude = new ArrayList();
|
||||||
ArrayList references = new ArrayList();
|
ArrayList references = new ArrayList();
|
||||||
ArrayList arglist = GetArgs(args);
|
ArrayList arglist = GetArgs(args);
|
||||||
if(arglist.Count == 0)
|
if(arglist.Count == 0)
|
||||||
|
@ -77,6 +78,8 @@ class Compiler
|
||||||
Console.Error.WriteLine(" -recurse:<filespec> Recurse directory and include matching files");
|
Console.Error.WriteLine(" -recurse:<filespec> Recurse directory and include matching files");
|
||||||
Console.Error.WriteLine(" -nojni Do not generate JNI stub for native methods");
|
Console.Error.WriteLine(" -nojni Do not generate JNI stub for native methods");
|
||||||
Console.Error.WriteLine(" -resource:<name>=<path> Include file as Java resource");
|
Console.Error.WriteLine(" -resource:<name>=<path> Include file as Java resource");
|
||||||
|
Console.Error.WriteLine(" -exclude:<filename> A file containing a list of classes to exclude");
|
||||||
|
Console.Error.WriteLine(" -debug Creates debugging information for the output file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ArrayList classes = new ArrayList();
|
ArrayList classes = new ArrayList();
|
||||||
|
@ -151,6 +154,14 @@ class Compiler
|
||||||
{
|
{
|
||||||
nojni = true;
|
nojni = true;
|
||||||
}
|
}
|
||||||
|
else if(s.StartsWith("-exclude:"))
|
||||||
|
{
|
||||||
|
ProcessExclusionFile(classesToExclude, s.Substring(9));
|
||||||
|
}
|
||||||
|
else if(s == "-debug")
|
||||||
|
{
|
||||||
|
JVM.Debug = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Warning: Unrecognized option: {0}", s);
|
Console.Error.WriteLine("Warning: Unrecognized option: {0}", s);
|
||||||
|
@ -190,7 +201,7 @@ class Compiler
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
JVM.Compile(outputfile, assemblyname, main, target, (byte[][])classes.ToArray(typeof(byte[])), (string[])references.ToArray(typeof(string)), nojni, resources);
|
JVM.Compile(outputfile, assemblyname, main, target, (byte[][])classes.ToArray(typeof(byte[])), (string[])references.ToArray(typeof(string)), nojni, resources, (string[])classesToExclude.ToArray(typeof(string)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(Exception x)
|
catch(Exception x)
|
||||||
|
@ -263,14 +274,21 @@ class Compiler
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// include as resource
|
// include as resource
|
||||||
using(FileStream fs = new FileStream(file, FileMode.Open))
|
try
|
||||||
{
|
{
|
||||||
byte[] b = new byte[fs.Length];
|
using(FileStream fs = new FileStream(file, FileMode.Open))
|
||||||
fs.Read(b, 0, b.Length);
|
{
|
||||||
// HACK very lame way to extract the resource name (by chopping off the base directory)
|
byte[] b = new byte[fs.Length];
|
||||||
string name = file.Substring(baseDir.FullName.Length + 1);
|
fs.Read(b, 0, b.Length);
|
||||||
name = name.Replace('\\', '/');
|
// HACK very lame way to extract the resource name (by chopping off the base directory)
|
||||||
resources.Add(name, b);
|
string name = file.Substring(baseDir.FullName.Length + 1);
|
||||||
|
name = name.Replace('\\', '/');
|
||||||
|
resources.Add(name, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Warning: Error reading file {0}: Access Denied", file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -289,4 +307,28 @@ class Compiler
|
||||||
Recurse(classes, resources, baseDir, sub, spec);
|
Recurse(classes, resources, baseDir, sub, spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This processes an exclusion file with a single regular expression per line
|
||||||
|
private static void ProcessExclusionFile(ArrayList classesToExclude, String filename)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using(StreamReader file = new StreamReader(filename))
|
||||||
|
{
|
||||||
|
String line;
|
||||||
|
while((line = file.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
line = line.Trim();
|
||||||
|
if(!line.StartsWith("//") && line.Length != 0)
|
||||||
|
{
|
||||||
|
classesToExclude.Add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(FileNotFoundException)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Warning: Could not find exclusion file '{0}'", filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -568,7 +568,23 @@ class ClassFileWriter
|
||||||
if(constantValue != null)
|
if(constantValue != null)
|
||||||
{
|
{
|
||||||
ushort constantValueIndex;
|
ushort constantValueIndex;
|
||||||
if(constantValue is int)
|
if(constantValue is sbyte)
|
||||||
|
{
|
||||||
|
constantValueIndex = AddInt((sbyte)constantValue);
|
||||||
|
}
|
||||||
|
else if(constantValue is bool)
|
||||||
|
{
|
||||||
|
constantValueIndex = AddInt((bool)constantValue ? 1 : 0);
|
||||||
|
}
|
||||||
|
else if(constantValue is short)
|
||||||
|
{
|
||||||
|
constantValueIndex = AddInt((short)constantValue);
|
||||||
|
}
|
||||||
|
else if(constantValue is char)
|
||||||
|
{
|
||||||
|
constantValueIndex = AddInt((char)constantValue);
|
||||||
|
}
|
||||||
|
else if(constantValue is int)
|
||||||
{
|
{
|
||||||
constantValueIndex = AddInt((int)constantValue);
|
constantValueIndex = AddInt((int)constantValue);
|
||||||
}
|
}
|
||||||
|
|
620
netexp/NetExp.cs
620
netexp/NetExp.cs
|
@ -25,8 +25,9 @@ using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections;
|
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
using java.lang;
|
||||||
|
using java.lang.reflect;
|
||||||
|
|
||||||
public class NetExp
|
public class NetExp
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,10 @@ public class NetExp
|
||||||
{
|
{
|
||||||
assembly = Assembly.LoadFrom(args[0]);
|
assembly = Assembly.LoadFrom(args[0]);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assembly = Assembly.LoadWithPartialName(args[0]);
|
||||||
|
}
|
||||||
if(assembly == null)
|
if(assembly == null)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
||||||
|
@ -46,299 +51,19 @@ public class NetExp
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
zipFile = new ZipOutputStream(new FileStream(assembly.GetName().Name + ".jar", FileMode.Create));
|
zipFile = new ZipOutputStream(new FileStream(assembly.GetName().Name + ".jar", FileMode.Create));
|
||||||
|
// HACK if we're doing the "classpath" assembly, also include the remapped types
|
||||||
|
// java.lang.Object and java.lang.Throwable are automatic, because of the $OverrideStub
|
||||||
|
if(args[0] == "classpath")
|
||||||
|
{
|
||||||
|
ProcessClass(assembly.FullName, Class.forName("java.lang.String"), null);
|
||||||
|
ProcessClass(assembly.FullName, Class.forName("java.lang.Comparable"), null);
|
||||||
|
}
|
||||||
ProcessAssembly(assembly);
|
ProcessAssembly(assembly);
|
||||||
zipFile.Close();
|
zipFile.Close();
|
||||||
}
|
}
|
||||||
}
|
// HACK if we run on the "classpath" assembly, the awt thread gets started,
|
||||||
|
// so we force an exit here
|
||||||
private static void ProcessAssembly(Assembly assembly)
|
Environment.Exit(0);
|
||||||
{
|
|
||||||
object[] attribs = assembly.GetCustomAttributes(typeof(CLSCompliantAttribute), false);
|
|
||||||
bool assemblyIsCLSCompliant = true;
|
|
||||||
if(attribs.Length != 1)
|
|
||||||
{
|
|
||||||
assemblyIsCLSCompliant = false;
|
|
||||||
Console.Error.WriteLine("Warning: assembly has no (or multiple) CLS compliance attribute");
|
|
||||||
}
|
|
||||||
else if(!((CLSCompliantAttribute)attribs[0]).IsCompliant)
|
|
||||||
{
|
|
||||||
assemblyIsCLSCompliant = false;
|
|
||||||
Console.Error.WriteLine("Warning: assembly is marked as non-CLS compliant");
|
|
||||||
}
|
|
||||||
foreach(Type t in assembly.GetTypes())
|
|
||||||
{
|
|
||||||
bool typeIsCLSCompliant = true;
|
|
||||||
if(assemblyIsCLSCompliant)
|
|
||||||
{
|
|
||||||
attribs = t.GetCustomAttributes(typeof(CLSCompliantAttribute), false);
|
|
||||||
if(attribs.Length == 1)
|
|
||||||
{
|
|
||||||
typeIsCLSCompliant = ((CLSCompliantAttribute)attribs[0]).IsCompliant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(t.IsPublic && typeIsCLSCompliant)
|
|
||||||
{
|
|
||||||
ProcessType(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static object UnwrapEnum(object o)
|
|
||||||
{
|
|
||||||
// is there a way to generically convert a boxed enum to its boxed underlying value?
|
|
||||||
Type underlyingType = Enum.GetUnderlyingType(o.GetType());
|
|
||||||
if (underlyingType == typeof(long))
|
|
||||||
{
|
|
||||||
o = (long)o;
|
|
||||||
}
|
|
||||||
else if(underlyingType == typeof(int))
|
|
||||||
{
|
|
||||||
o = (int)o;
|
|
||||||
}
|
|
||||||
else if(underlyingType == typeof(short))
|
|
||||||
{
|
|
||||||
o = (short)o;
|
|
||||||
}
|
|
||||||
else if (underlyingType == typeof(sbyte))
|
|
||||||
{
|
|
||||||
o = (sbyte)o;
|
|
||||||
}
|
|
||||||
else if (underlyingType == typeof(ulong))
|
|
||||||
{
|
|
||||||
o = (ulong)o;
|
|
||||||
}
|
|
||||||
else if (underlyingType == typeof(uint))
|
|
||||||
{
|
|
||||||
o = (uint)o;
|
|
||||||
}
|
|
||||||
else if (underlyingType == typeof(ushort))
|
|
||||||
{
|
|
||||||
o = (ushort)o;
|
|
||||||
}
|
|
||||||
else if (underlyingType == typeof(byte))
|
|
||||||
{
|
|
||||||
o = (byte)o;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException(o.GetType().Name);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ClassName(Type t)
|
|
||||||
{
|
|
||||||
if(t == typeof(object))
|
|
||||||
{
|
|
||||||
return "java/lang/Object";
|
|
||||||
}
|
|
||||||
else if(t == typeof(string))
|
|
||||||
{
|
|
||||||
return "java/lang/String";
|
|
||||||
}
|
|
||||||
string name = t.FullName;
|
|
||||||
int lastDot = name.LastIndexOf('.');
|
|
||||||
if(lastDot > 0)
|
|
||||||
{
|
|
||||||
name = name.Substring(0, lastDot).ToLower() + name.Substring(lastDot);
|
|
||||||
}
|
|
||||||
return name.Replace('.', '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the mapped type in signature format (e.g. Ljava/lang/String;)
|
|
||||||
private static string SigType(Type t)
|
|
||||||
{
|
|
||||||
if(t.IsByRef)
|
|
||||||
{
|
|
||||||
return "[" + SigType(t.GetElementType());
|
|
||||||
}
|
|
||||||
if(t.IsEnum)
|
|
||||||
{
|
|
||||||
t = Enum.GetUnderlyingType(t);
|
|
||||||
}
|
|
||||||
if(t == typeof(void))
|
|
||||||
{
|
|
||||||
return "V";
|
|
||||||
}
|
|
||||||
else if(t == typeof(byte) || t == typeof(sbyte))
|
|
||||||
{
|
|
||||||
return "B";
|
|
||||||
}
|
|
||||||
else if(t == typeof(bool))
|
|
||||||
{
|
|
||||||
return "Z";
|
|
||||||
}
|
|
||||||
else if(t == typeof(short) || t == typeof(ushort))
|
|
||||||
{
|
|
||||||
return "S";
|
|
||||||
}
|
|
||||||
else if(t == typeof(char))
|
|
||||||
{
|
|
||||||
return "C";
|
|
||||||
}
|
|
||||||
else if(t == typeof(int) || t == typeof(uint))
|
|
||||||
{
|
|
||||||
return "I";
|
|
||||||
}
|
|
||||||
else if(t == typeof(long) || t == typeof(ulong))
|
|
||||||
{
|
|
||||||
return "J";
|
|
||||||
}
|
|
||||||
else if(t == typeof(float))
|
|
||||||
{
|
|
||||||
return "F";
|
|
||||||
}
|
|
||||||
else if(t == typeof(double))
|
|
||||||
{
|
|
||||||
return "D";
|
|
||||||
}
|
|
||||||
else if(t == typeof(IntPtr))
|
|
||||||
{
|
|
||||||
// HACK
|
|
||||||
return "I";
|
|
||||||
}
|
|
||||||
else if(t.IsArray)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
while(t.IsArray)
|
|
||||||
{
|
|
||||||
sb.Append('[');
|
|
||||||
t = t.GetElementType();
|
|
||||||
}
|
|
||||||
sb.Append(SigType(t));
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
else if(!t.IsPrimitive)
|
|
||||||
{
|
|
||||||
return "L" + ClassName(t) + ";";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException(t.FullName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ProcessType(Type type)
|
|
||||||
{
|
|
||||||
if(type == typeof(object))// || type == typeof(string))
|
|
||||||
{
|
|
||||||
// special case for System.Object & System.String, don't emit those
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
string name = ClassName(type);
|
|
||||||
if(type == typeof(string))
|
|
||||||
{
|
|
||||||
name = "system/String";
|
|
||||||
}
|
|
||||||
string super;
|
|
||||||
if(type.BaseType == null)
|
|
||||||
{
|
|
||||||
// in .NET interfaces don't have a baseType, but in Java they "extend" java/lang/Object
|
|
||||||
super = "java/lang/Object";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(type == typeof(Exception))
|
|
||||||
{
|
|
||||||
super = "java/lang/Throwable";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
super = ClassName(type.BaseType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Modifiers mods = Modifiers.Public | Modifiers.Super;
|
|
||||||
if(type.IsInterface)
|
|
||||||
{
|
|
||||||
mods |= Modifiers.Interface;
|
|
||||||
}
|
|
||||||
if(type.IsSealed)
|
|
||||||
{
|
|
||||||
mods |= Modifiers.Final;
|
|
||||||
}
|
|
||||||
if(type.IsAbstract)
|
|
||||||
{
|
|
||||||
mods |= Modifiers.Abstract;
|
|
||||||
}
|
|
||||||
ClassFileWriter f = new ClassFileWriter(mods, name, super);
|
|
||||||
f.AddStringAttribute("IK.VM.NET.Type", type.AssemblyQualifiedName);
|
|
||||||
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
|
|
||||||
Hashtable clashtable = new Hashtable();
|
|
||||||
for(int i = 0; i < fields.Length; i++)
|
|
||||||
{
|
|
||||||
if(fields[i].IsPublic || fields[i].IsFamily)
|
|
||||||
{
|
|
||||||
object[] attribs = fields[i].GetCustomAttributes(typeof(CLSCompliantAttribute), false);
|
|
||||||
if(attribs.Length == 1 && !((CLSCompliantAttribute)attribs[0]).IsCompliant)
|
|
||||||
{
|
|
||||||
// skip non-CLS compliant field
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessField(type, f, fields[i], clashtable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clashtable.Clear();
|
|
||||||
ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
for(int i = 0; i < constructors.Length; i++)
|
|
||||||
{
|
|
||||||
if(constructors[i].IsPublic || constructors[i].IsFamily)
|
|
||||||
{
|
|
||||||
object[] attribs = constructors[i].GetCustomAttributes(typeof(CLSCompliantAttribute), false);
|
|
||||||
if(attribs.Length == 1 && !((CLSCompliantAttribute)attribs[0]).IsCompliant)
|
|
||||||
{
|
|
||||||
// skip non-CLS compliant constructor
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessMethod(type, f, constructors[i], clashtable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
|
|
||||||
for(int i = 0; i < methods.Length; i++)
|
|
||||||
{
|
|
||||||
if(methods[i].IsPublic || methods[i].IsFamily)
|
|
||||||
{
|
|
||||||
object[] attribs = methods[i].GetCustomAttributes(typeof(CLSCompliantAttribute), false);
|
|
||||||
if(attribs.Length == 1 && !((CLSCompliantAttribute)attribs[0]).IsCompliant)
|
|
||||||
{
|
|
||||||
// skip non-CLS compliant method
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessMethod(type, f, methods[i], clashtable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for delegates we have to construct the inner interface
|
|
||||||
if(type.IsSubclassOf(typeof(MulticastDelegate)))
|
|
||||||
{
|
|
||||||
InnerClassesAttribute innerclasses = new InnerClassesAttribute(f);
|
|
||||||
string outer = ClassName(type);
|
|
||||||
innerclasses.Add(outer + "$Method", outer, "Method", 0x609);
|
|
||||||
f.AddAttribute(innerclasses);
|
|
||||||
// now we construct the inner interface type
|
|
||||||
ClassFileWriter iface = new ClassFileWriter(Modifiers.Interface | Modifiers.Public | Modifiers.Abstract, outer + "$Method", "java/lang/Object");
|
|
||||||
MethodInfo invoke = type.GetMethod("Invoke");
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.Append('(');
|
|
||||||
ParameterInfo[] parameters = invoke.GetParameters();
|
|
||||||
for(int i = 0; i < parameters.Length; i++)
|
|
||||||
{
|
|
||||||
sb.Append(SigType(parameters[i].ParameterType));
|
|
||||||
}
|
|
||||||
sb.Append(')');
|
|
||||||
sb.Append(SigType(invoke.ReturnType));
|
|
||||||
// TODO IK.VM.NET.Sig must be set here as well
|
|
||||||
iface.AddMethod(Modifiers.Public | Modifiers.Abstract, "Invoke", sb.ToString());
|
|
||||||
innerclasses = new InnerClassesAttribute(iface);
|
|
||||||
innerclasses.Add(outer + "$Method", outer, "Method", 0x609);
|
|
||||||
iface.AddAttribute(innerclasses);
|
|
||||||
WriteClass(outer + "$Method.class", iface);
|
|
||||||
}
|
|
||||||
WriteClass(name + ".class", f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteClass(string name, ClassFileWriter c)
|
private static void WriteClass(string name, ClassFileWriter c)
|
||||||
|
@ -347,164 +72,219 @@ public class NetExp
|
||||||
c.Write(zipFile);
|
c.Write(zipFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessField(Type type, ClassFileWriter f, FieldInfo fi, Hashtable clashtable)
|
private class MyClassLoader : ClassLoader
|
||||||
{
|
{
|
||||||
Modifiers access;
|
public Class loadClass(Type type)
|
||||||
if(fi.IsPublic)
|
|
||||||
{
|
{
|
||||||
access = Modifiers.Public;
|
return base.loadClass(type.AssemblyQualifiedName);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
access = Modifiers.Protected;
|
|
||||||
}
|
|
||||||
object v = null;
|
|
||||||
if(fi.IsLiteral)
|
|
||||||
{
|
|
||||||
v = fi.GetValue(null);
|
|
||||||
if(v is Enum)
|
|
||||||
{
|
|
||||||
v = UnwrapEnum(v);
|
|
||||||
}
|
|
||||||
if(v is byte)
|
|
||||||
{
|
|
||||||
v = (int)(byte)v;
|
|
||||||
}
|
|
||||||
else if (v is sbyte)
|
|
||||||
{
|
|
||||||
v = (int)(sbyte)v;
|
|
||||||
}
|
|
||||||
else if(v is char)
|
|
||||||
{
|
|
||||||
v = (int)(char)v;
|
|
||||||
}
|
|
||||||
else if(v is short)
|
|
||||||
{
|
|
||||||
v = (int)(short)v;
|
|
||||||
}
|
|
||||||
else if(v is ushort)
|
|
||||||
{
|
|
||||||
v = (int)(ushort)v;
|
|
||||||
}
|
|
||||||
else if(v is bool)
|
|
||||||
{
|
|
||||||
v = ((bool)v) ? 1 : 0;
|
|
||||||
}
|
|
||||||
else if(v is int || v is uint || v is ulong || v is long || v is float || v is double || v is string)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException(v.GetType().FullName);
|
|
||||||
}
|
|
||||||
access |= Modifiers.Static | Modifiers.Final;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(fi.IsInitOnly)
|
|
||||||
{
|
|
||||||
access |= Modifiers.Final;
|
|
||||||
}
|
|
||||||
if(fi.IsStatic)
|
|
||||||
{
|
|
||||||
access |= Modifiers.Static;
|
|
||||||
}
|
|
||||||
if(type.IsEnum)
|
|
||||||
{
|
|
||||||
// we don't want the value__ field
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
string sig = SigType(fi.FieldType);
|
|
||||||
string key = fi.Name + sig;
|
|
||||||
if(clashtable.ContainsKey(key))
|
|
||||||
{
|
|
||||||
// TODO instead of skipping, we should mangle the name
|
|
||||||
Console.Error.WriteLine("Skipping field " + type.FullName + "." + fi.Name + " (type " + sig + ") because it clashes");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clashtable.Add(key, key);
|
|
||||||
f.AddField(access, fi.Name, sig, v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessMethod(Type type, ClassFileWriter f, MethodBase mb, Hashtable clashtable)
|
private static void ProcessAssembly(Assembly assembly)
|
||||||
{
|
{
|
||||||
Modifiers access = 0;
|
// HACK we use our own class loader to prevent class initialization
|
||||||
if(!mb.IsAbstract)
|
MyClassLoader loader = new MyClassLoader();
|
||||||
|
foreach(Type t in assembly.GetTypes())
|
||||||
{
|
{
|
||||||
access = Modifiers.Native;
|
if(t.IsPublic)
|
||||||
|
{
|
||||||
|
ProcessClass(assembly.FullName, loader.loadClass(t), null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(mb.IsPublic)
|
}
|
||||||
|
|
||||||
|
private static void ProcessClass(string assemblyName, Class c, Class outer)
|
||||||
|
{
|
||||||
|
string name = c.getName().Replace('.', '/');
|
||||||
|
//Console.WriteLine(name);
|
||||||
|
string super = null;
|
||||||
|
if(c.getSuperclass() != null)
|
||||||
{
|
{
|
||||||
access |= Modifiers.Public;
|
super = c.getSuperclass().getName().Replace('.', '/');
|
||||||
}
|
}
|
||||||
else
|
if(c.isInterface())
|
||||||
{
|
{
|
||||||
access |= Modifiers.Protected;
|
super = "java/lang/Object";
|
||||||
}
|
}
|
||||||
if(mb.IsFinal || !mb.IsVirtual)
|
ClassFileWriter f = new ClassFileWriter((Modifiers)c.getModifiers(), name, super);
|
||||||
|
f.AddStringAttribute("IKVM.NET.Assembly", assemblyName);
|
||||||
|
InnerClassesAttribute innerClassesAttribute = null;
|
||||||
|
if(outer != null)
|
||||||
{
|
{
|
||||||
access |= Modifiers.Final;
|
innerClassesAttribute = new InnerClassesAttribute(f);
|
||||||
|
innerClassesAttribute.Add(name, outer.getName().Replace('.', '/'), null, (ushort)Modifiers.Public);
|
||||||
}
|
}
|
||||||
if(mb.IsStatic)
|
Class[] innerClasses = c.getDeclaredClasses();
|
||||||
|
for(int i = 0; i < innerClasses.Length; i++)
|
||||||
{
|
{
|
||||||
access |= Modifiers.Static;
|
Modifiers mods = (Modifiers)innerClasses[i].getModifiers();
|
||||||
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
||||||
|
{
|
||||||
|
if(innerClassesAttribute == null)
|
||||||
|
{
|
||||||
|
innerClassesAttribute = new InnerClassesAttribute(f);
|
||||||
|
}
|
||||||
|
string namePart = innerClasses[i].getName();
|
||||||
|
namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
|
||||||
|
innerClassesAttribute.Add(innerClasses[i].getName().Replace('.', '/'), name, namePart, (ushort)innerClasses[i].getModifiers());
|
||||||
|
ProcessClass(assemblyName, innerClasses[i], c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(mb.IsAbstract)
|
Constructor[] constructors = c.getDeclaredConstructors();
|
||||||
|
for(int i = 0; i < constructors.Length; i++)
|
||||||
{
|
{
|
||||||
access |= Modifiers.Abstract;
|
Modifiers mods = (Modifiers)constructors[i].getModifiers();
|
||||||
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
||||||
|
{
|
||||||
|
f.AddMethod(mods | Modifiers.Native, "<init>", MakeSig(constructors[i].getParameterTypes(), java.lang.Void.TYPE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// special case for delegate constructors!
|
Method[] methods = c.getDeclaredMethods();
|
||||||
if(mb.IsConstructor && type.IsSubclassOf(typeof(MulticastDelegate)))
|
for(int i = 0; i < methods.Length; i++)
|
||||||
{
|
{
|
||||||
access &= ~Modifiers.Final;
|
Modifiers mods = (Modifiers)methods[i].getModifiers();
|
||||||
f.AddMethod(access, "<init>", "(L" + ClassName(type) + "$Method;)V");
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
||||||
return;
|
{
|
||||||
|
if((mods & Modifiers.Abstract) == 0)
|
||||||
|
{
|
||||||
|
mods |= Modifiers.Native;
|
||||||
|
}
|
||||||
|
f.AddMethod(mods, methods[i].getName(), MakeSig(methods[i].getParameterTypes(), methods[i].getReturnType()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// HACK the native signature is really is very lame way of storing the signature
|
Field[] fields = c.getDeclaredFields();
|
||||||
// TODO only store it when it doesn't match the Java sig and split it into parts (instead of one giant string)
|
for(int i = 0; i < fields.Length; i++)
|
||||||
StringBuilder nativesig = new StringBuilder();
|
{
|
||||||
|
Modifiers mods = (Modifiers)fields[i].getModifiers();
|
||||||
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
||||||
|
{
|
||||||
|
object constantValue = null;
|
||||||
|
// HACK we only look for constants on static final fields, to trigger less static initializers
|
||||||
|
if((mods & (Modifiers.Final | Modifiers.Static)) == (Modifiers.Final | Modifiers.Static))
|
||||||
|
{
|
||||||
|
// HACK we use a non-standard API to get constant value
|
||||||
|
// NOTE we can't use Field.get() because that will run the static initializer and
|
||||||
|
// also won't allow us to see the difference between constants and blank final fields.
|
||||||
|
constantValue = NativeCode.java.lang.reflect.Field.getConstant(fields[i]);
|
||||||
|
if(constantValue != null)
|
||||||
|
{
|
||||||
|
if(constantValue is java.lang.Boolean)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Boolean)constantValue).booleanValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Byte)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Byte)constantValue).byteValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Short)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Short)constantValue).shortValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Character)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Character)constantValue).charValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Integer)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Integer)constantValue).intValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Long)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Long)constantValue).longValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Float)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Float)constantValue).floatValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is java.lang.Double)
|
||||||
|
{
|
||||||
|
constantValue = ((java.lang.Double)constantValue).doubleValue();
|
||||||
|
}
|
||||||
|
else if(constantValue is string)
|
||||||
|
{
|
||||||
|
// no conversion needed
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.AddField(mods, fields[i].getName(), ClassToSig(fields[i].getType()), constantValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(innerClassesAttribute != null)
|
||||||
|
{
|
||||||
|
f.AddAttribute(innerClassesAttribute);
|
||||||
|
}
|
||||||
|
WriteClass(name + ".class", f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string MakeSig(Class[] args, Class ret)
|
||||||
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.Append('(');
|
sb.Append('(');
|
||||||
ParameterInfo[] parameters = mb.GetParameters();
|
for(int i = 0; i < args.Length; i++)
|
||||||
string sep = "";
|
|
||||||
for(int i = 0; i < parameters.Length; i++)
|
|
||||||
{
|
{
|
||||||
if(parameters[i].ParameterType.IsPointer)
|
sb.Append(ClassToSig(args[i]));
|
||||||
{
|
|
||||||
// Java doesn't support pointer parameters
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sb.Append(SigType(parameters[i].ParameterType));
|
|
||||||
nativesig.Append(sep).Append(parameters[i].ParameterType.AssemblyQualifiedName);
|
|
||||||
sep = "|";
|
|
||||||
}
|
}
|
||||||
sb.Append(')');
|
sb.Append(')');
|
||||||
if(mb.IsConstructor)
|
sb.Append(ClassToSig(ret));
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ClassToSig(Class c)
|
||||||
|
{
|
||||||
|
if(c.isPrimitive())
|
||||||
{
|
{
|
||||||
// HACK constructors may not be final in Java
|
if(c == java.lang.Void.TYPE)
|
||||||
access &= ~Modifiers.Final;
|
{
|
||||||
sb.Append('V');
|
return "V";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Byte.TYPE)
|
||||||
|
{
|
||||||
|
return "B";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Boolean.TYPE)
|
||||||
|
{
|
||||||
|
return "Z";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Short.TYPE)
|
||||||
|
{
|
||||||
|
return "S";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Character.TYPE)
|
||||||
|
{
|
||||||
|
return "C";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Integer.TYPE)
|
||||||
|
{
|
||||||
|
return "I";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Long.TYPE)
|
||||||
|
{
|
||||||
|
return "J";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Float.TYPE)
|
||||||
|
{
|
||||||
|
return "F";
|
||||||
|
}
|
||||||
|
else if(c == java.lang.Double.TYPE)
|
||||||
|
{
|
||||||
|
return "D";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(c.isArray())
|
||||||
|
{
|
||||||
|
return "[" + ClassToSig(c.getComponentType());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.Append(SigType(((MethodInfo)mb).ReturnType));
|
return "L" + c.getName().Replace('.', '/') + ";";
|
||||||
}
|
|
||||||
string name = mb.IsConstructor ? "<init>" : mb.Name;
|
|
||||||
string sig = sb.ToString();
|
|
||||||
string key = name + sig;
|
|
||||||
if(clashtable.ContainsKey(key))
|
|
||||||
{
|
|
||||||
// TODO instead of skipping, we should mangle the name
|
|
||||||
Console.Error.WriteLine("Skipping method " + type.FullName + "." + name + sig + " because it clashes");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clashtable.Add(key, key);
|
|
||||||
f.AddMethod(access, name, sig)
|
|
||||||
.AddAttribute(new StringAttribute(f.AddUtf8("IK.VM.NET.Sig"), f.AddUtf8(nativesig.ToString())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
<includes name="*.cs" />
|
<includes name="*.cs" />
|
||||||
</sources>
|
</sources>
|
||||||
<references>
|
<references>
|
||||||
|
<includes name="../bin/classpath.dll" asis="true" />
|
||||||
|
<includes name="../bin/ik.vm.net.dll" asis="true" />
|
||||||
|
<includes name="../bin/OpenSystem.Java.dll" asis="true" />
|
||||||
<includes name="../bin/SharpZipLib.dll" asis="true" />
|
<includes name="../bin/SharpZipLib.dll" asis="true" />
|
||||||
</references>
|
</references>
|
||||||
</csc>
|
</csc>
|
||||||
|
|
|
@ -84,6 +84,21 @@
|
||||||
AssemblyName = "SharpZipLib"
|
AssemblyName = "SharpZipLib"
|
||||||
HintPath = "..\bin\SharpZipLib.dll"
|
HintPath = "..\bin\SharpZipLib.dll"
|
||||||
/>
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "IK.VM.NET"
|
||||||
|
Project = "{F5C7B588-0403-4AF2-A4DE-5697DE21BC2C}"
|
||||||
|
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "OpenSystem.Java"
|
||||||
|
Project = "{13A5BB9F-D5FB-4061-BB0C-A111BE84A978}"
|
||||||
|
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "classpath"
|
||||||
|
AssemblyName = "classpath"
|
||||||
|
HintPath = "..\bin\classpath.dll"
|
||||||
|
/>
|
||||||
</References>
|
</References>
|
||||||
</Build>
|
</Build>
|
||||||
<Files>
|
<Files>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче