зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
a2b54470a6
Коммит
7cc7744ec9
|
@ -637,6 +637,7 @@ class Compiler
|
|||
{
|
||||
Null,
|
||||
New,
|
||||
This,
|
||||
UnitializedThis,
|
||||
Other
|
||||
}
|
||||
|
@ -681,6 +682,10 @@ class Compiler
|
|||
// new objects aren't really there on the stack
|
||||
types[i] = StackType.New;
|
||||
}
|
||||
else if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
types[i] = StackType.This;
|
||||
}
|
||||
else if(type == VerifierTypeWrapper.UninitializedThis)
|
||||
{
|
||||
// uninitialized references cannot be stored in a local, but we can reload them
|
||||
|
@ -703,6 +708,7 @@ class Compiler
|
|||
case StackType.New:
|
||||
// new objects aren't really there on the stack
|
||||
break;
|
||||
case StackType.This:
|
||||
case StackType.UnitializedThis:
|
||||
compiler.ilGenerator.Emit(OpCodes.Ldarg_0);
|
||||
break;
|
||||
|
@ -719,6 +725,7 @@ class Compiler
|
|||
switch(types[i])
|
||||
{
|
||||
case StackType.Null:
|
||||
case StackType.This:
|
||||
case StackType.UnitializedThis:
|
||||
compiler.ilGenerator.Emit(OpCodes.Pop);
|
||||
break;
|
||||
|
@ -1417,8 +1424,7 @@ class Compiler
|
|||
ClassFile.ConstantPoolItemFieldref cpi = classFile.GetFieldref(instr.Arg1);
|
||||
FieldWrapper field = cpi.GetField();
|
||||
TypeWrapper tw = field.FieldTypeWrapper;
|
||||
TypeWrapper val = ma.GetRawStackTypeWrapper(i, 0);
|
||||
tw.EmitConvStackTypeToSignatureType(ilGenerator, val);
|
||||
tw.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0));
|
||||
field.EmitSet(ilGenerator);
|
||||
break;
|
||||
}
|
||||
|
@ -1511,8 +1517,8 @@ class Compiler
|
|||
cpi.Signature == "(Ljava.lang.Object;ILjava.lang.Object;II)V" &&
|
||||
cpi.GetClassType().GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader())
|
||||
{
|
||||
TypeWrapper dst_type = ma.GetRawStackTypeWrapper(i, 2);
|
||||
TypeWrapper src_type = ma.GetRawStackTypeWrapper(i, 4);
|
||||
TypeWrapper dst_type = ma.GetStackTypeWrapper(i, 2);
|
||||
TypeWrapper src_type = ma.GetStackTypeWrapper(i, 4);
|
||||
if(!dst_type.IsUnloadable && dst_type.IsArray && dst_type == src_type)
|
||||
{
|
||||
switch(dst_type.Name[1])
|
||||
|
@ -1675,7 +1681,7 @@ class Compiler
|
|||
{
|
||||
if(!stackfix[j])
|
||||
{
|
||||
TypeWrapper stacktype = ma.GetRawStackTypeWrapper(i, argcount + 1 + j);
|
||||
TypeWrapper stacktype = ma.GetStackTypeWrapper(i, argcount + 1 + j);
|
||||
// it could be another new object reference (not from current invokespecial <init>
|
||||
// instruction)
|
||||
if(stacktype == VerifierTypeWrapper.Null)
|
||||
|
@ -1763,10 +1769,21 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
if(instr.NormalizedOpCode == NormalizedByteCode.__invokespecial
|
||||
&& !method.IsPrivate) // if the method is private, we can get away with a callvirt (and not generate the stub)
|
||||
if(instr.NormalizedOpCode == NormalizedByteCode.__invokespecial)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Callvirt, GetInvokeSpecialStub(method));
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
method.EmitCall(ilGenerator);
|
||||
}
|
||||
else if(method.IsPrivate)
|
||||
{
|
||||
// if the method is private, we can get away with a callvirt (and not generate the stub)
|
||||
method.EmitCallvirt(ilGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Callvirt, GetInvokeSpecialStub(method));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1793,11 +1810,7 @@ class Compiler
|
|||
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
|
||||
{
|
||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsSignatureType);
|
||||
}
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0));
|
||||
local = UnsafeAllocTempLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
}
|
||||
|
@ -1822,11 +1835,7 @@ class Compiler
|
|||
else
|
||||
{
|
||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsSignatureType);
|
||||
}
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetStackTypeWrapper(i, 0));
|
||||
if(stackHeight != 1)
|
||||
{
|
||||
LocalBuilder local = AllocTempLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
|
@ -1852,6 +1861,10 @@ class Compiler
|
|||
{
|
||||
// since new objects aren't represented on the stack, we don't need to do anything here
|
||||
}
|
||||
else if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarg_0);
|
||||
}
|
||||
else if(type == VerifierTypeWrapper.UninitializedThis)
|
||||
{
|
||||
// any unitialized this reference has to be loaded from arg 0
|
||||
|
@ -2982,7 +2995,7 @@ class Compiler
|
|||
}
|
||||
else if(args[i].IsInterfaceOrInterfaceArray)
|
||||
{
|
||||
TypeWrapper tw = ma.GetRawStackTypeWrapper(instructionIndex, args.Length - 1 - i);
|
||||
TypeWrapper tw = ma.GetStackTypeWrapper(instructionIndex, args.Length - 1 - i);
|
||||
if(!tw.IsUnloadable && !tw.IsAssignableTo(args[i]))
|
||||
{
|
||||
needsCast = true;
|
||||
|
@ -3020,7 +3033,8 @@ class Compiler
|
|||
for(int i = firstCastArg + 1; i < args.Length; i++)
|
||||
{
|
||||
TypeWrapper tw = ma.GetRawStackTypeWrapper(instructionIndex, args.Length - 1 - i);
|
||||
if(tw != VerifierTypeWrapper.UninitializedThis)
|
||||
if(tw != VerifierTypeWrapper.UninitializedThis
|
||||
&& !VerifierTypeWrapper.IsThis(tw))
|
||||
{
|
||||
tw = args[i];
|
||||
}
|
||||
|
@ -3030,7 +3044,7 @@ class Compiler
|
|||
{
|
||||
if(!args[i].IsUnloadable && !args[i].IsGhost)
|
||||
{
|
||||
TypeWrapper tw = ma.GetRawStackTypeWrapper(instructionIndex, args.Length - 1 - i);
|
||||
TypeWrapper tw = ma.GetStackTypeWrapper(instructionIndex, args.Length - 1 - i);
|
||||
if(tw.IsUnloadable || (args[i].IsInterfaceOrInterfaceArray && !tw.IsAssignableTo(args[i])))
|
||||
{
|
||||
EmitHelper.EmitAssertType(ilGenerator, args[i].TypeAsTBD);
|
||||
|
@ -3251,7 +3265,8 @@ class Compiler
|
|||
// TODO this method should have a better name
|
||||
private TypeWrapper SigTypeToClassName(TypeWrapper type, TypeWrapper nullType)
|
||||
{
|
||||
if(type == VerifierTypeWrapper.UninitializedThis)
|
||||
if(type == VerifierTypeWrapper.UninitializedThis
|
||||
|| VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
|
|
|
@ -434,6 +434,14 @@ class InstructionState
|
|||
{
|
||||
return VerifierTypeWrapper.Invalid;
|
||||
}
|
||||
if(VerifierTypeWrapper.IsThis(type1))
|
||||
{
|
||||
type1 = ((VerifierTypeWrapper)type1).UnderlyingType;
|
||||
}
|
||||
if(VerifierTypeWrapper.IsThis(type2))
|
||||
{
|
||||
type2 = ((VerifierTypeWrapper)type2).UnderlyingType;
|
||||
}
|
||||
if(type1.IsUnloadable || type2.IsUnloadable)
|
||||
{
|
||||
return VerifierTypeWrapper.Unloadable;
|
||||
|
@ -820,6 +828,10 @@ class InstructionState
|
|||
{
|
||||
stackEnd++;
|
||||
}
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
type = ((VerifierTypeWrapper)type).UnderlyingType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -993,7 +1005,12 @@ struct StackState
|
|||
{
|
||||
throw new VerifyError("Unable to pop operand off an empty stack");
|
||||
}
|
||||
return state.GetStackByIndex(sp - 1);
|
||||
TypeWrapper type = state.GetStackByIndex(sp - 1);
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
type = ((VerifierTypeWrapper)type).UnderlyingType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
internal TypeWrapper PopAnyType()
|
||||
|
@ -1002,7 +1019,12 @@ struct StackState
|
|||
{
|
||||
throw new VerifyError("Unable to pop operand off an empty stack");
|
||||
}
|
||||
return state.GetStackByIndex(--sp);
|
||||
TypeWrapper type = state.GetStackByIndex(--sp);
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
type = ((VerifierTypeWrapper)type).UnderlyingType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
internal TypeWrapper PopType(TypeWrapper baseType)
|
||||
|
@ -1114,7 +1136,7 @@ class VerifierTypeWrapper : TypeWrapper
|
|||
{
|
||||
internal static readonly TypeWrapper Invalid = null;
|
||||
internal static readonly TypeWrapper Null = new VerifierTypeWrapper("null", 0, null);
|
||||
internal static readonly TypeWrapper UninitializedThis = new VerifierTypeWrapper("this", 0, null);
|
||||
internal static readonly TypeWrapper UninitializedThis = new VerifierTypeWrapper("uninitialized-this", 0, null);
|
||||
internal static readonly TypeWrapper Unloadable = new UnloadableTypeWrapper("<verifier>");
|
||||
|
||||
private int index;
|
||||
|
@ -1143,6 +1165,16 @@ class VerifierTypeWrapper : TypeWrapper
|
|||
return new VerifierTypeWrapper("ret", bytecodeIndex, null);
|
||||
}
|
||||
|
||||
// NOTE the "this" type is special, it can only exist in local[0] and on the stack
|
||||
// as soon as the type on the stack is merged or popped it turns into its underlying type.
|
||||
// It exists to capture the verification rules for non-virtual base class method invocation in .NET 2.0,
|
||||
// which requires that the invocation is done on a "this" reference that was directly loaded onto the
|
||||
// stack (using ldarg_0).
|
||||
internal static TypeWrapper MakeThis(TypeWrapper type)
|
||||
{
|
||||
return new VerifierTypeWrapper("this", 0, type);
|
||||
}
|
||||
|
||||
internal static bool IsNew(TypeWrapper w)
|
||||
{
|
||||
return w != null && w.IsVerifierType && w.Name == "new";
|
||||
|
@ -1158,6 +1190,11 @@ class VerifierTypeWrapper : TypeWrapper
|
|||
return w == Null || w.IsUnloadable;
|
||||
}
|
||||
|
||||
internal static bool IsThis(TypeWrapper w)
|
||||
{
|
||||
return w != null && w.IsVerifierType && w.Name == "this";
|
||||
}
|
||||
|
||||
internal int Index
|
||||
{
|
||||
get
|
||||
|
@ -1353,9 +1390,11 @@ class MethodAnalyzer
|
|||
|
||||
// start by computing the initial state, the stack is empty and the locals contain the arguments
|
||||
state[0] = new InstructionState(method.MaxLocals, method.MaxStack);
|
||||
TypeWrapper thisType;
|
||||
int firstNonArgLocalIndex = 0;
|
||||
if(!method.IsStatic)
|
||||
{
|
||||
thisType = VerifierTypeWrapper.MakeThis(wrapper);
|
||||
// this reference. If we're a constructor, the this reference is uninitialized.
|
||||
if(method.Name == "<init>")
|
||||
{
|
||||
|
@ -1364,9 +1403,13 @@ class MethodAnalyzer
|
|||
}
|
||||
else
|
||||
{
|
||||
state[0].SetLocalType(firstNonArgLocalIndex++, wrapper, -1);
|
||||
state[0].SetLocalType(firstNonArgLocalIndex++, thisType, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thisType = null;
|
||||
}
|
||||
// mw can be null when we're invoked from IsSideEffectFreeStaticInitializer
|
||||
TypeWrapper[] argTypeWrappers = mw == null ? TypeWrapper.EmptyArray : mw.GetParameters();
|
||||
for(int i = 0; i < argTypeWrappers.Length; i++)
|
||||
|
@ -1766,6 +1809,10 @@ class MethodAnalyzer
|
|||
// are now initialized
|
||||
if(type == VerifierTypeWrapper.UninitializedThis)
|
||||
{
|
||||
if(s.GetLocalTypeEx(0) == type)
|
||||
{
|
||||
s.SetLocalType(0, thisType, i);
|
||||
}
|
||||
s.MarkInitialized(type, wrapper, i);
|
||||
s.SetUnitializedThis(false);
|
||||
}
|
||||
|
@ -2667,7 +2714,7 @@ class MethodAnalyzer
|
|||
{
|
||||
LocalVar v = new LocalVar();
|
||||
v.local = instructions[i].NormalizedArg1;
|
||||
v.type = GetRawStackTypeWrapper(i, 0);
|
||||
v.type = GetStackTypeWrapper(i, 0);
|
||||
v.FindLvtEntry(method, i);
|
||||
locals.Add(v);
|
||||
localByStoreSite.Add(i + ":" + v.local, v);
|
||||
|
@ -2879,6 +2926,7 @@ class MethodAnalyzer
|
|||
instr.PatchOpCode(NormalizedByteCode.__dynamic_invokevirtual);
|
||||
break;
|
||||
case NormalizedByteCode.__invokespecial:
|
||||
// TODO support dynamically instantiating an unloadable type
|
||||
instr.SetHardError(HardError.LinkageError, AllocErrorMessage("Base class no longer loadable"));
|
||||
break;
|
||||
default:
|
||||
|
@ -3174,7 +3222,7 @@ class MethodAnalyzer
|
|||
else
|
||||
{
|
||||
Debug.Assert(IsStoreLocal(method.Instructions[store].NormalizedOpCode));
|
||||
type = InstructionState.FindCommonBaseType(type, GetRawStackTypeWrapper(store, 0));
|
||||
type = InstructionState.FindCommonBaseType(type, GetStackTypeWrapper(store, 0));
|
||||
}
|
||||
}
|
||||
// we can't have an invalid type, because that would have failed verification earlier
|
||||
|
@ -3206,7 +3254,14 @@ class MethodAnalyzer
|
|||
{
|
||||
local = new LocalVar();
|
||||
local.local = localIndex;
|
||||
local.type = type;
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
local.type = ((VerifierTypeWrapper)type).UnderlyingType;
|
||||
}
|
||||
else
|
||||
{
|
||||
local.type = type;
|
||||
}
|
||||
local.isArg = isArg;
|
||||
if(JVM.Debug)
|
||||
{
|
||||
|
@ -3359,6 +3414,16 @@ class MethodAnalyzer
|
|||
return state[index].GetStackHeight();
|
||||
}
|
||||
|
||||
internal TypeWrapper GetStackTypeWrapper(int index, int pos)
|
||||
{
|
||||
TypeWrapper type = state[index].GetStackSlot(pos);
|
||||
if(VerifierTypeWrapper.IsThis(type))
|
||||
{
|
||||
type = ((VerifierTypeWrapper)type).UnderlyingType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
internal TypeWrapper GetRawStackTypeWrapper(int index, int pos)
|
||||
{
|
||||
return state[index].GetStackSlot(pos);
|
||||
|
|
|
@ -670,8 +670,11 @@ namespace IKVM.Internal
|
|||
AttributeHelper.SetSourceFile(moduleBuilder, null);
|
||||
}
|
||||
AttributeHelper.SetJavaModule(moduleBuilder);
|
||||
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, JVM.Debug });
|
||||
assemblyBuilder.SetCustomAttribute(debugAttr);
|
||||
if(JVM.Debug || !JVM.NoStackTraceInfo)
|
||||
{
|
||||
CustomAttributeBuilder debugAttr = new CustomAttributeBuilder(typeof(DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new object[] { true, JVM.Debug });
|
||||
assemblyBuilder.SetCustomAttribute(debugAttr);
|
||||
}
|
||||
return moduleBuilder;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче