This commit is contained in:
jfrijters 2003-07-02 14:50:35 +00:00
Родитель 648f45dc3a
Коммит 0d9f6a60cc
2 изменённых файлов: 63 добавлений и 28 удалений

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

@ -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);
} }