зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
11608ba623
Коммит
8cddcbc71d
|
@ -441,4 +441,5 @@ final class VMClassLoader
|
|||
static final boolean USE_VM_CACHE = true;
|
||||
|
||||
static native Class findLoadedClass(ClassLoader cl, String name);
|
||||
static native void registerInitiatingLoader(ClassLoader cl, Class c);
|
||||
}
|
||||
|
|
|
@ -192,6 +192,42 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal TypeWrapper RegisterInitiatingLoader(TypeWrapper tw)
|
||||
{
|
||||
if(tw.IsUnloadable || tw.IsPrimitive)
|
||||
return tw;
|
||||
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
object existing = types[tw.Name];
|
||||
if(existing != tw)
|
||||
{
|
||||
if(existing != null)
|
||||
{
|
||||
throw new LinkageError("duplicate class definition: " + tw.Name);
|
||||
}
|
||||
if(tw.IsArray)
|
||||
{
|
||||
TypeWrapper elem = tw;
|
||||
// TODO there should be a way to get the ultimate element type
|
||||
// without creating all the intermediate types
|
||||
while(elem.IsArray)
|
||||
{
|
||||
elem = elem.ElementTypeWrapper;
|
||||
}
|
||||
RegisterInitiatingLoader(elem);
|
||||
}
|
||||
// NOTE if types.ContainsKey(tw.Name) is true (i.e. the value is null),
|
||||
// we currently have a DefineClass in progress on another thread and we've
|
||||
// beaten that thread to the punch by loading the class from a parent class
|
||||
// loader instead. This is ok as DefineClass will throw a LinkageError when
|
||||
// it is done.
|
||||
types[tw.Name] = tw;
|
||||
}
|
||||
}
|
||||
return tw;
|
||||
}
|
||||
|
||||
// FXBUG This mangles type names, to enable different class loaders loading classes with the same names.
|
||||
// We used to support this by using an assembly per class loader instance, but because
|
||||
// of the CLR TypeResolve bug, we put all types in a single assembly for now.
|
||||
|
@ -276,7 +312,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
type = type.GetClassLoader().CreateArrayType(name, type, dims);
|
||||
}
|
||||
return type;
|
||||
return RegisterInitiatingLoader(type);
|
||||
}
|
||||
if(name.Length != dims + 1)
|
||||
{
|
||||
|
@ -286,21 +322,21 @@ namespace IKVM.Internal
|
|||
switch(name[dims])
|
||||
{
|
||||
case 'B':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BYTE, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BYTE, dims));
|
||||
case 'C':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.CHAR, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.CHAR, dims));
|
||||
case 'D':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.DOUBLE, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.DOUBLE, dims));
|
||||
case 'F':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.FLOAT, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.FLOAT, dims));
|
||||
case 'I':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.INT, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.INT, dims));
|
||||
case 'J':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.LONG, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.LONG, dims));
|
||||
case 'S':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.SHORT, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.SHORT, dims));
|
||||
case 'Z':
|
||||
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BOOLEAN, dims);
|
||||
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BOOLEAN, dims));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -332,7 +368,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(t.Module.IsDefined(typeof(JavaModuleAttribute), false))
|
||||
{
|
||||
return GetWrapperFromType(t);
|
||||
return RegisterInitiatingLoader(GetWrapperFromType(t));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -350,7 +386,7 @@ namespace IKVM.Internal
|
|||
Type t = GetBootstrapTypeRaw(name);
|
||||
if(t != null)
|
||||
{
|
||||
return GetWrapperFromBootstrapType(t);
|
||||
return RegisterInitiatingLoader(GetWrapperFromBootstrapType(t));
|
||||
}
|
||||
type = DotNetTypeWrapper.CreateDotNetTypeWrapper(name);
|
||||
if(type != null)
|
||||
|
@ -399,7 +435,7 @@ namespace IKVM.Internal
|
|||
Profiler.Leave("ClassLoader.loadClass");
|
||||
}
|
||||
}
|
||||
return type;
|
||||
return RegisterInitiatingLoader(type);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -626,7 +662,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
type = race;
|
||||
throw new LinkageError("duplicate class definition: " + f.Name);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
/>
|
||||
<Reference
|
||||
Name = "System.XML"
|
||||
AssemblyName = "System.XML"
|
||||
AssemblyName = "System.Xml"
|
||||
HintPath = "..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
|
||||
/>
|
||||
</References>
|
||||
|
|
|
@ -2168,7 +2168,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
if(BaseTypeWrapper.IsFinal)
|
||||
{
|
||||
throw new VerifyError("Cannot inherit from final class");
|
||||
throw new VerifyError("Class " + f.Name + " extends final class " + BaseTypeWrapper.Name);
|
||||
}
|
||||
if(BaseTypeWrapper.IsInterface)
|
||||
{
|
||||
|
@ -2283,8 +2283,6 @@ namespace IKVM.Internal
|
|||
try
|
||||
{
|
||||
impl = impl.Finish(forDebugSave);
|
||||
// call Finish again to get the verify error for doomed types
|
||||
impl.Finish(forDebugSave);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -3049,7 +3047,6 @@ namespace IKVM.Internal
|
|||
parent = parent.BaseTypeWrapper;
|
||||
}
|
||||
}
|
||||
string verifyError = null;
|
||||
bool basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer;
|
||||
bool hasclinit = false;
|
||||
for(int i = 0; i < classFile.Methods.Length; i++)
|
||||
|
@ -3067,7 +3064,7 @@ namespace IKVM.Internal
|
|||
EmitConstantValueInitialization(ilGenerator);
|
||||
EmitHelper.RunClassConstructor(ilGenerator, Type.BaseType);
|
||||
}
|
||||
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref verifyError);
|
||||
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3184,7 +3181,7 @@ namespace IKVM.Internal
|
|||
continue;
|
||||
}
|
||||
bool nonleaf = false;
|
||||
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref verifyError, ref nonleaf);
|
||||
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref nonleaf);
|
||||
if(nonleaf)
|
||||
{
|
||||
mbld.SetImplementationFlags(mbld.GetMethodImplementationFlags() | MethodImplAttributes.NoInlining);
|
||||
|
@ -3345,16 +3342,9 @@ namespace IKVM.Internal
|
|||
Profiler.Leave("TypeBuilder.CreateType");
|
||||
}
|
||||
ClassLoaderWrapper.SetWrapperForType(type, wrapper);
|
||||
if(verifyError != null)
|
||||
{
|
||||
return new DoomedTypeImpl(verifyError);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapper.FinishGhostStep2();
|
||||
finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, this.ReflectiveModifiers);
|
||||
return finishedType;
|
||||
}
|
||||
wrapper.FinishGhostStep2();
|
||||
finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, this.ReflectiveModifiers);
|
||||
return finishedType;
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
|
@ -3921,7 +3911,7 @@ namespace IKVM.Internal
|
|||
// method more accessible, because otherwise the CLR will complain that we're reducing access
|
||||
MethodBase baseMethod = baseMce.GetMethod();
|
||||
if((baseMethod.IsPublic && !m.IsPublic) ||
|
||||
(baseMethod.IsFamily && !m.IsPublic && !m.IsProtected) ||
|
||||
((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) ||
|
||||
(!m.IsPublic && !m.IsProtected && !baseMce.DeclaringType.IsInSamePackageAs(wrapper)))
|
||||
{
|
||||
attribs &= ~MethodAttributes.MemberAccessMask;
|
||||
|
@ -4158,67 +4148,6 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private class DoomedTypeImpl : DynamicImpl
|
||||
{
|
||||
private string message;
|
||||
|
||||
internal DoomedTypeImpl(string message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
internal override TypeWrapper DeclaringTypeWrapper
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override DynamicImpl Finish(bool forDebugSave)
|
||||
{
|
||||
if(!forDebugSave)
|
||||
{
|
||||
throw new VerifyError(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
internal override TypeWrapper[] InnerClasses
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override FieldInfo LinkField(FieldWrapper fw)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override MethodBase LinkMethod(MethodWrapper mw)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override Modifiers ReflectiveModifiers
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Modifiers)0;
|
||||
}
|
||||
}
|
||||
|
||||
internal override Type Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FinishedTypeImpl : DynamicImpl
|
||||
{
|
||||
private Type type;
|
||||
|
|
|
@ -648,7 +648,7 @@ namespace IKVM.NativeCode.java
|
|||
{
|
||||
rank++;
|
||||
}
|
||||
if(name[rank] == 'L')
|
||||
if(name[rank] == 'L' && name[rank + 1] != '[')
|
||||
{
|
||||
wrapper = loader.GetLoadedClass(name.Substring(rank + 1, name.Length - (rank + 2)));
|
||||
if(wrapper != null)
|
||||
|
@ -659,6 +659,23 @@ namespace IKVM.NativeCode.java
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerInitiatingLoader(object javaClassLoader, object clazz)
|
||||
{
|
||||
ClassLoaderWrapper loader = ClassLoaderWrapper.GetClassLoaderWrapper(javaClassLoader);
|
||||
TypeWrapper tw = VMClass.getWrapperFromClass(clazz);
|
||||
if(tw.GetClassLoader() != loader)
|
||||
{
|
||||
try
|
||||
{
|
||||
loader.RegisterInitiatingLoader(tw);
|
||||
}
|
||||
catch(RetargetableJavaException x)
|
||||
{
|
||||
throw x.ToJava();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VMClass
|
||||
|
|
|
@ -813,13 +813,13 @@ class Compiler
|
|||
}
|
||||
}
|
||||
|
||||
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref string verifyError)
|
||||
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator)
|
||||
{
|
||||
bool nonleaf = false;
|
||||
Compile(clazz, mw, classFile, m, ilGenerator, ref verifyError, ref nonleaf);
|
||||
Compile(clazz, mw, classFile, m, ilGenerator, ref nonleaf);
|
||||
}
|
||||
|
||||
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref string verifyError, ref bool nonleaf)
|
||||
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref bool nonleaf)
|
||||
{
|
||||
ClassLoaderWrapper classLoader = clazz.GetClassLoader();
|
||||
ISymbolDocumentWriter symboldocument = null;
|
||||
|
@ -892,10 +892,6 @@ class Compiler
|
|||
// because in Java the method is only verified if it is actually called,
|
||||
// we generate code here to throw the VerificationError
|
||||
EmitHelper.Throw(ilGenerator, "java.lang.VerifyError", x.Message);
|
||||
if(verifyError == null)
|
||||
{
|
||||
verifyError = x.Message;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Profiler.Enter("Compile");
|
||||
|
@ -1166,7 +1162,7 @@ class Compiler
|
|||
{
|
||||
if(cpi.GetFieldType() != fw.FieldTypeWrapper && !fw.FieldTypeWrapper.IsUnloadable)
|
||||
{
|
||||
throw new LinkageError("Loader constraints violated: " + fw.Name);
|
||||
throw new LinkageError("Loader constraints violated: " + fw.DeclaringType.Name + "." + fw.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1174,7 +1170,7 @@ class Compiler
|
|||
{
|
||||
if(cpi.GetRetType() != mw.ReturnType && !mw.ReturnType.IsUnloadable)
|
||||
{
|
||||
throw new LinkageError("Loader constraints violated: " + mw.Name + mw.Signature);
|
||||
throw new LinkageError("Loader constraints violated (return type): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature);
|
||||
}
|
||||
TypeWrapper[] here = cpi.GetArgTypes();
|
||||
TypeWrapper[] there = mw.GetParameters();
|
||||
|
@ -1182,7 +1178,7 @@ class Compiler
|
|||
{
|
||||
if(here[i] != there[i] && !there[i].IsUnloadable)
|
||||
{
|
||||
throw new LinkageError("Loader constraints violated: " + mw.Name + mw.Signature);
|
||||
throw new LinkageError("Loader constraints violated (arg " + i + "): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче