зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
648f45dc3a
Коммит
0d9f6a60cc
|
@ -141,9 +141,58 @@ public abstract class CodeEmitter
|
||||||
internal static CodeEmitter Create(OpCode opcode, FieldInfo fi)
|
internal static CodeEmitter Create(OpCode opcode, FieldInfo fi)
|
||||||
{
|
{
|
||||||
Debug.Assert(fi != null);
|
Debug.Assert(fi != null);
|
||||||
|
Debug.Assert(!fi.IsLiteral);
|
||||||
return new FieldInfoCodeEmitter(opcode, fi);
|
return new FieldInfoCodeEmitter(opcode, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static CodeEmitter CreateLoadConstant(object constant)
|
||||||
|
{
|
||||||
|
if(constant == null)
|
||||||
|
{
|
||||||
|
return new CodeEmitter.OpCodeEmitter(OpCodes.Ldnull);
|
||||||
|
}
|
||||||
|
else if(constant is int || constant is uint ||
|
||||||
|
constant is short || constant is ushort ||
|
||||||
|
constant is byte || constant is sbyte ||
|
||||||
|
constant is char ||
|
||||||
|
constant is bool)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||||
|
}
|
||||||
|
else if(constant is string)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldstr, (string)constant);
|
||||||
|
}
|
||||||
|
else if(constant is float)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_R4, (float)constant);
|
||||||
|
}
|
||||||
|
else if(constant is double)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_R8, (double)constant);
|
||||||
|
}
|
||||||
|
else if(constant is long || constant is ulong)
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I8, (long)constant);
|
||||||
|
}
|
||||||
|
else if(constant is Enum)
|
||||||
|
{
|
||||||
|
Type underlying = Enum.GetUnderlyingType(constant.GetType());
|
||||||
|
if(underlying == typeof(long) || underlying == typeof(ulong))
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I8, ((IConvertible)constant).ToInt64(null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException(constant.GetType().FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class OpCodeEmitter : CodeEmitter
|
private class OpCodeEmitter : CodeEmitter
|
||||||
{
|
{
|
||||||
private OpCode opcode;
|
private OpCode opcode;
|
||||||
|
|
|
@ -1935,30 +1935,7 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
// NOTE even though you're not supposed to access a constant static final (the compiler is supposed
|
// 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
|
// to inline them), we have to support it (because it does happen, e.g. if the field becomes final
|
||||||
// after the referencing class was compiled)
|
// after the referencing class was compiled)
|
||||||
if(constantValue is int || constantValue is short || constantValue is sbyte || constantValue is char || constantValue is bool)
|
fields[i].EmitGet = CodeEmitter.CreateLoadConstant(constantValue);
|
||||||
{
|
|
||||||
fields[i].EmitGet = CodeEmitter.Create(OpCodes.Ldc_I4, ((IConvertible)constantValue).ToInt32(null));
|
|
||||||
}
|
|
||||||
else if(constantValue is string)
|
|
||||||
{
|
|
||||||
fields[i].EmitGet = CodeEmitter.Create(OpCodes.Ldstr, (string)constantValue);
|
|
||||||
}
|
|
||||||
else if(constantValue is float)
|
|
||||||
{
|
|
||||||
fields[i].EmitGet = CodeEmitter.Create(OpCodes.Ldc_R4, (float)constantValue);
|
|
||||||
}
|
|
||||||
else if(constantValue is double)
|
|
||||||
{
|
|
||||||
fields[i].EmitGet = CodeEmitter.Create(OpCodes.Ldc_R8, (double)constantValue);
|
|
||||||
}
|
|
||||||
else if(constantValue is long)
|
|
||||||
{
|
|
||||||
fields[i].EmitGet = CodeEmitter.Create(OpCodes.Ldc_I8, (long)constantValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException(constantValue.GetType().FullName);
|
|
||||||
}
|
|
||||||
// when non-blank final fields are updated, the JIT normally doesn't see that (because the
|
// when non-blank final fields are updated, the JIT normally doesn't see that (because the
|
||||||
// constant value is inlined), so we emulate that behavior by emitting a Pop
|
// constant value is inlined), so we emulate that behavior by emitting a Pop
|
||||||
fields[i].EmitSet = CodeEmitter.Pop;
|
fields[i].EmitSet = CodeEmitter.Pop;
|
||||||
|
@ -2142,7 +2119,9 @@ class DynamicTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
// NOTE we don't need to record the modifiers here, because they aren't visible from Java reflection
|
// NOTE we don't need to record the modifiers here, because they aren't visible from Java reflection
|
||||||
// (well they might be visible from JNI reflection, but that isn't important enough to justify the custom attribute)
|
// (well they might be visible from JNI reflection, but that isn't important enough to justify the custom attribute)
|
||||||
method = typeBuilder.DefineTypeInitializer();
|
// HACK because Peverify (in Whidbey) is complaining about private methods in interfaces, I'm making them public for the time being
|
||||||
|
method = typeBuilder.DefineConstructor(MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
|
||||||
|
//method = typeBuilder.DefineTypeInitializer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3497,10 +3476,17 @@ class CompiledTypeWrapper : TypeWrapper
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO if field is a literal, we should emit an ldc instead of a ldsfld
|
// if field is a literal, we emit an ldc instead of a ldsfld
|
||||||
fieldWrapper.EmitGet = CodeEmitter.Create(OpCodes.Ldsfld, field);
|
if(field.IsLiteral)
|
||||||
|
{
|
||||||
|
fieldWrapper.EmitGet = CodeEmitter.CreateLoadConstant(field.GetValue(null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldWrapper.EmitGet = CodeEmitter.Create(OpCodes.Ldsfld, field);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(field != null)
|
if(field != null && !field.IsLiteral)
|
||||||
{
|
{
|
||||||
fieldWrapper.EmitSet = CodeEmitter.Create(OpCodes.Stsfld, field);
|
fieldWrapper.EmitSet = CodeEmitter.Create(OpCodes.Stsfld, field);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче