зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
afe6bc0055
Коммит
8bde1e1e49
|
@ -68,7 +68,7 @@ public class ByteCodeHelper
|
|||
throw JavaException.NegativeArraySizeException();
|
||||
}
|
||||
TypeWrapper wrapper = LoadTypeWrapper(type, clazz);
|
||||
return Array.CreateInstance(wrapper.TypeOrUnloadableAsObject, length);
|
||||
return Array.CreateInstance(wrapper.TypeAsArrayType, length);
|
||||
}
|
||||
|
||||
[StackTraceInfo(Hidden = true)]
|
||||
|
|
|
@ -132,13 +132,17 @@ class ClassLoaderWrapper
|
|||
|
||||
internal static bool IsGhost(TypeWrapper wrapper)
|
||||
{
|
||||
string name = wrapper.Name;
|
||||
return wrapper.GetClassLoader() == bootstrapClassLoader && name != null && ghosts.ContainsKey(name);
|
||||
return wrapper.IsInterface && wrapper.GetClassLoader() == bootstrapClassLoader && ghosts.ContainsKey(wrapper.Name);
|
||||
}
|
||||
|
||||
internal static TypeWrapper[] GetGhostImplementers(TypeWrapper wrapper)
|
||||
{
|
||||
return (TypeWrapper[])((ArrayList)ghosts[wrapper.Name]).ToArray(typeof(TypeWrapper));
|
||||
ArrayList list = (ArrayList)ghosts[wrapper.Name];
|
||||
if(list == null)
|
||||
{
|
||||
return TypeWrapper.EmptyArray;
|
||||
}
|
||||
return (TypeWrapper[])list.ToArray(typeof(TypeWrapper));
|
||||
}
|
||||
|
||||
internal static bool IsRemappedType(Type type)
|
||||
|
|
|
@ -386,12 +386,12 @@ public abstract class CodeEmitter
|
|||
}
|
||||
}
|
||||
|
||||
class CastEmitter : CodeEmitter
|
||||
class ReturnCastEmitter : CodeEmitter
|
||||
{
|
||||
private Type type;
|
||||
private string className;
|
||||
|
||||
internal CastEmitter(string className)
|
||||
internal ReturnCastEmitter(string className)
|
||||
{
|
||||
this.className = className;
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ class CastEmitter : CodeEmitter
|
|||
{
|
||||
if(type == null)
|
||||
{
|
||||
type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(className).TypeOrUnloadableAsObject;
|
||||
type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(className).TypeAsParameterType;
|
||||
}
|
||||
if(type != typeof(object))
|
||||
{
|
||||
|
|
|
@ -206,7 +206,7 @@ class MethodWrapper : MemberWrapper
|
|||
LocalBuilder[] argLocals = new LocalBuilder[args.Length];
|
||||
for(int i = args.Length - 1; i >= 0; i--)
|
||||
{
|
||||
argLocals[i] = ilgen.DeclareLocal(args[i].TypeOrUnloadableAsObject);
|
||||
argLocals[i] = ilgen.DeclareLocal(args[i].TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, argLocals[i]);
|
||||
}
|
||||
Label end = ilgen.DefineLabel();
|
||||
|
|
|
@ -966,8 +966,7 @@ abstract class TypeWrapper
|
|||
}
|
||||
}
|
||||
|
||||
// TODO this should really be named TypeAsLocalArgOrStackType (or something like that)
|
||||
internal Type TypeOrUnloadableAsObject
|
||||
internal Type TypeAsFieldType
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -985,11 +984,71 @@ abstract class TypeWrapper
|
|||
}
|
||||
return Type.GetType(type, true);
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsParameterType
|
||||
{
|
||||
get
|
||||
{
|
||||
return TypeAsFieldType;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsBaseType
|
||||
{
|
||||
get
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsLocalOrStackType
|
||||
{
|
||||
get
|
||||
{
|
||||
// HACK as a convenience to the compiler, we replace return address types with typeof(int)
|
||||
if(VerifierTypeWrapper.IsRet(this))
|
||||
{
|
||||
return typeof(int);
|
||||
}
|
||||
if(IsUnloadable || IsGhost || IsNonPrimitiveValueType)
|
||||
{
|
||||
return typeof(object);
|
||||
}
|
||||
if(IsGhostArray)
|
||||
{
|
||||
int rank = ArrayRank;
|
||||
string type = "System.Object";
|
||||
for(int i = 0; i < rank; i++)
|
||||
{
|
||||
type += "[]";
|
||||
}
|
||||
return Type.GetType(type, true);
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsArrayType
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO if ghosts are ever compiled as value types (for fields), we need special treatment here,
|
||||
// otherwise array covariance breaks down
|
||||
return TypeAsFieldType;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsExceptionType
|
||||
{
|
||||
get
|
||||
{
|
||||
if(IsUnloadable)
|
||||
{
|
||||
return typeof(Exception);
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
}
|
||||
|
@ -1696,12 +1755,12 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
typeAttribs |= TypeAttributes.Class;
|
||||
if(outer != null)
|
||||
{
|
||||
// TODO in the CLR interfaces cannot contain nested types!
|
||||
typeBuilder = outer.DefineNestedType(GetInnerClassName(outerClassWrapper.Name, f.Name), typeAttribs, wrapper.BaseTypeWrapper.Type);
|
||||
// TODO in the CLR interfaces cannot contain nested types! (well, it works fine, but the spec says it isn't allowed)
|
||||
typeBuilder = outer.DefineNestedType(GetInnerClassName(outerClassWrapper.Name, f.Name), typeAttribs, wrapper.BaseTypeWrapper.TypeAsBaseType);
|
||||
}
|
||||
else
|
||||
{
|
||||
typeBuilder = wrapper.GetClassLoader().ModuleBuilder.DefineType(wrapper.GetClassLoader().MangleTypeName(f.Name), typeAttribs, wrapper.BaseTypeWrapper.Type);
|
||||
typeBuilder = wrapper.GetClassLoader().ModuleBuilder.DefineType(wrapper.GetClassLoader().MangleTypeName(f.Name), typeAttribs, wrapper.BaseTypeWrapper.TypeAsBaseType);
|
||||
}
|
||||
}
|
||||
TypeWrapper[] interfaces = wrapper.Interfaces;
|
||||
|
@ -2105,7 +2164,7 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
modargs[1] = typeof(IntPtr);
|
||||
for(int i = 0; i < args.Length; i++)
|
||||
{
|
||||
modargs[i + 2] = args[i].TypeOrUnloadableAsObject;
|
||||
modargs[i + 2] = args[i].TypeAsParameterType;
|
||||
}
|
||||
int add = 0;
|
||||
if(!m.IsStatic)
|
||||
|
@ -2159,7 +2218,7 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.Type);
|
||||
}
|
||||
}
|
||||
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeOrUnloadableAsObject);
|
||||
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, retValue);
|
||||
}
|
||||
ilGenerator.BeginCatchBlock(typeof(object));
|
||||
|
@ -2233,12 +2292,15 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
{
|
||||
FieldBuilder field;
|
||||
ClassFile.Field fld = classFile.Fields[i];
|
||||
string fieldName = fld.Name;
|
||||
TypeWrapper typeWrapper = fld.GetFieldType(wrapper.GetClassLoader());
|
||||
Type type = typeWrapper.TypeOrUnloadableAsObject;
|
||||
Type type = typeWrapper.TypeAsFieldType;
|
||||
if(typeWrapper.IsUnloadable)
|
||||
{
|
||||
// TODO the field name should be mangled here, because otherwise it might conflict with another field
|
||||
// with the same name and a different unloadable type (or java.lang.Object as its type)
|
||||
// the field name is mangled here, because otherwise it can (theoretically)
|
||||
// conflict with another unloadable or object field
|
||||
// (fields can be overloaded on type)
|
||||
fieldName += "/" + typeWrapper.Name;
|
||||
}
|
||||
FieldAttributes attribs = 0;
|
||||
MethodAttributes methodAttribs = 0;
|
||||
|
@ -2275,7 +2337,7 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
{
|
||||
Profiler.Count("Static Final Constant");
|
||||
attribs |= FieldAttributes.Literal;
|
||||
field = typeBuilder.DefineField(fld.Name, type, attribs);
|
||||
field = typeBuilder.DefineField(fieldName, type, attribs);
|
||||
field.SetConstant(constantValue);
|
||||
// NOTE even though you're not supposed to access a constant static final (the compiler is supposed
|
||||
// to inline them), we have to support it (because it does happen, e.g. if the field becomes final
|
||||
|
@ -2301,7 +2363,7 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
setModifiers = true;
|
||||
}
|
||||
}
|
||||
field = typeBuilder.DefineField(fld.Name, type, attribs);
|
||||
field = typeBuilder.DefineField(fieldName, type, attribs);
|
||||
if(fld.IsTransient)
|
||||
{
|
||||
CustomAttributeBuilder transientAttrib = new CustomAttributeBuilder(typeof(NonSerializedAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
|
||||
|
@ -2419,10 +2481,10 @@ class DynamicTypeWrapper : TypeWrapper
|
|||
TypeWrapper[] argTypeWrappers = m.GetArgTypes(wrapper.GetClassLoader());
|
||||
TypeWrapper retTypeWrapper = m.GetRetType(wrapper.GetClassLoader());
|
||||
Type[] args = new Type[argTypeWrappers.Length];
|
||||
Type retType = retTypeWrapper.TypeOrUnloadableAsObject;
|
||||
Type retType = retTypeWrapper.TypeAsParameterType;
|
||||
for(int i = 0; i < args.Length; i++)
|
||||
{
|
||||
args[i] = argTypeWrappers[i].TypeOrUnloadableAsObject;
|
||||
args[i] = argTypeWrappers[i].TypeAsParameterType;
|
||||
}
|
||||
bool setModifiers = false;
|
||||
MethodAttributes attribs = 0;
|
||||
|
@ -2995,7 +3057,7 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
ret = ret.Substring(1, ret.Length - 2);
|
||||
}
|
||||
retcast = new CastEmitter(ret);
|
||||
retcast = new ReturnCastEmitter(ret);
|
||||
}
|
||||
if(BaseTypeWrapper != null && !Type.IsSealed)
|
||||
{
|
||||
|
@ -3198,7 +3260,7 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
ret = ret.Substring(1, ret.Length - 2);
|
||||
}
|
||||
retcast = new CastEmitter(ret);
|
||||
retcast = new ReturnCastEmitter(ret);
|
||||
}
|
||||
CodeEmitter ignore = null;
|
||||
MethodWrapper.CreateEmitters(null, redirect, ref ignore, ref ignore, ref newopc);
|
||||
|
@ -3276,11 +3338,11 @@ class RemappedTypeWrapper : TypeWrapper
|
|||
{
|
||||
if(fieldSig[0] == 'L')
|
||||
{
|
||||
getter += new CastEmitter(fieldSig.Substring(1, fieldSig.Length - 2));
|
||||
getter += new ReturnCastEmitter(fieldSig.Substring(1, fieldSig.Length - 2));
|
||||
}
|
||||
else if(fieldSig[0] == '[')
|
||||
{
|
||||
getter += new CastEmitter(fieldSig);
|
||||
getter += new ReturnCastEmitter(fieldSig);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3752,7 +3814,15 @@ class CompiledTypeWrapper : TypeWrapper
|
|||
{
|
||||
if(!AttributeHelper.IsHideFromReflection(fields[i]))
|
||||
{
|
||||
list.Add(CreateFieldWrapper(AttributeHelper.GetModifiers(fields[i]), fields[i].Name, fields[i].FieldType, fields[i], null));
|
||||
// if the field name is mangled (because its type is unloadable),
|
||||
// chop off the mangled bit
|
||||
string fieldName = fields[i].Name;
|
||||
int idx = fieldName.IndexOf('/');
|
||||
if(idx >= 0)
|
||||
{
|
||||
fieldName = fieldName.Substring(0, idx);
|
||||
}
|
||||
list.Add(CreateFieldWrapper(AttributeHelper.GetModifiers(fields[i]), fieldName, fields[i].FieldType, fields[i], null));
|
||||
}
|
||||
}
|
||||
return (FieldWrapper[])list.ToArray(typeof(FieldWrapper));
|
||||
|
|
|
@ -375,13 +375,9 @@ class Compiler
|
|||
{
|
||||
// new objects aren't really there on the stack
|
||||
}
|
||||
else if(!type.IsUnloadable && type.IsNonPrimitiveValueType)
|
||||
{
|
||||
locals[i] = ilgen.DeclareLocal(typeof(object));
|
||||
}
|
||||
else
|
||||
{
|
||||
locals[i] = ilgen.DeclareLocal(type.TypeOrUnloadableAsObject);
|
||||
locals[i] = ilgen.DeclareLocal(type.TypeAsLocalOrStackType);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -556,7 +552,7 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(t.TypeOrUnloadableAsObject);
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(t.TypeAsLocalOrStackType);
|
||||
stack.Push(local);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
}
|
||||
|
@ -620,7 +616,7 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(t.TypeOrUnloadableAsObject);
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(t.TypeAsLocalOrStackType);
|
||||
bc.Stack.Push(local);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
}
|
||||
|
@ -642,7 +638,7 @@ class Compiler
|
|||
{
|
||||
exceptionTypeWrapper = tw;
|
||||
}
|
||||
excType = tw.TypeOrUnloadableAsObject;
|
||||
excType = tw.TypeAsExceptionType;
|
||||
}
|
||||
if(true)
|
||||
{
|
||||
|
@ -1082,7 +1078,7 @@ class Compiler
|
|||
}
|
||||
else if(!VerifierTypeWrapper.IsNew(stacktype))
|
||||
{
|
||||
LocalBuilder lb = ilGenerator.DeclareLocal(stacktype.TypeOrUnloadableAsObject);
|
||||
LocalBuilder lb = ilGenerator.DeclareLocal(stacktype.TypeAsLocalOrStackType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, lb);
|
||||
tempstack[j] = lb;
|
||||
}
|
||||
|
@ -1180,7 +1176,7 @@ class Compiler
|
|||
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
|
||||
{
|
||||
TypeWrapper retTypeWrapper = m.Method.GetRetType(classLoader);
|
||||
rc.Local = ilGenerator.DeclareLocal(retTypeWrapper.TypeOrUnloadableAsObject);
|
||||
rc.Local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsLocalOrStackType);
|
||||
if(!retTypeWrapper.IsUnloadable)
|
||||
{
|
||||
// because of the way interface merging works, any reference is valid
|
||||
|
@ -1234,7 +1230,7 @@ class Compiler
|
|||
}
|
||||
if(stackHeight != 1)
|
||||
{
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeOrUnloadableAsObject);
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
for(int j = 1; j < stackHeight; j++)
|
||||
{
|
||||
|
@ -1384,7 +1380,7 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
Type type = wrapper.TypeOrUnloadableAsObject;
|
||||
Type type = wrapper.TypeAsArrayType;
|
||||
ilGenerator.Emit(OpCodes.Ldtoken, type);
|
||||
ilGenerator.Emit(OpCodes.Ldloc, localArray);
|
||||
ilGenerator.Emit(OpCodes.Call, multiANewArrayMethod);
|
||||
|
@ -1403,7 +1399,7 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
// HACK we use TypeOrUnloadableAsObject here, to make sure that Ghost implementers can be
|
||||
// NOTE for ghost types we create object arrays to make sure that Ghost implementers can be
|
||||
// stored in ghost arrays, but this has the unintended consequence that ghost arrays can
|
||||
// contain *any* reference type (because they are compiled as Object arrays). We could
|
||||
// modify aastore to emit code to check for this, but this would have an huge performance
|
||||
|
@ -1413,7 +1409,7 @@ class Compiler
|
|||
// is unfortunate, but I think we can live with this minor incompatibility.
|
||||
// NOTE that this does not break type safety, because when the incorrect object is eventually
|
||||
// used as the ghost interface type it will generate a ClassCastException.
|
||||
ilGenerator.Emit(OpCodes.Newarr, wrapper.TypeOrUnloadableAsObject);
|
||||
ilGenerator.Emit(OpCodes.Newarr, wrapper.TypeAsArrayType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2886,7 +2882,7 @@ class Compiler
|
|||
TypeWrapper t = ma.GetDeclaredLocalTypeWrapper(index);
|
||||
if(t != VerifierTypeWrapper.Null)
|
||||
{
|
||||
type = t.TypeOrUnloadableAsObject;
|
||||
type = t.TypeAsLocalOrStackType;
|
||||
}
|
||||
}
|
||||
LocalBuilder lb = (LocalBuilder)locals[name];
|
||||
|
|
Загрузка…
Ссылка в новой задаче