This commit is contained in:
jfrijters 2003-08-21 10:06:34 +00:00
Родитель 57c81013a1
Коммит 9d6bf7d010
36 изменённых файлов: 1948 добавлений и 1543 удалений

Просмотреть файл

@ -484,11 +484,11 @@ class ClassFile
}
}
internal string NetExpTypeAttribute
internal string NetExpAssemblyAttribute
{
get
{
Attribute attr = GetAttribute("IK.VM.NET.Type");
Attribute attr = GetAttribute("IKVM.NET.Assembly");
if(attr != null)
{
return ((ConstantPoolItemUtf8)GetConstantPoolItem(attr.Data.ReadUInt16())).Value;

Просмотреть файл

@ -126,7 +126,7 @@ class ClassLoaderWrapper
this.javaClassLoader = javaClassLoader;
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));
}
internal static bool IsRemappedType(Type type)
{
return typeToTypeWrapper[type] is RemappedTypeWrapper;
}
internal void LoadRemappedTypes()
{
nativeMethods = new Hashtable();
@ -161,7 +166,9 @@ class ClassLoaderWrapper
baseWrapper = null;
}
TypeWrapper tw = new RemappedTypeWrapper(this, modifiers, name, type, new TypeWrapper[0], baseWrapper);
Debug.Assert(!types.ContainsKey(name));
types.Add(name, tw);
Debug.Assert(!typeToTypeWrapper.ContainsKey(tw.Type));
typeToTypeWrapper.Add(tw.Type, tw);
}
// find the ghost interfaces
@ -301,16 +308,44 @@ class ClassLoaderWrapper
Type t = Type.GetType(name);
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 != "")
{
type = GetBootstrapType(name);
}
if(type != null)
{
return type;
Type t = GetBootstrapTypeRaw(name);
if(t != null)
{
return GetWrapperFromBootstrapType(t);
}
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)
{
@ -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
Debug.Assert(this == GetBootstrapClassLoader());
string name = NativeCode.java.lang.VMClass.getName(type);
TypeWrapper wrapper = (TypeWrapper)types[name];
if(wrapper == null)
TypeWrapper wrapper = null;
if(type.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false))
{
wrapper = new CompiledTypeWrapper(name, 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;
string name = CompiledTypeWrapper.GetName(type);
wrapper = (TypeWrapper)types[name];
if(wrapper == null)
{
// TODO instead of using CompiledTypeWrapper here, we probably should
// have a subclass that converts all instance methods to static methods (and
// makes the class appear final with only a private constructor)
// since this type was compiled from Java source, we have to look for our
// attributes
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;
@ -398,18 +444,11 @@ class ClassLoaderWrapper
return t;
}
}
// HACK we also try mscorlib and this assembly (for the remapped types)
// TODO this should be fixed by making the map.xml type names for .NET types assembly qualified
return Type.GetType(name);
return null;
}
internal virtual TypeWrapper GetBootstrapType(string name)
internal virtual TypeWrapper GetTypeWrapperCompilerHook(string name)
{
Type t = GetBootstrapTypeRaw(name);
if(t != null)
{
return GetCompiledTypeWrapper(t);
}
return null;
}
@ -454,10 +493,12 @@ class ClassLoaderWrapper
modifiers |= Modifiers.Public;
}
wrapper = new ArrayTypeWrapper(array, modifiers, name, this);
Debug.Assert(!types.ContainsKey(name));
types.Add(name, wrapper);
if(!(elementType is TypeBuilder))
{
typeToTypeWrapper[array] = wrapper;
Debug.Assert(!typeToTypeWrapper.ContainsKey(array));
typeToTypeWrapper.Add(array, wrapper);
}
}
return wrapper;
@ -510,14 +551,24 @@ class ClassLoaderWrapper
{
throw JavaException.IncompatibleClassChangeError("Class {0} has interface {1} as superclass", f.Name, baseType.Name);
}
string dotnetType = f.NetExpTypeAttribute;
if(dotnetType != null)
string dotnetAssembly = f.NetExpAssemblyAttribute;
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
{
type = new DynamicTypeWrapper(f, this, nativeMethods);
Debug.Assert(!dynamicTypes.ContainsKey(type.Type.FullName));
dynamicTypes.Add(type.Type.FullName, type);
}
Debug.Assert(types[f.Name] == null);
@ -856,7 +907,8 @@ class ClassLoaderWrapper
// if we found it, store it in the map
if(wrapper != null)
{
typeToTypeWrapper[type] = wrapper;
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
typeToTypeWrapper.Add(type, wrapper);
}
}
return wrapper;
@ -880,58 +932,14 @@ class ClassLoaderWrapper
}
wrapper = GetWrapperFromType(elem);
// HACK this is a lame way of creating the array wrapper
if(wrapper.IsPrimitive)
{
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 + ";");
}
return wrapper.GetClassLoader().LoadClassByDottedName(new String('[', rank) + wrapper.SigName);
}
// 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
// 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
// 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;
}
@ -939,6 +947,7 @@ class ClassLoaderWrapper
internal static void SetWrapperForType(Type type, TypeWrapper wrapper)
{
TypeWrapper.AssertFinished(type);
Debug.Assert(!typeToTypeWrapper.ContainsKey(type));
typeToTypeWrapper.Add(type, wrapper);
}

Просмотреть файл

@ -151,7 +151,7 @@ public abstract class CodeEmitter
{
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 byte || constant is sbyte ||
constant is char ||
@ -159,6 +159,10 @@ public abstract class CodeEmitter
{
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)
{
return CodeEmitter.Create(OpCodes.Ldstr, (string)constant);
@ -171,17 +175,29 @@ public abstract class CodeEmitter
{
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);
}
else if(constant is ulong)
{
return CodeEmitter.Create(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
}
else if(constant is Enum)
{
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));
}
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
{
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));

Просмотреть файл

@ -531,8 +531,9 @@ sealed class FieldWrapper : MemberWrapper
internal readonly CodeEmitter EmitSet;
private FieldInfo field;
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)
{
Debug.Assert(fieldType != null);
@ -543,10 +544,48 @@ sealed class FieldWrapper : MemberWrapper
this.name = name;
this.sig = sig;
this.fieldType = fieldType;
this.field = field;
this.EmitGet = emitGet;
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)
{
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)
@ -697,7 +736,7 @@ sealed class FieldWrapper : MemberWrapper
{
emitGet += 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)
{
@ -712,7 +751,7 @@ sealed class FieldWrapper : MemberWrapper
// TODO shouldn't we use += here (for volatile fields inside of value types)?
emitGet = new VolatileLongDoubleGetter(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;
emitSet += CodeEmitter.Volatile;
@ -731,7 +770,7 @@ sealed class FieldWrapper : MemberWrapper
{
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()
@ -751,7 +790,7 @@ sealed class FieldWrapper : MemberWrapper
internal void SetValue(object obj, object val)
{
// TODO this is a broken implementation (for one thing, it needs to support redirection)
if(field == null)
if(field == null || field is FieldBuilder)
{
LookupField();
}
@ -761,7 +800,7 @@ sealed class FieldWrapper : MemberWrapper
internal object GetValue(object obj)
{
// TODO this is a broken implementation (for one thing, it needs to support redirection)
if(field == null)
if(field == null || field is FieldBuilder)
{
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);
// class name in the sig should be dotted
@ -178,6 +178,11 @@ sealed class MethodDescriptor
}
else
{
if(type.IsByRef)
{
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
// TODO test type for unsupported types
}
name = GetSigNameFromType(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)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
@ -348,6 +355,7 @@ class EmitHelper
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.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
// 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;
}
@ -444,14 +452,20 @@ class AttributeHelper
{
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)
{
modifiers |= Modifiers.Static;
}
if((mb.GetMethodImplementationFlags() & MethodImplAttributes.Synchronized) != 0)
{
modifiers |= Modifiers.Synchronized;
}
if((mb.Attributes & MethodAttributes.PinvokeImpl) != 0)
{
modifiers |= Modifiers.Native;
@ -597,6 +611,15 @@ class AttributeHelper
CustomAttributeBuilder attrib = new CustomAttributeBuilder(typeof(UnloadableTypeAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { name });
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
@ -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
{
get
@ -1361,22 +1393,32 @@ class UnloadableTypeWrapper : TypeWrapper
class PrimitiveTypeWrapper : TypeWrapper
{
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(sbyte));
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(typeof(char));
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double));
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float));
internal static readonly PrimitiveTypeWrapper INT = new PrimitiveTypeWrapper(typeof(int));
internal static readonly PrimitiveTypeWrapper LONG = new PrimitiveTypeWrapper(typeof(long));
internal static readonly PrimitiveTypeWrapper SHORT = new PrimitiveTypeWrapper(typeof(short));
internal static readonly PrimitiveTypeWrapper BOOLEAN = new PrimitiveTypeWrapper(typeof(bool));
internal static readonly PrimitiveTypeWrapper VOID = new PrimitiveTypeWrapper(typeof(void));
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(sbyte), "B");
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(typeof(char), "C");
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double), "D");
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float), "F");
internal static readonly PrimitiveTypeWrapper INT = new PrimitiveTypeWrapper(typeof(int), "I");
internal static readonly PrimitiveTypeWrapper LONG = new PrimitiveTypeWrapper(typeof(long), "J");
internal static readonly PrimitiveTypeWrapper SHORT = new PrimitiveTypeWrapper(typeof(short), "S");
internal static readonly PrimitiveTypeWrapper BOOLEAN = new PrimitiveTypeWrapper(typeof(bool), "Z");
internal static readonly PrimitiveTypeWrapper VOID = new PrimitiveTypeWrapper(typeof(void), "V");
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)
{
this.type = type;
this.sigName = sigName;
}
internal override string SigName
{
get
{
return sigName;
}
}
internal override ClassLoaderWrapper GetClassLoader()
@ -1721,16 +1763,11 @@ class DynamicTypeWrapper : TypeWrapper
{
declaringTypeWrapper = classFile.GetConstantPoolClassType(innerclasses[i].outerClass, wrapper.GetClassLoader());
reflectiveModifiers = innerclasses[i].accessFlags;
Type[] argTypes = new Type[] { typeof(string), typeof(string), typeof(string), typeof(Modifiers) };
object[] args = new object[] {
AttributeHelper.SetInnerClass(typeBuilder,
classFile.GetConstantPoolClass(innerclasses[i].innerClass),
classFile.GetConstantPoolClass(innerclasses[i].outerClass),
innerclasses[i].name == 0 ? null : classFile.GetConstantPoolUtf8String(innerclasses[i].name),
reflectiveModifiers
};
ConstructorInfo ci = typeof(InnerClassAttribute).GetConstructor(argTypes);
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(ci, args);
typeBuilder.SetCustomAttribute(customAttributeBuilder);
reflectiveModifiers);
}
}
}
@ -2227,7 +2264,7 @@ class DynamicTypeWrapper : TypeWrapper
// 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
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
{
@ -2292,7 +2329,7 @@ class DynamicTypeWrapper : TypeWrapper
{
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
{
@ -3232,7 +3269,7 @@ class RemappedTypeWrapper : TypeWrapper
}
CodeEmitter setter = CodeEmitter.Throw("java.lang.IllegalAccessError", "Redirected field " + this.Name + "." + fieldName + " is read-only");
// 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);
}
}
@ -3515,199 +3552,31 @@ class RemappedTypeWrapper : TypeWrapper
}
}
class NetExpTypeWrapper : TypeWrapper
{
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()
{
}
}
// TODO CompiledTypeWrapper & DotNetTypeWrapper should have a common base class
class CompiledTypeWrapper : TypeWrapper
{
private readonly Type type;
private TypeWrapper[] interfaces;
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
private static TypeWrapper GetBaseTypeWrapper(Type type)
internal static TypeWrapper GetBaseTypeWrapper(Type type)
{
if(type.IsInterface)
{
@ -3727,12 +3596,15 @@ class CompiledTypeWrapper : TypeWrapper
internal CompiledTypeWrapper(string name, Type type)
: base(GetModifiers(type), name, GetBaseTypeWrapper(type), ClassLoaderWrapper.GetBootstrapClassLoader())
{
Debug.Assert(!type.IsDefined(typeof(HideFromReflectionAttribute), false));
Debug.Assert(!(type is TypeBuilder));
Debug.Assert(!type.IsArray);
Debug.Assert(!ClassLoaderWrapper.IsRemappedType(type));
this.type = type;
}
private static Modifiers GetModifiers(Type type)
internal static Modifiers GetModifiers(Type type)
{
try
{
@ -3922,7 +3794,7 @@ class CompiledTypeWrapper : TypeWrapper
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)
@ -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
{
private static TypeWrapper[] interfaces;
@ -4101,6 +4522,15 @@ class ArrayTypeWrapper : TypeWrapper
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
{
get

Просмотреть файл

@ -179,6 +179,10 @@ namespace NativeCode.java
{
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)
{
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 });
}
else if(o is ushort)
{
return Activator.CreateInstance(java_lang_Short, new object[] { (short)(ushort)o });
}
else if(o is char)
{
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 });
}
else if(o is uint)
{
return Activator.CreateInstance(java_lang_Integer, new object[] { (int)(uint)o });
}
else if(o is long)
{
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)
{
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 });
}
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
{
throw new NotImplementedException(o.GetType().FullName);
@ -327,6 +375,14 @@ namespace NativeCode.java
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)
{
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
@ -951,28 +1007,28 @@ namespace NativeCode.java
return null;
}
public static Type getPrimitiveType(char type)
public static object getPrimitiveClass(char type)
{
switch(type)
{
case 'Z':
return typeof(bool);
return VMClass.getClassFromType(typeof(bool));
case 'B':
return typeof(sbyte);
return VMClass.getClassFromType(typeof(sbyte));
case 'C':
return typeof(char);
return VMClass.getClassFromType(typeof(char));
case 'D':
return typeof(double);
return VMClass.getClassFromType(typeof(double));
case 'F':
return typeof(float);
return VMClass.getClassFromType(typeof(float));
case 'I':
return typeof(int);
return VMClass.getClassFromType(typeof(int));
case 'J':
return typeof(long);
return VMClass.getClassFromType(typeof(long));
case 'S':
return typeof(short);
return VMClass.getClassFromType(typeof(short));
case 'V':
return typeof(void);
return VMClass.getClassFromType(typeof(void));
default:
throw new InvalidOperationException();
}
@ -990,7 +1046,7 @@ namespace NativeCode.java
throw JavaException.NoClassDefFoundError("{0} (wrong name: {1})", name, classFile.Name);
}
TypeWrapper type = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader).DefineClass(classFile);
object clazz = VMClass.CreateInstance(null, type);
object clazz = VMClass.CreateClassInstance(type);
if(protectionDomain != null)
{
// TODO cache the FieldInfo
@ -1008,8 +1064,9 @@ namespace NativeCode.java
public class VMClass
{
private static Hashtable map = new Hashtable();
private static MethodInfo createClass;
private static MethodInfo getTypeMethod;
private delegate object CreateClassDelegate(object typeWrapper);
private static CreateClassDelegate CreateClass;
private static MethodInfo getWrapper;
public static void throwException(Exception e)
{
@ -1038,20 +1095,27 @@ namespace NativeCode.java
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)
{
if(type != null)
{
map.Add(type, clazz);
}
if(wrapper != null)
{
map.Add(wrapper, clazz);
@ -1060,11 +1124,21 @@ namespace NativeCode.java
return clazz;
}
public static bool IsAssignableFrom(Object w1, Object w2)
public static bool IsAssignableFrom(object w1, object w2)
{
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)
{
TypeWrapper baseWrapper = ((TypeWrapper)wrapper).BaseTypeWrapper;
@ -1093,13 +1167,6 @@ namespace NativeCode.java
((TypeWrapper)wrapper).Finish();
Type type = ((TypeWrapper)wrapper).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;
}
@ -1110,11 +1177,13 @@ namespace NativeCode.java
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)
@ -1124,12 +1193,7 @@ namespace NativeCode.java
object clazz = map[wrapper];
if(clazz == null)
{
// Maybe the Class object was already constructed from the type
clazz = map[wrapper.Type];
if(clazz == null)
{
clazz = CreateInstance(null, wrapper);
}
clazz = CreateClassInstance(wrapper);
}
return clazz;
}
@ -1142,71 +1206,61 @@ namespace NativeCode.java
{
return null;
}
lock(map.SyncRoot)
{
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;
}
return getClassFromWrapper(ClassLoaderWrapper.GetWrapperFromType(type));
}
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)
{
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);
}
TypeWrapper wrapperType = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
if(wrapperType != null)
{
string name = ((TypeWrapper)wrapperType).Name;
@ -1256,7 +1310,8 @@ namespace NativeCode.java
}
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)
@ -1307,12 +1362,13 @@ namespace NativeCode.java
}
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
{
sb.Append('L').Append(GetName(type, null)).Append(';');
sb.Append('L').Append(getName(type)).Append(';');
}
return sb.ToString();
}
@ -1333,32 +1389,38 @@ namespace NativeCode.java
{
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)]
public static void initializeType(Type type)
{
RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
public static object getClassLoader0(Type type, object wrapper)
{
if(wrapper != null)
{
return ((TypeWrapper)wrapper).GetClassLoader().GetJavaClassLoader();
}
return ClassLoaderWrapper.GetClassLoader(type).GetJavaClassLoader();
}
public static object[] GetDeclaredMethods(Type type, object cwrapper, bool getMethods, bool publicOnly)
public static void initialize(object cwrapper)
{
TypeWrapper wrapper = (TypeWrapper)cwrapper;
wrapper.Finish();
RuntimeHelpers.RunClassConstructor(wrapper.Type.TypeHandle);
}
public static object getClassLoader0(object wrapper)
{
return ((TypeWrapper)wrapper).GetClassLoader().GetJavaClassLoader();
}
public static object getClassLoaderFromType(Type type)
{
return ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader().GetJavaClassLoader();
}
public static object[] GetDeclaredMethods(object cwrapper, bool getMethods, bool publicOnly)
{
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
wrapper.Finish();
// 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));
}
public static object[] GetDeclaredFields(Type type, object cwrapper, bool publicOnly)
public static object[] GetDeclaredFields(object cwrapper, bool publicOnly)
{
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
wrapper.Finish();
// 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;
}
public static object[] GetDeclaredClasses(Type type, object cwrapper, bool publicOnly)
public static object[] GetDeclaredClasses(object cwrapper, bool publicOnly)
{
TypeWrapper wrapper = (TypeWrapper)cwrapper;
if(wrapper == null)
{
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
}
// NOTE to get at the InnerClasses we need to finish the type
wrapper.Finish();
TypeWrapper[] wrappers = wrapper.InnerClasses;
@ -1476,13 +1530,9 @@ namespace NativeCode.java
return innerclasses;
}
public static object GetDeclaringClass(Type type, object cwrapper)
public static object GetDeclaringClass(object cwrapper)
{
TypeWrapper wrapper = (TypeWrapper)cwrapper;
if(wrapper == null)
{
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
}
// before we can call DeclaringTypeWrapper, we need to finish the type
wrapper.Finish();
TypeWrapper declaring = wrapper.DeclaringTypeWrapper;
@ -1497,14 +1547,11 @@ namespace NativeCode.java
return getClassFromWrapper(declaring);
}
public static object[] GetInterfaces(Type type, object cwrapper)
public static object[] GetInterfaces(object 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
// TODO this should not be needed (make sure it isn't and remove)
wrapper.Finish();
TypeWrapper[] interfaceWrappers = wrapper.Interfaces;
object[] interfaces = new object[interfaceWrappers.Length];
@ -1515,13 +1562,9 @@ namespace NativeCode.java
return interfaces;
}
public static int GetModifiers(Type type, Object cwrapper)
public static int GetModifiers(Object cwrapper)
{
TypeWrapper wrapper = (TypeWrapper)cwrapper;
if(wrapper == null)
{
wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
}
// NOTE ReflectiveModifiers is only available for finished types
wrapper.Finish();
// 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))
{
TypeWrapper[] args = cpi.GetArgTypes(classLoader);
CastInterfaceArgs(args, i, true, false);
CastInterfaceArgs(args, i, false, false);
}
else
{

Просмотреть файл

@ -27,23 +27,22 @@
<class name="java.lang.Object" type="System.Object" modifiers="public">
<constructor sig="()V" modifiers="public" />
<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 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 name="wait" sig="()V" modifiers="public final">
<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 -->
<pop />
</invokespecial>
<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 -->
<pop />
</invokevirtual>
<!--redirect class="System.Threading.Monitor" name="Wait" sig="(Ljava.lang.Object;)V" type="static" /-->
</method>
<method name="wait" sig="(J)V" modifiers="public final">
<redirect class="java.lang.ObjectHelper" name="wait" sig="(Ljava.lang.Object;J)V" type="static" />
@ -68,7 +67,7 @@
<invokespecial>
<!-- TODO if we already know statically that the type implements java.lang.Cloneable this check can be omitted -->
<dup />
<isinst type="java.lang.Cloneable" />
<isinst class="java.lang.Cloneable" />
<brtrue name="ok" />
<newobj class="java.lang.CloneNotSupportedException" name="&lt;init&gt;" sig="()V" />
<throw />
@ -104,9 +103,9 @@
<override name="GetHashCode" />
<invokevirtual>
<dup />
<isinst type="System.String" />
<isinst type="System.String, mscorlib" />
<brfalse name="skip" />
<castclass type="System.String" />
<castclass type="System.String, mscorlib" />
<call class="java.lang.StringHelper" name="hashCode" sig="(Ljava.lang.String;)I" />
<br name="end" />
<label name="skip" />
@ -121,7 +120,7 @@
<override name="Finalize" />
</method>
</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.CharSequence" />
<implements class="java.io.Serializable" />
@ -129,7 +128,7 @@
<!-- TODO -->
<newobj>
<ldstr value="" />
<call type="System.String" name="Copy" />
<call type="System.String, mscorlib" name="Copy" />
</newobj>
</constructor>
<constructor sig="([C)V" modifiers="public" />
@ -139,7 +138,7 @@
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([CIIZ)Ljava.lang.String;" />
</constructor>
<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 sig="(Ljava.lang.StringBuffer;)V" modifiers="public">
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
@ -299,12 +298,12 @@
</method>
<method name="copyValueOf" sig="([C)Ljava.lang.String;" modifiers="public static">
<invokestatic>
<newobj type="System.String" name=".ctor" sig="([C)V" />
<newobj type="System.String, mscorlib" name=".ctor" sig="([C)V" />
</invokestatic>
</method>
<method name="copyValueOf" sig="([CII)Ljava.lang.String;" modifiers="public static">
<invokestatic>
<newobj type="System.String" name=".ctor" sig="([CII)V" />
<newobj type="System.String, mscorlib" name=".ctor" sig="([CII)V" />
</invokestatic>
</method>
<field name="CASE_INSENSITIVE_ORDER" sig="Ljava.util.Comparator;" modifiers="public static final">
@ -335,20 +334,20 @@
<implements class="java.io.Serializable" />
<constructor sig="()V" modifiers="public">
<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" />
</invokespecial>
</constructor>
<constructor sig="(Ljava.lang.String;)V" modifiers="public">
<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" />
</invokespecial>
</constructor>
<constructor sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" modifiers="public">
<invokespecial>
<stloc name="x" type="System.Exception" />
<call type="ExceptionHelper" name="FilterMessage" />
<call type="ExceptionHelper, ik.vm.net" name="FilterMessage" />
<ldloc name="x" />
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
</invokespecial>
@ -357,47 +356,47 @@
<invokespecial>
<stloc name="x" type="System.Exception" />
<ldloc name="x" />
<call type="ExceptionHelper" name="GetMessageFromCause" />
<call type="ExceptionHelper, ik.vm.net" name="GetMessageFromCause" />
<ldloc name="x" />
<call type="System.Exception" name=".ctor" sig="(Ljava.lang.String;Ljava.lang.Throwable;)V" />
</invokespecial>
</constructor>
<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 type="virtual" name="printStackTrace" sig="(Ljava.io.PrintStream;)V" modifiers="public">
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
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 type="virtual" name="printStackTrace" sig="(Ljava.io.PrintWriter;)V" modifiers="public">
<!-- NOTE both printStackTrace(Ljava.io.PrintStream;)V & printStackTrace(Ljava.io.PrintWriter;)V redirect
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 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 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 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 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 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 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 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 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>
</class>
<class name="java.lang.Comparable" type="System.IComparable" modifiers="public interface">
@ -449,5 +448,15 @@
<ret />
</method>
</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>
</root>

Просмотреть файл

@ -20,7 +20,7 @@ obj11.Name = "notifyAll";
obj11.Sig = "()V";
obj11.Modifiers = (MapXml.MapModifiers)17;
MapXml.Redirect obj15 = new MapXml.Redirect();
obj15.Class = "System.Threading.Monitor";
obj15.Class = "System.Threading.Monitor, mscorlib";
obj15.Name = "PulseAll";
obj15.Sig = "(Ljava.lang.Object;)V";
obj15.Type = "static";
@ -31,7 +31,7 @@ obj20.Name = "notify";
obj20.Sig = "()V";
obj20.Modifiers = (MapXml.MapModifiers)17;
MapXml.Redirect obj24 = new MapXml.Redirect();
obj24.Class = "System.Threading.Monitor";
obj24.Class = "System.Threading.Monitor, mscorlib";
obj24.Name = "Pulse";
obj24.Sig = "(Ljava.lang.Object;)V";
obj24.Type = "static";
@ -44,7 +44,7 @@ obj29.Modifiers = (MapXml.MapModifiers)17;
MapXml.InstructionList obj33 = new MapXml.InstructionList();
MapXml.Instruction[] obj34 = new MapXml.Instruction[2];
MapXml.Call obj35 = new MapXml.Call();
obj35.type = "System.Threading.Monitor";
obj35.type = "System.Threading.Monitor, mscorlib";
obj35.Name = "Wait";
obj35.Sig = "(Ljava.lang.Object;)Z";
obj34[0] = obj35;
@ -55,7 +55,7 @@ obj29.invokevirtual = obj33;
MapXml.InstructionList obj40 = new MapXml.InstructionList();
MapXml.Instruction[] obj41 = new MapXml.Instruction[2];
MapXml.Call obj42 = new MapXml.Call();
obj42.type = "System.Threading.Monitor";
obj42.type = "System.Threading.Monitor, mscorlib";
obj42.Name = "Wait";
obj42.Sig = "(Ljava.lang.Object;)Z";
obj41[0] = obj42;
@ -138,7 +138,7 @@ MapXml.Instruction[] obj99 = new MapXml.Instruction[7];
MapXml.Dup obj100 = new MapXml.Dup();
obj99[0] = obj100;
MapXml.IsInst obj101 = new MapXml.IsInst();
obj101.type = "java.lang.Cloneable";
obj101.Class = "java.lang.Cloneable";
obj99[1] = obj101;
MapXml.BrTrue obj103 = new MapXml.BrTrue();
obj103.Name = "ok";
@ -216,13 +216,13 @@ MapXml.Instruction[] obj152 = new MapXml.Instruction[9];
MapXml.Dup obj153 = new MapXml.Dup();
obj152[0] = obj153;
MapXml.IsInst obj154 = new MapXml.IsInst();
obj154.type = "System.String";
obj154.type = "System.String, mscorlib";
obj152[1] = obj154;
MapXml.BrFalse obj156 = new MapXml.BrFalse();
obj156.Name = "skip";
obj152[2] = obj156;
MapXml.Castclass obj158 = new MapXml.Castclass();
obj158.type = "System.String";
obj158.type = "System.String, mscorlib";
obj152[3] = obj158;
MapXml.Call obj160 = new MapXml.Call();
obj160.Class = "java.lang.StringHelper";
@ -268,7 +268,7 @@ obj2.Methods = obj10;
obj1[0] = obj2;
MapXml.Class obj187 = new MapXml.Class();
obj187.Name = "java.lang.String";
obj187.Type = "System.String";
obj187.Type = "System.String, mscorlib";
obj187.Modifiers = (MapXml.MapModifiers)17;
MapXml.Constructor[] obj191 = new MapXml.Constructor[12];
MapXml.Constructor obj192 = new MapXml.Constructor();
@ -280,7 +280,7 @@ MapXml.Ldstr obj197 = new MapXml.Ldstr();
obj197.Value = "";
obj196[0] = obj197;
MapXml.Call obj199 = new MapXml.Call();
obj199.type = "System.String";
obj199.type = "System.String, mscorlib";
obj199.Name = "Copy";
obj196[1] = obj199;
obj195.invoke = obj196;
@ -308,7 +308,7 @@ MapXml.Constructor obj216 = new MapXml.Constructor();
obj216.Sig = "(Ljava.lang.String;)V";
obj216.Modifiers = (MapXml.MapModifiers)1;
MapXml.Redirect obj219 = new MapXml.Redirect();
obj219.Class = "System.String";
obj219.Class = "System.String, mscorlib";
obj219.Name = "Copy";
obj219.Sig = "(Ljava.lang.String;)Ljava.lang.String;";
obj219.Type = "static";
@ -808,7 +808,7 @@ obj606.Modifiers = (MapXml.MapModifiers)9;
MapXml.InstructionList obj610 = new MapXml.InstructionList();
MapXml.Instruction[] obj611 = new MapXml.Instruction[1];
MapXml.NewObj obj612 = new MapXml.NewObj();
obj612.type = "System.String";
obj612.type = "System.String, mscorlib";
obj612.Name = ".ctor";
obj612.Sig = "([C)V";
obj611[0] = obj612;
@ -822,7 +822,7 @@ obj616.Modifiers = (MapXml.MapModifiers)9;
MapXml.InstructionList obj620 = new MapXml.InstructionList();
MapXml.Instruction[] obj621 = new MapXml.Instruction[1];
MapXml.NewObj obj622 = new MapXml.NewObj();
obj622.type = "System.String";
obj622.type = "System.String, mscorlib";
obj622.Name = ".ctor";
obj622.Sig = "([CII)V";
obj621[0] = obj622;
@ -908,7 +908,7 @@ obj682.Modifiers = (MapXml.MapModifiers)1;
MapXml.InstructionList obj685 = new MapXml.InstructionList();
MapXml.Instruction[] obj686 = new MapXml.Instruction[2];
MapXml.Call obj687 = new MapXml.Call();
obj687.type = "ExceptionHelper";
obj687.type = "ExceptionHelper, ik.vm.net";
obj687.Name = "get_NullString";
obj686[0] = obj687;
MapXml.Call obj690 = new MapXml.Call();
@ -925,7 +925,7 @@ obj694.Modifiers = (MapXml.MapModifiers)1;
MapXml.InstructionList obj697 = new MapXml.InstructionList();
MapXml.Instruction[] obj698 = new MapXml.Instruction[2];
MapXml.Call obj699 = new MapXml.Call();
obj699.type = "ExceptionHelper";
obj699.type = "ExceptionHelper, ik.vm.net";
obj699.Name = "FilterMessage";
obj698[0] = obj699;
MapXml.Call obj702 = new MapXml.Call();
@ -946,7 +946,7 @@ obj711.Name = "x";
obj711.type = "System.Exception";
obj710[0] = obj711;
MapXml.Call obj714 = new MapXml.Call();
obj714.type = "ExceptionHelper";
obj714.type = "ExceptionHelper, ik.vm.net";
obj714.Name = "FilterMessage";
obj710[1] = obj714;
MapXml.LdLoc obj717 = new MapXml.LdLoc();
@ -973,7 +973,7 @@ MapXml.LdLoc obj731 = new MapXml.LdLoc();
obj731.Name = "x";
obj727[1] = obj731;
MapXml.Call obj733 = new MapXml.Call();
obj733.type = "ExceptionHelper";
obj733.type = "ExceptionHelper, ik.vm.net";
obj733.Name = "GetMessageFromCause";
obj727[2] = obj733;
MapXml.LdLoc obj736 = new MapXml.LdLoc();
@ -995,7 +995,7 @@ obj743.Sig = "()V";
obj743.Modifiers = (MapXml.MapModifiers)1;
obj743.Type = "virtual";
MapXml.Redirect obj748 = new MapXml.Redirect();
obj748.Class = "ExceptionHelper";
obj748.Class = "ExceptionHelper, ik.vm.net";
obj748.Sig = "(Ljava.lang.Throwable;)V";
obj748.Type = "static";
obj743.redirect = obj748;
@ -1006,7 +1006,7 @@ obj752.Sig = "(Ljava.io.PrintStream;)V";
obj752.Modifiers = (MapXml.MapModifiers)1;
obj752.Type = "virtual";
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.Type = "static";
obj752.redirect = obj757;
@ -1017,7 +1017,7 @@ obj761.Sig = "(Ljava.io.PrintWriter;)V";
obj761.Modifiers = (MapXml.MapModifiers)1;
obj761.Type = "virtual";
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.Type = "static";
obj761.redirect = obj766;
@ -1028,7 +1028,7 @@ obj770.Sig = "()Ljava.lang.String;";
obj770.Modifiers = (MapXml.MapModifiers)1;
obj770.Type = "virtual";
MapXml.Redirect obj775 = new MapXml.Redirect();
obj775.Class = "ExceptionHelper";
obj775.Class = "ExceptionHelper, ik.vm.net";
obj775.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
obj775.Type = "static";
obj770.redirect = obj775;
@ -1039,7 +1039,7 @@ obj779.Sig = "()Ljava.lang.String;";
obj779.Modifiers = (MapXml.MapModifiers)1;
obj779.Type = "virtual";
MapXml.Redirect obj784 = new MapXml.Redirect();
obj784.Class = "ExceptionHelper";
obj784.Class = "ExceptionHelper, ik.vm.net";
obj784.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
obj784.Type = "static";
obj779.redirect = obj784;
@ -1050,7 +1050,7 @@ obj788.Sig = "()Ljava.lang.Throwable;";
obj788.Modifiers = (MapXml.MapModifiers)1;
obj788.Type = "virtual";
MapXml.Redirect obj793 = new MapXml.Redirect();
obj793.Class = "ExceptionHelper";
obj793.Class = "ExceptionHelper, ik.vm.net";
obj793.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
obj793.Type = "static";
obj788.redirect = obj793;
@ -1061,7 +1061,7 @@ obj797.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
obj797.Modifiers = (MapXml.MapModifiers)1;
obj797.Type = "virtual";
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.Type = "static";
obj797.redirect = obj802;
@ -1072,7 +1072,7 @@ obj806.Sig = "()Ljava.lang.Throwable;";
obj806.Modifiers = (MapXml.MapModifiers)1;
obj806.Type = "virtual";
MapXml.Redirect obj811 = new MapXml.Redirect();
obj811.Class = "ExceptionHelper";
obj811.Class = "ExceptionHelper, ik.vm.net";
obj811.Sig = "(Ljava.lang.Throwable;)Ljava.lang.Throwable;";
obj811.Type = "static";
obj806.redirect = obj811;
@ -1083,7 +1083,7 @@ obj815.Sig = "()[Ljava.lang.StackTraceElement;";
obj815.Modifiers = (MapXml.MapModifiers)1;
obj815.Type = "virtual";
MapXml.Redirect obj820 = new MapXml.Redirect();
obj820.Class = "ExceptionHelper";
obj820.Class = "ExceptionHelper, ik.vm.net";
obj820.Sig = "(Ljava.lang.Throwable;)[Ljava.lang.StackTraceElement;";
obj820.Type = "static";
obj815.redirect = obj820;
@ -1094,7 +1094,7 @@ obj824.Sig = "([Ljava.lang.StackTraceElement;)V";
obj824.Modifiers = (MapXml.MapModifiers)1;
obj824.Type = "virtual";
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.Type = "static";
obj824.redirect = obj829;
@ -1105,7 +1105,7 @@ obj833.Sig = "()Ljava.lang.String;";
obj833.Modifiers = (MapXml.MapModifiers)1;
obj833.Type = "virtual";
MapXml.Redirect obj838 = new MapXml.Redirect();
obj838.Class = "ExceptionHelper";
obj838.Class = "ExceptionHelper, ik.vm.net";
obj838.Sig = "(Ljava.lang.Throwable;)Ljava.lang.String;";
obj838.Type = "static";
obj833.redirect = obj838;
@ -1189,7 +1189,7 @@ obj860[7] = obj893;
obj856.Methods = obj860;
obj1[4] = obj856;
obj0.remappings = obj1;
MapXml.Class[] obj899 = new MapXml.Class[3];
MapXml.Class[] obj899 = new MapXml.Class[4];
MapXml.Class obj900 = new MapXml.Class();
obj900.Name = "java.lang.Runtime";
obj900.Modifiers = (MapXml.MapModifiers)0;
@ -1260,6 +1260,34 @@ obj936.invoke = obj940;
obj935[0] = obj936;
obj932.Methods = obj935;
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;
return obj0;
}

Просмотреть файл

@ -58,7 +58,7 @@ namespace MapXml
{
Debug.Assert(Class == null && type != null);
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
{
@ -77,11 +77,11 @@ namespace MapXml
if(Sig != null)
{
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
{
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
{
typeType = ClassLoaderWrapper.GetType(type);
typeType = Type.GetType(type, true);
}
}
ilgen.Emit(opcode, typeType != null ? typeType : typeWrapper.Type);
@ -296,7 +296,7 @@ namespace MapXml
Debug.Assert(Class == null ^ type == null);
if(type != null)
{
typeType = ClassLoaderWrapper.GetType(type);
typeType = Type.GetType(type, true);
}
else
{

Просмотреть файл

@ -29,6 +29,7 @@ using System.Collections;
using System.Xml;
using System.Diagnostics;
using OpenSystem.Java;
using System.Text.RegularExpressions;
public class JVM
{
@ -145,7 +146,6 @@ public class JVM
private string assembly;
private string path;
private AssemblyBuilder assemblyBuilder;
private ModuleBuilder moduleBuilder;
internal CompilerClassLoader(string path, string assembly, Hashtable classes)
: base(null)
@ -157,26 +157,23 @@ public class JVM
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();
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 = 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);
}
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, true });
moduleBuilder.SetCustomAttribute(debugAttr);
}
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)
{
ClassFile f = (ClassFile)classes[name];
@ -201,11 +198,7 @@ public class JVM
internal void AddResources(Hashtable resources)
{
if(moduleBuilder == null)
{
// this happens if the module contains no clases
CreateModuleBuilder();
}
ModuleBuilder moduleBuilder = this.ModuleBuilder;
foreach(DictionaryEntry d in resources)
{
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;
noJniStubs = nojni;
@ -232,12 +225,29 @@ public class JVM
{
ClassFile f = new ClassFile(classes[i], 0, classes[i].Length, null);
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))
{
Console.Error.WriteLine("Duplicate class name: {0}", name);
return;
}
h[name] = f;
if(!excluded)
{
h[name] = f;
}
}
// 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)
{
// don't handle inner classes for NetExp types
if(classFile.NetExpTypeAttribute == null)
if(classFile.NetExpAssemblyAttribute == null)
{
ClassFile.InnerClass[] innerClasses = classFile.InnerClasses;
if(innerClasses != null)

Двоичные данные
classpath/System.Xml.jar

Двоичный файл не отображается.

Двоичные данные
classpath/System.jar

Двоичный файл не отображается.

Просмотреть файл

@ -24,8 +24,8 @@
package gnu.java.net.protocol.ikvmres;
import system.io.*;
import system.reflection.*;
import cli.System.IO.*;
import cli.System.Reflection.*;
import java.net.*;
import java.io.*;
import java.io.IOException;
@ -56,8 +56,8 @@ class IkvmresURLConnection extends URLConnection
{
throw new IOException("resource " + resource + " not found in assembly " + assembly);
}
byte[] b = new byte[system.runtime.interopservices.Marshal.SizeOf(fi.get_FieldType())];
system.runtime.compilerservices.RuntimeHelpers.InitializeArray((system.Array)(Object)b, fi.get_FieldHandle());
byte[] b = new byte[cli.System.Runtime.InteropServices.Marshal.SizeOf(fi.get_FieldType())];
cli.System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray((cli.System.Array)(Object)b, fi.get_FieldHandle());
inputStream = new ByteArrayInputStream(b);
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.OutputStream;
import java.io.File;
import system.text.StringBuilder;
import system.diagnostics.ProcessStartInfo;
import cli.System.Text.StringBuilder;
import cli.System.Diagnostics.ProcessStartInfo;
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;
}
@ -72,10 +72,10 @@ public class DotNetProcess extends Process
{
try
{
if(false) throw new system.InvalidOperationException();
if(false) throw new cli.System.InvalidOperationException();
proc.Kill();
}
catch(system.InvalidOperationException x)
catch(cli.System.InvalidOperationException x)
{
}
}
@ -119,6 +119,6 @@ public class DotNetProcess extends Process
}
}
// 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;
import system.Console;
import system.io.*;
import cli.System.Console;
import cli.System.IO.*;
import ikvm.lang.ByteArrayHack;
/**
* This class represents an opaque file handle as a Java class. It should
@ -91,12 +92,12 @@ public final class FileDescriptor
}
try
{
if(false) throw new system.io.IOException();
if(false) throw new cli.System.IO.IOException();
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
{
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;
@ -171,23 +172,23 @@ public final class FileDescriptor
default:
throw new IllegalArgumentException("Invalid mode value: " + mode);
}
if(false) throw new system.io.IOException();
if(false) throw new system.security.SecurityException();
if(false) throw new system.UnauthorizedAccessException();
stream = system.io.File.Open(demanglePath(path), fileMode, fileAccess, FileShare.ReadWrite);
if(false) throw new cli.System.IO.IOException();
if(false) throw new cli.System.Security.SecurityException();
if(false) throw new cli.System.UnauthorizedAccessException();
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
throw new FileNotFoundException(x3.get_Message());
throw new FileNotFoundException(x3.getMessage());
}
// TODO map al the other exceptions as well...
}
@ -199,12 +200,12 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
if(false) throw new cli.System.IO.IOException();
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...
}
@ -216,12 +217,12 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
if(false) throw new cli.System.IO.IOException();
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...
}
@ -237,12 +238,12 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
if(false) throw new cli.System.IO.IOException();
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...
}
@ -257,17 +258,17 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
long newpos = stream.Seek(offset, whence);
if(false) throw new cli.System.IO.IOException();
long newpos = stream.Seek(offset, SeekOrigin.wrap(whence));
if(stopAtEof && newpos > stream.get_Length())
{
newpos = stream.Seek(0, SeekOrigin.End);
newpos = stream.Seek(0, SeekOrigin.wrap(SeekOrigin.End));
}
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...
}
@ -279,12 +280,12 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
if(false) throw new cli.System.IO.IOException();
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...
}
@ -305,37 +306,25 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
int count = stream.Read(buf, offset, len);
if(false) throw new cli.System.IO.IOException();
int count = stream.Read(ByteArrayHack.cast(buf), offset, len);
if(count == 0)
{
count = -1;
}
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...
}
synchronized void write(int b) throws IOException
{
if(stream == null)
{
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...
// HACK we can't call WriteByte because it takes a cli.System.Byte
write(new byte[] { (byte)b }, 0, 1);
}
synchronized void write(byte[] buf, int offset, int len) throws IOException
@ -354,12 +343,12 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
stream.Write(buf, offset, len);
if(false) throw new cli.System.IO.IOException();
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...
}
@ -371,17 +360,17 @@ public final class FileDescriptor
try
{
if(false) throw new system.io.IOException();
if(false) throw new system.NotSupportedException();
if(false) throw new cli.System.IO.IOException();
if(false) throw new cli.System.NotSupportedException();
if(stream.get_CanSeek())
return (int)Math.min(Integer.MAX_VALUE, Math.max(0, stream.get_Length() - stream.get_Position()));
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
// support Length and Position

Просмотреть файл

@ -44,12 +44,12 @@ public class ObjectHelper
}
if(timeout == 0 && nanos == 0)
{
system.threading.Monitor.Wait(o);
cli.System.Threading.Monitor.Wait(o);
}
else
{
// 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)
{
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)
{
return false;
}
system.String s = (system.String)(Object)si;
s = (system.String)(Object)s.Substring(Math.min(s.get_Length(), toffset));
return s.StartsWith(prefix);
s = cli.System.String.Substring(s, Math.min(s.length(), toffset));
return cli.System.String.StartsWith(s, prefix);
}
public static char charAt(String s, int index)
{
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
// 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)
{
((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)
@ -344,31 +343,28 @@ public final class StringHelper
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
system.String s = (system.String)(Object)si;
return s.IndexOf(ch, Math.max(0, Math.min(s.get_Length(), fromIndex)));
return cli.System.String.IndexOf(s, ch, Math.max(0, Math.min(s.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
system.String s = (system.String)(Object)si;
return s.IndexOf(o, Math.max(0, Math.min(s.get_Length(), fromIndex)));
return cli.System.String.IndexOf(s, o, Math.max(0, Math.min(s.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
int len = s.get_Length();
int len = s.length();
if(fromIndex < 0)
{
return -1;
}
// 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)
@ -376,11 +372,10 @@ public final class StringHelper
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
int len = s.get_Length();
int len = s.length();
if(fromIndex < 0)
{
return -1;
@ -390,7 +385,7 @@ public final class StringHelper
return Math.min(len, fromIndex);
}
// 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)
@ -401,7 +396,7 @@ public final class StringHelper
{
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)
@ -501,7 +496,7 @@ public final class StringHelper
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)
@ -531,11 +526,11 @@ public final class StringHelper
public static int hashCode(String s)
{
system.String ns = (system.String)(Object)s;
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;
}

Просмотреть файл

@ -40,8 +40,8 @@ package java.lang;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import system.*;
import system.reflection.*;
import cli.System.*;
import cli.System.Reflection.*;
/*
* This class is a reference version, mainly for compiling a class library
@ -57,366 +57,345 @@ import system.reflection.*;
*/
final class VMClass
{
/** The .NET type */
private Type type;
private Object wrapper;
private Object wrapper; // the corresponding TypeWrapper
private Class clazz;
public static native Class getClassFromType(Type t);
private static native Type getTypeFromWrapper(Object clazz, Object wrapper);
private static native Object getWrapperFromType(Type t);
private static Type getTypeFromClass(Class c)
// NOTE this is used in classpath.cs to go from a Class object to a TypeWrapper
private static Object getWrapperFromClass(Class c)
{
return c.vmClass.getType();
return c.vmClass.wrapper;
}
private Type getType()
{
if(type == null)
{
type = getTypeFromWrapper(clazz, wrapper);
}
return type;
}
private Object getWrapper()
{
if(wrapper == null)
{
wrapper = getWrapperFromType(type);
}
return wrapper;
}
private VMClass(Object wrapper)
{
this.wrapper = wrapper;
}
private VMClass(Type type, Object wrapper)
{
this.type = type;
this.wrapper = wrapper;
}
private static Class createClass(Type type, Object wrapper)
{
VMClass vmClass = new VMClass(type, wrapper);
Class c = new Class(vmClass);
vmClass.clazz = c;
return c;
}
// HACK public because we want to create a delegate to call it
public static Object createClass(Object wrapper)
{
VMClass vmClass = new VMClass(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
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
* as almost like <code>o instanceof (this class)</code>.
*
* @param o the Object to check
* @return whether o is an instance of this class
* @since 1.1
*/
boolean isInstance(Object o)
{
// TODO this needs to be implemented by the "native" code, because
// remapped types can appear to implement interfaces that they don't
// actually implement
return getType().IsInstanceOfType(o);
}
/**
* Discover whether an Object is an instance of this Class. Think of it
* as almost like <code>o instanceof (this class)</code>.
*
* @param o the Object to check
* @return whether o is an instance of this class
* @since 1.1
*/
boolean isInstance(Object o)
{
return o != null && clazz.isAssignableFrom(o.getClass());
}
/**
* Discover whether an instance of the Class parameter would be an
* instance of this Class as well. Think of doing
* <code>isInstance(c.newInstance())</code> or even
* <code>c.newInstance() instanceof (this class)</code>. While this
* checks widening conversions for objects, it must be exact for primitive
* types.
*
* @param c the class to check
* @return whether an instance of c would be an instance of this class
* as well
* @throws NullPointerException if c is null
* @since 1.1
*/
boolean isAssignableFrom(Class c)
{
// this needs to be implemented by the "native" code, because
// remapped types can appear to implement interfaces that they don't
// actually implement
return IsAssignableFrom(getWrapper(), c.vmClass.getWrapper());
}
private static native boolean IsAssignableFrom(Object w1, Object w2);
/**
* Discover whether an instance of the Class parameter would be an
* instance of this Class as well. Think of doing
* <code>isInstance(c.newInstance())</code> or even
* <code>c.newInstance() instanceof (this class)</code>. While this
* checks widening conversions for objects, it must be exact for primitive
* types.
*
* @param c the class to check
* @return whether an instance of c would be an instance of this class
* as well
* @throws NullPointerException if c is null
* @since 1.1
*/
boolean isAssignableFrom(Class c)
{
// this is implemented by the "native" code, because
// remapped types can appear to implement interfaces that they don't
// actually implement
return IsAssignableFrom(wrapper, c.vmClass.wrapper);
}
private static native boolean IsAssignableFrom(Object w1, Object w2);
/**
* Check whether this class is an interface or not. Array types are not
* interfaces.
*
* @return whether this class is an interface or not
*/
boolean isInterface()
{
return getType().get_IsInterface();
}
/**
* Check whether this class is an interface or not. Array types are not
* interfaces.
*
* @return whether this class is an interface or not
*/
boolean isInterface()
{
return IsInterface(wrapper);
}
private static native boolean IsInterface(Object wrapper);
/**
* Return whether this class is a primitive type. A primitive type class
* is a class representing a kind of "placeholder" for the various
* primitive types, or void. You can access the various primitive type
* classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
* or through boolean.class, int.class, etc.
*
* @return whether this class is a primitive type
* @see Boolean#TYPE
* @see Byte#TYPE
* @see Character#TYPE
* @see Short#TYPE
* @see Integer#TYPE
* @see Long#TYPE
* @see Float#TYPE
* @see Double#TYPE
* @see Void#TYPE
* @since 1.1
*/
boolean isPrimitive()
{
return clazz == boolean.class ||
clazz == byte.class ||
clazz == char.class ||
clazz == short.class ||
clazz == int.class ||
clazz == long.class ||
clazz == float.class ||
clazz == double.class ||
clazz == void.class;
}
/**
* Return whether this class is a primitive type. A primitive type class
* is a class representing a kind of "placeholder" for the various
* primitive types, or void. You can access the various primitive type
* classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
* or through boolean.class, int.class, etc.
*
* @return whether this class is a primitive type
* @see Boolean#TYPE
* @see Byte#TYPE
* @see Character#TYPE
* @see Short#TYPE
* @see Integer#TYPE
* @see Long#TYPE
* @see Float#TYPE
* @see Double#TYPE
* @see Void#TYPE
* @since 1.1
*/
boolean isPrimitive()
{
return clazz == boolean.class ||
clazz == byte.class ||
clazz == char.class ||
clazz == short.class ||
clazz == int.class ||
clazz == long.class ||
clazz == float.class ||
clazz == double.class ||
clazz == void.class;
}
/**
* Get the name of this class, separated by dots for package separators.
* Primitive types and arrays are encoded as:
* <pre>
* boolean Z
* byte B
* char C
* short S
* int I
* long J
* float F
* double D
* void V
* array type [<em>element type</em>
* class or interface, alone: &lt;dotted name&gt;
* class or interface, as element type: L&lt;dotted name&gt;;
*
* @return the name of this class
*/
String getName()
{
// getName() is used by the classloader, so it shouldn't trigger a resolve of the class
return GetName(type, wrapper);
}
private static native String GetName(Type type, Object wrapper);
/**
* Get the name of this class, separated by dots for package separators.
* Primitive types and arrays are encoded as:
* <pre>
* boolean Z
* byte B
* char C
* short S
* int I
* long J
* float F
* double D
* void V
* array type [<em>element type</em>
* class or interface, alone: &lt;dotted name&gt;
* class or interface, as element type: L&lt;dotted name&gt;;
*
* @return the name of this class
*/
String getName()
{
// getName() is used by the classloader, so it shouldn't trigger a resolve of the class
return GetName(wrapper);
}
private static native String GetName(Object wrapper);
/**
* 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
* array type, it will return Object.
*
* @return the direct superclass of this class
*/
Class getSuperclass()
{
return (Class)GetSuperClassFromWrapper(getWrapper());
}
private native static Object GetSuperClassFromWrapper(Object wrapper);
/**
* 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
* array type, it will return Object.
*
* @return the direct superclass of this class
*/
Class getSuperclass()
{
return (Class)GetSuperClassFromWrapper(wrapper);
}
private native static Object GetSuperClassFromWrapper(Object wrapper);
/**
* Get the interfaces this class <EM>directly</EM> implements, in the
* order that they were declared. This returns an empty array, not null,
* for Object, primitives, void, and classes or interfaces with no direct
* superinterface. Array types return Cloneable and Serializable.
*
* @return the interfaces this class directly implements
*/
Class[] getInterfaces()
{
Object[] interfaces = GetInterfaces(type, wrapper);
Class[] interfacesClass = new Class[interfaces.length];
System.arraycopy(interfaces, 0, interfacesClass, 0, interfaces.length);
return interfacesClass;
}
private static native Object[] GetInterfaces(Type type, Object wrapper);
/**
* Get the interfaces this class <EM>directly</EM> implements, in the
* order that they were declared. This returns an empty array, not null,
* for Object, primitives, void, and classes or interfaces with no direct
* superinterface. Array types return Cloneable and Serializable.
*
* @return the interfaces this class directly implements
*/
Class[] getInterfaces()
{
Object[] interfaces = GetInterfaces(wrapper);
Class[] interfacesClass = new Class[interfaces.length];
System.arraycopy(interfaces, 0, interfacesClass, 0, interfaces.length);
return interfacesClass;
}
private static native Object[] GetInterfaces(Object wrapper);
/**
* If this is an array, get the Class representing the type of array.
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
* calling getComponentType on that would give "java.lang.String". If
* this is not an array, returns null.
*
* @return the array type of this class, or null
* @see Array
* @since 1.1
*/
Class getComponentType()
{
// .NET array types can have unfinished element types, but we don't
// want to expose those, so we may need to finish the type
return (Class)getComponentClassFromWrapper(getWrapper());
}
private static native Object getComponentClassFromWrapper(Object wrapper);
/**
* If this is an array, get the Class representing the type of array.
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
* calling getComponentType on that would give "java.lang.String". If
* this is not an array, returns null.
*
* @return the array type of this class, or null
* @see Array
* @since 1.1
*/
Class getComponentType()
{
// .NET array types can have unfinished element types, but we don't
// want to expose those, so we may need to finish the type
return (Class)getComponentClassFromWrapper(wrapper);
}
private static native Object getComponentClassFromWrapper(Object wrapper);
/**
* 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
* final, static, abstract, or interface. An array class has the same
* public, protected, or private modifier as its component type, and is
* marked final but not an interface. Primitive types and void are marked
* public and final, but not an interface.
*
* @return the modifiers of this class
* @see Modifer
* @since 1.1
*/
int getModifiers()
{
return GetModifiers(type, wrapper);
}
private static native int GetModifiers(Type type, Object wrapper);
/**
* 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
* final, static, abstract, or interface. An array class has the same
* public, protected, or private modifier as its component type, and is
* marked final but not an interface. Primitive types and void are marked
* public and final, but not an interface.
*
* @return the modifiers of this class
* @see Modifer
* @since 1.1
*/
int getModifiers()
{
return GetModifiers(wrapper);
}
private static native int GetModifiers(Object wrapper);
/**
* If this is a nested or inner class, return the class that declared it.
* If not, return null.
*
* @return the declaring class of this class
* @since 1.1
*/
Class getDeclaringClass()
{
return (Class)GetDeclaringClass(type, wrapper);
}
private native static Object GetDeclaringClass(Type type, Object wrapper);
/**
* If this is a nested or inner class, return the class that declared it.
* If not, return null.
*
* @return the declaring class of this class
* @since 1.1
*/
Class getDeclaringClass()
{
return (Class)GetDeclaringClass(wrapper);
}
private native static Object GetDeclaringClass(Object wrapper);
/**
* Like <code>getDeclaredClasses()</code> but without the security checks.
*
* @param pulicOnly Only public classes should be returned
*/
Class[] getDeclaredClasses(boolean publicOnly)
{
Object[] classes = GetDeclaredClasses(type, wrapper, publicOnly);
Class[] classesClass = new Class[classes.length];
System.arraycopy(classes, 0, classesClass, 0, classes.length);
return classesClass;
}
private static native Object[] GetDeclaredClasses(Type type, Object wrapper, boolean publicOnly);
/**
* Like <code>getDeclaredClasses()</code> but without the security checks.
*
* @param pulicOnly Only public classes should be returned
*/
Class[] getDeclaredClasses(boolean publicOnly)
{
Object[] classes = GetDeclaredClasses(wrapper, publicOnly);
Class[] classesClass = new Class[classes.length];
System.arraycopy(classes, 0, classesClass, 0, classes.length);
return classesClass;
}
private static native Object[] GetDeclaredClasses(Object wrapper, boolean publicOnly);
/**
* Like <code>getDeclaredFields()</code> but without the security checks.
*
* @param pulicOnly Only public fields should be returned
*/
Field[] getDeclaredFields(boolean publicOnly)
/**
* Like <code>getDeclaredFields()</code> but without the security checks.
*
* @param pulicOnly Only public fields should be returned
*/
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);
Field[] fields = new Field[fieldCookies.length];
for(int i = 0; i < fields.length; i++)
{
fields[i] = new Field(clazz, fieldCookies[i]);
}
return fields;
fields[i] = new Field(clazz, fieldCookies[i]);
}
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.
*
* @param pulicOnly Only public methods should be returned
*/
Method[] getDeclaredMethods(boolean publicOnly)
/**
* Like <code>getDeclaredMethods()</code> but without the security checks.
*
* @param pulicOnly Only public methods should be returned
*/
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);
Method[] methods = new Method[methodCookies.length];
for(int i = 0; i < methodCookies.length; i++)
{
methods[i] = new Method(clazz, methodCookies[i]);
}
return methods;
methods[i] = new Method(clazz, methodCookies[i]);
}
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
* the security checks.
*
* @param pulicOnly Only public constructors should be returned
*/
Constructor[] getDeclaredConstructors(boolean publicOnly)
/**
* Like <code>getDeclaredConstructors()</code> but without
* the security checks.
*
* @param pulicOnly Only public constructors should be returned
*/
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);
Constructor[] constructors = new Constructor[methodCookies.length];
for(int i = 0; i < methodCookies.length; i++)
{
constructors[i] = new Constructor(clazz, methodCookies[i]);
}
return constructors;
constructors[i] = new Constructor(clazz, methodCookies[i]);
}
return constructors;
}
/**
* Return the class loader of this class.
*
* @return the class loader
*/
ClassLoader getClassLoader()
{
// getClassLoader() can be used by the classloader, so it shouldn't trigger a resolve of the class
return getClassLoader0(type, wrapper);
}
private static native ClassLoader getClassLoader0(Type type, Object wrapper);
/**
* Return the class loader of this class.
*
* @return the class loader
*/
ClassLoader getClassLoader()
{
// getClassLoader() can be used by the classloader, so it shouldn't trigger a resolve of the class
return getClassLoader0(wrapper);
}
private static native ClassLoader getClassLoader0(Object wrapper);
/**
* VM implementors are free to make this method a noop if
* the default implementation is acceptable.
*
* @param name the name of the class to find
* @return the Class object representing the class or null for noop
* @throws ClassNotFoundException if the class was not found by the
* classloader
* @throws LinkageError if linking the class fails
* @throws ExceptionInInitializerError if the class loads, but an exception
* occurs during initialization
*/
static Class forName(String name) throws ClassNotFoundException
/**
* VM implementors are free to make this method a noop if
* the default implementation is acceptable.
*
* @param name the name of the class to find
* @return the Class object representing the class or null for noop
* @throws ClassNotFoundException if the class was not found by the
* classloader
* @throws LinkageError if linking the class fails
* @throws ExceptionInInitializerError if the class loads, but an exception
* occurs during initialization
*/
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
// 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);
frame = new cli.System.Diagnostics.StackFrame(2);
}
ClassLoader cl = getClassLoaderFromType(frame.GetMethod().get_DeclaringType());
return Class.forName(name, true, cl);
}
private static native ClassLoader getClassLoaderFromType(Type type);
void initialize()
{
initializeType(getType());
initialize(wrapper);
}
private static native void initialize(Object wrapper);
static native Class loadArrayClass(String name, Object classLoader);
static native Class loadBootstrapClass(String name, boolean initialize);
private static native void initializeType(Type type);
static native Class loadArrayClass(String name, Object classLoader);
static native Class loadBootstrapClass(String name, boolean initialize);
static native void throwException(Throwable t);
/**
* Return whether this class is an array type.
*
* @return 1 if this class is an array type, 0 otherwise, -1 if unsupported
* operation
*/
int isArray()
{
return getType().get_IsArray() ? 1 : 0;
}
} // class VMClass
/**
* Return whether this class is an array type.
*
* @return 1 if this class is an array type, 0 otherwise, -1 if unsupported
* operation
*/
int isArray()
{
return IsArray(wrapper) ? 1 : 0;
}
private static native boolean IsArray(Object wrapper);
}

Просмотреть файл

@ -46,8 +46,8 @@ import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Constructor;
import gnu.java.lang.SystemClassLoader;
import system.*;
import system.reflection.*;
import cli.System.*;
import cli.System.Reflection.*;
/**
* java.lang.VMClassLoader is a package-private helper for VMs to implement
@ -217,12 +217,7 @@ final class VMClassLoader
* @param type the primitive type
* @return a "bogus" class representing the primitive type
*/
static final Class getPrimitiveClass(char type)
{
return VMClass.getClassFromType(getPrimitiveType(type));
}
private static native system.Type getPrimitiveType(char type);
static native Class getPrimitiveClass(char type);
/**
* The system default for assertion status. This is used for all system

Просмотреть файл

@ -28,7 +28,7 @@ final class VMDouble
{
static double longBitsToDouble(long v)
{
return system.BitConverter.Int64BitsToDouble(v);
return cli.System.BitConverter.Int64BitsToDouble(v);
}
static long doubleToLongBits(double v)
@ -37,11 +37,11 @@ final class VMDouble
{
return 0x7ff8000000000000L;
}
return system.BitConverter.DoubleToInt64Bits(v);
return cli.System.BitConverter.DoubleToInt64Bits(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)
{
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)
@ -37,11 +37,11 @@ final class VMFloat
{
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)
{
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;
}
private static system.LocalDataStoreSlot localDataStoreSlot = system.threading.Thread.AllocateDataSlot();
private system.threading.Thread nativeThread;
private static cli.System.LocalDataStoreSlot localDataStoreSlot = cli.System.Threading.Thread.AllocateDataSlot();
private cli.System.Threading.Thread nativeThread;
/*native*/ void start(long stacksize)
{
system.threading.ThreadStart starter = new system.threading.ThreadStart(
new system.threading.ThreadStart.Method()
cli.System.Threading.ThreadStart starter = new cli.System.Threading.ThreadStart(
new cli.System.Threading.ThreadStart.Method()
{
public void Invoke()
{
system.threading.Thread.SetData(localDataStoreSlot, thread);
cli.System.Threading.Thread.SetData(localDataStoreSlot, thread);
run();
}
});
nativeThread = new system.threading.Thread(starter);
nativeThread = new cli.System.Threading.Thread(starter);
nativeThread.set_Name(thread.name);
nativeThread.set_IsBackground(thread.daemon);
nativeSetPriority(thread.priority);
@ -149,7 +149,7 @@ final class VMThread
try
{
if(false) throw new InterruptedException();
system.threading.Thread.Sleep(0);
cli.System.Threading.Thread.Sleep(0);
return false;
}
catch(InterruptedException x)
@ -179,23 +179,23 @@ final class VMThread
{
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)
{
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)
{
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)
{
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)
{
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()
{
Thread javaThread = (Thread)system.threading.Thread.GetData(localDataStoreSlot);
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
if(javaThread == null)
{
// 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
// 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.nativeThread = nativeThread;
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;
break;
case system.threading.ThreadPriority.BelowNormal:
case cli.System.Threading.ThreadPriority.BelowNormal:
priority = 3;
break;
case system.threading.ThreadPriority.Normal:
case cli.System.Threading.ThreadPriority.Normal:
priority = Thread.NORM_PRIORITY;
break;
case system.threading.ThreadPriority.AboveNormal:
case cli.System.Threading.ThreadPriority.AboveNormal:
priority = 7;
break;
case system.threading.ThreadPriority.Highest:
case cli.System.Threading.ThreadPriority.Highest:
priority = Thread.MAX_PRIORITY;
break;
}
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
vmThread.thread = javaThread;
system.threading.Thread.SetData(localDataStoreSlot, javaThread);
cli.System.Threading.Thread.SetData(localDataStoreSlot, javaThread);
javaThread.group = ThreadGroup.root;
javaThread.group.addThread(javaThread);
InheritableThreadLocal.newChildThread(javaThread);
@ -246,20 +246,20 @@ final class VMThread
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
{
try
{
if(false) throw new system.threading.ThreadInterruptedException();
if(false) throw new cli.System.Threading.ThreadInterruptedException();
// 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())
{
if(false) throw new InterruptedException();
system.threading.Thread.Sleep(0);
cli.System.Threading.Thread.Sleep(0);
}
return false;
}
@ -292,7 +292,7 @@ final class VMThread
// NOTE Wait causes the lock to be released temporarily, which isn't what we want
if(false) throw new IllegalMonitorStateException();
if(false) throw new InterruptedException();
system.threading.Monitor.Wait(obj, 0);
cli.System.Threading.Monitor.Wait(obj, 0);
return true;
}
catch(IllegalMonitorStateException x)
@ -302,7 +302,7 @@ final class VMThread
catch(InterruptedException x1)
{
// 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;
}
}

Просмотреть файл

@ -38,8 +38,6 @@ exception statement from your version. */
package java.lang.reflect;
import system.reflection.*;
/**
* The Constructor class represents a constructor of a class. It also allows
* dynamic creation of an object, via reflection. Invocation on Constructor
@ -162,7 +160,7 @@ public final class Constructor
*/
public boolean equals(Object o)
{
if(o instanceof ConstructorInfo)
if(o instanceof Constructor)
{
return methodCookie == ((Constructor)o).methodCookie;
}

Просмотреть файл

@ -38,8 +38,6 @@ exception statement from your version. */
package java.lang.reflect;
import system.reflection.*;
/**
* The Method class represents a member method of a class. It also allows
* dynamic invocation, via reflection. This works for both static and

Просмотреть файл

@ -39,9 +39,10 @@ exception statement from your version. */
package java.net;
import java.io.IOException;
import system.net.*;
import system.net.sockets.*;
import cli.System.Net.*;
import cli.System.Net.Sockets.*;
import ikvm.lang.CIL;
import ikvm.lang.ByteArrayHack;
/**
* This is the default socket implementation for datagram sockets.
@ -70,12 +71,12 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
private static class MyUdpClient extends UdpClient
{
MyUdpClient(system.net.IPEndPoint ep)
MyUdpClient(cli.System.Net.IPEndPoint ep)
{
super(ep);
}
system.net.sockets.Socket getSocket()
cli.System.Net.Sockets.Socket getSocket()
{
return super.get_Client();
}
@ -153,7 +154,7 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
{
// TODO error handling
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
throw new IOException();
@ -183,13 +184,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
byte[] data = packet.getData();
int length = packet.getLength();
system.net.IPEndPoint[] remoteEP = new system.net.IPEndPoint[] {
new system.net.IPEndPoint(0, 0)
cli.System.Net.IPEndPoint[] remoteEP = new cli.System.Net.IPEndPoint[] {
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));
// I think the spec says that the Length property of DatagramPacket
// contains the number of bytes in the network packet (even if
@ -201,10 +202,10 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
packet.setAddress(remoteAddress);
packet.setPort(remoteEP[0].get_Port());
}
catch(system.net.sockets.SocketException x)
catch(cli.System.Net.Sockets.SocketException x)
{
// TODO error handling
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -221,13 +222,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
socket.JoinMulticastGroup(new system.net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
if(false) throw new cli.System.Net.Sockets.SocketException();
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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -244,13 +245,13 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
socket.DropMulticastGroup(new system.net.IPAddress(PlainSocketImpl.getAddressFromInetAddress(addr)));
if(false) throw new cli.System.Net.Sockets.SocketException();
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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -335,20 +336,20 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
switch(option_id)
{
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:
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:
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
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
switch(option_id)
{
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;
case SocketOptions.SO_TIMEOUT:
socket.getSocket().SetSocketOption(SocketOptionLevel.Socket, 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.ReceiveTimeout), ((Integer)val).intValue());
socket.getSocket().SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendTimeout), ((Integer)val).intValue());
break;
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;
default:
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.OutputStream;
import java.io.IOException;
import system.net.*;
import system.net.sockets.*;
import cli.System.Net.*;
import cli.System.Net.Sockets.*;
import ikvm.lang.CIL;
import ikvm.lang.ByteArrayHack;
/**
* 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
*/
private system.net.sockets.Socket socket;
private cli.System.Net.Sockets.Socket socket;
/**
@ -80,8 +81,8 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
system.net.sockets.Socket accept = socket.Accept();
if(false) throw new cli.System.Net.Sockets.SocketException();
cli.System.Net.Sockets.Socket accept = socket.Accept();
((PlainSocketImpl)impl).socket = accept;
IPEndPoint remoteEndPoint = ((IPEndPoint)accept.get_RemoteEndPoint());
long remoteIP = remoteEndPoint.get_Address().get_Address();
@ -90,10 +91,10 @@ class PlainSocketImpl extends SocketImpl
impl.port = remoteEndPoint.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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -109,13 +110,13 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
return socket.get_Available();
}
catch(system.net.sockets.SocketException x)
catch(cli.System.Net.Sockets.SocketException x)
{
// TODO error handling
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -132,14 +133,14 @@ class PlainSocketImpl extends SocketImpl
{
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));
this.address = addr;
}
catch(system.net.sockets.SocketException x)
catch(cli.System.Net.Sockets.SocketException x)
{
// TODO error handling
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -162,13 +163,13 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
socket.Close();
}
catch(system.net.sockets.SocketException x)
catch(cli.System.Net.Sockets.SocketException x)
{
// TODO error handling
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -184,16 +185,16 @@ class PlainSocketImpl extends SocketImpl
{
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));
this.address = addr;
this.port = 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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -229,13 +230,13 @@ class PlainSocketImpl extends SocketImpl
}
try
{
if(false) throw new system.net.sockets.SocketException();
socket = new system.net.sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if(false) throw new cli.System.Net.Sockets.SocketException();
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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -253,14 +254,14 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
socket.Listen(queuelen);
localport = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
}
catch(system.net.sockets.SocketException x)
catch(cli.System.Net.Sockets.SocketException x)
{
// TODO error handling
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -277,13 +278,13 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
return socket.Receive(buf, offset, len, SocketFlags.None);
if(false) throw new cli.System.Net.Sockets.SocketException();
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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -298,13 +299,13 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
socket.Send(buf, offset, len, SocketFlags.None);
if(false) throw new cli.System.Net.Sockets.SocketException();
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
throw new IOException(x.get_Message());
throw new IOException(x.getMessage());
}
}
@ -323,56 +324,56 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
switch(option_id)
{
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;
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;
case SocketOptions.SO_TIMEOUT:
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, ((Integer)val).intValue());
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, ((Integer)val).intValue());
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout), ((Integer)val).intValue());
socket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendTimeout), ((Integer)val).intValue());
break;
case SocketOptions.SO_LINGER:
{
system.net.sockets.LingerOption linger;
cli.System.Net.Sockets.LingerOption linger;
if(val instanceof Boolean)
{
linger = new system.net.sockets.LingerOption(false, 0);
linger = new cli.System.Net.Sockets.LingerOption(false, 0);
}
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;
}
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;
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;
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;
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;
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;
default:
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
throw new SocketException(x.get_Message());
throw new SocketException(x.getMessage());
}
}
@ -391,7 +392,7 @@ class PlainSocketImpl extends SocketImpl
{
try
{
if(false) throw new system.net.sockets.SocketException();
if(false) throw new cli.System.Net.Sockets.SocketException();
switch(option_id)
{
case SocketOptions.SO_BINDADDR:
@ -404,14 +405,14 @@ class PlainSocketImpl extends SocketImpl
throw new SocketException(x.getMessage());
}
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:
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:
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:
{
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())
{
return new Integer(linger.get_LingerTime());
@ -419,29 +420,29 @@ class PlainSocketImpl extends SocketImpl
return Boolean.FALSE;
}
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:
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:
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:
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:
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:
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
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) };
}

Двоичные данные
classpath/mscorlib.jar

Двоичный файл не отображается.

Просмотреть файл

@ -24,7 +24,7 @@
package sun.misc;
import system.WeakReference;
import cli.System.WeakReference;
public abstract class Ref
{

Просмотреть файл

@ -4,10 +4,10 @@
<nant buildfile="OpenSystem.Java/OpenSystem.Java.build" />
<nant buildfile="IK.VM.NET/ik.vm.net.build" />
<nant buildfile="IK.VM.JNI/ik.vm.jni.build" />
<nant buildfile="netexp/netexp.build" />
<nant buildfile="ikvmc/ikvmc.build" />
<nant buildfile="classpath/classpath.build" />
<nant buildfile="ikvm/ikvm.build" />
<nant buildfile="awt/awt.build" />
<nant buildfile="netexp/netexp.build" />
</target>
</project>

Просмотреть файл

@ -60,6 +60,7 @@ class Compiler
string outputfile = null;
string main = null;
bool nojni = false;
ArrayList classesToExclude = new ArrayList();
ArrayList references = new ArrayList();
ArrayList arglist = GetArgs(args);
if(arglist.Count == 0)
@ -77,6 +78,8 @@ class Compiler
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(" -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;
}
ArrayList classes = new ArrayList();
@ -151,6 +154,14 @@ class Compiler
{
nojni = true;
}
else if(s.StartsWith("-exclude:"))
{
ProcessExclusionFile(classesToExclude, s.Substring(9));
}
else if(s == "-debug")
{
JVM.Debug = true;
}
else
{
Console.Error.WriteLine("Warning: Unrecognized option: {0}", s);
@ -190,7 +201,7 @@ class Compiler
}
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;
}
catch(Exception x)
@ -263,14 +274,21 @@ class Compiler
else
{
// include as resource
using(FileStream fs = new FileStream(file, FileMode.Open))
try
{
byte[] b = new byte[fs.Length];
fs.Read(b, 0, b.Length);
// HACK very lame way to extract the resource name (by chopping off the base directory)
string name = file.Substring(baseDir.FullName.Length + 1);
name = name.Replace('\\', '/');
resources.Add(name, b);
using(FileStream fs = new FileStream(file, FileMode.Open))
{
byte[] b = new byte[fs.Length];
fs.Read(b, 0, b.Length);
// HACK very lame way to extract the resource name (by chopping off the base directory)
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;
@ -289,4 +307,28 @@ class Compiler
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)
{
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);
}

Просмотреть файл

@ -25,8 +25,9 @@ using System;
using System.Reflection;
using System.IO;
using System.Text;
using System.Collections;
using ICSharpCode.SharpZipLib.Zip;
using java.lang;
using java.lang.reflect;
public class NetExp
{
@ -39,6 +40,10 @@ public class NetExp
{
assembly = Assembly.LoadFrom(args[0]);
}
else
{
assembly = Assembly.LoadWithPartialName(args[0]);
}
if(assembly == null)
{
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
@ -46,299 +51,19 @@ public class NetExp
else
{
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);
zipFile.Close();
}
}
private static void ProcessAssembly(Assembly assembly)
{
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);
// HACK if we run on the "classpath" assembly, the awt thread gets started,
// so we force an exit here
Environment.Exit(0);
}
private static void WriteClass(string name, ClassFileWriter c)
@ -347,164 +72,219 @@ public class NetExp
c.Write(zipFile);
}
private static void ProcessField(Type type, ClassFileWriter f, FieldInfo fi, Hashtable clashtable)
private class MyClassLoader : ClassLoader
{
Modifiers access;
if(fi.IsPublic)
public Class loadClass(Type type)
{
access = Modifiers.Public;
}
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);
return base.loadClass(type.AssemblyQualifiedName);
}
}
private static void ProcessMethod(Type type, ClassFileWriter f, MethodBase mb, Hashtable clashtable)
private static void ProcessAssembly(Assembly assembly)
{
Modifiers access = 0;
if(!mb.IsAbstract)
// HACK we use our own class loader to prevent class initialization
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!
if(mb.IsConstructor && type.IsSubclassOf(typeof(MulticastDelegate)))
Method[] methods = c.getDeclaredMethods();
for(int i = 0; i < methods.Length; i++)
{
access &= ~Modifiers.Final;
f.AddMethod(access, "<init>", "(L" + ClassName(type) + "$Method;)V");
return;
Modifiers mods = (Modifiers)methods[i].getModifiers();
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
{
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
// TODO only store it when it doesn't match the Java sig and split it into parts (instead of one giant string)
StringBuilder nativesig = new StringBuilder();
Field[] fields = c.getDeclaredFields();
for(int i = 0; i < fields.Length; i++)
{
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();
sb.Append('(');
ParameterInfo[] parameters = mb.GetParameters();
string sep = "";
for(int i = 0; i < parameters.Length; i++)
for(int i = 0; i < args.Length; i++)
{
if(parameters[i].ParameterType.IsPointer)
{
// Java doesn't support pointer parameters
return;
}
sb.Append(SigType(parameters[i].ParameterType));
nativesig.Append(sep).Append(parameters[i].ParameterType.AssemblyQualifiedName);
sep = "|";
sb.Append(ClassToSig(args[i]));
}
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
access &= ~Modifiers.Final;
sb.Append('V');
if(c == java.lang.Void.TYPE)
{
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
{
sb.Append(SigType(((MethodInfo)mb).ReturnType));
}
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())));
return "L" + c.getName().Replace('.', '/') + ";";
}
}
}

Просмотреть файл

@ -6,6 +6,9 @@
<includes name="*.cs" />
</sources>
<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" />
</references>
</csc>

Просмотреть файл

@ -84,6 +84,21 @@
AssemblyName = "SharpZipLib"
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>
</Build>
<Files>