Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2015-12-01 10:12:23 +0300
committerJan Kotas <jkotas@microsoft.com>2015-12-22 02:57:17 +0300
commit0fd800466452d74c011f602c79bca1c8b318ed18 (patch)
treeaae76724c51da726baa946621a0ca8e3988842fd /src/ILCompiler.Compiler
parentd4023eecf7fcc7306802f3d0363ea96837579217 (diff)
Remove CoreRT TODOs in Buffer.CopyBlock and Array.Copy
- Respect explicit layout and emit proper EEType flags in CppCodeGen - required for "Hello world" with TODOs removed - Reduce dependencies of autogenerated files for CppCodeGen
Diffstat (limited to 'src/ILCompiler.Compiler')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs113
-rw-r--r--src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs123
-rw-r--r--src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs6
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj2
4 files changed, 99 insertions, 145 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
index 8778a7587..a06978347 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -217,127 +217,20 @@ namespace ILCompiler.DependencyAnalysis
private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
{
+ UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);
+
// Todo: RelatedTypeViaIATFlag when we support cross-module EETypes
// Todo: GenericVarianceFlag when we support variance
// Todo: Generic Type Definition EETypes
- UInt16 flags = (UInt16)EETypeKind.CanonicalEEType;
-
- if (_type.IsArray || _type.IsPointer)
- {
- flags = (UInt16)EETypeKind.ParameterizedEEType;
- }
-
- if (_type.IsValueType)
- {
- flags |= (UInt16)EETypeFlags.ValueTypeFlag;
- }
-
- if (_type.HasFinalizer)
- {
- flags |= (UInt16)EETypeFlags.HasFinalizerFlag;
- }
-
- if (_type is MetadataType && ((MetadataType)_type).ContainsPointers)
- {
- flags |= (UInt16)EETypeFlags.HasPointersFlag;
- }
- else if (_type.IsArray)
- {
- ArrayType arrayType = _type as ArrayType;
- if ((arrayType.ElementType.IsValueType && ((DefType)arrayType.ElementType).ContainsPointers) ||
- !arrayType.ElementType.IsValueType)
- {
- flags |= (UInt16)EETypeFlags.HasPointersFlag;
- }
- }
-
- if (_type.IsInterface)
- {
- flags |= (UInt16)EETypeFlags.IsInterfaceFlag;
- }
-
- if (_type.HasInstantiation)
- {
- flags |= (UInt16)EETypeFlags.IsGenericFlag;
- }
-
if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
{
flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
}
- int corElementType = 0;
-
- // The top 5 bits of flags are used to convey enum underlying type, primitive type, or mark the type as being System.Array
- if (_type.IsEnum)
- {
- TypeDesc underlyingType = _type.UnderlyingType;
- Debug.Assert(TypeFlags.SByte <= underlyingType.Category && underlyingType.Category <= TypeFlags.UInt64);
- corElementType = ComputeRhCorElementType(underlyingType);
- }
- else if (_type.IsPrimitive)
- {
- corElementType = ComputeRhCorElementType(_type);
- }
- else if (_type.IsArray)
- {
- corElementType = 0x14; // ELEMENT_TYPE_ARRAY
- }
-
- if (corElementType > 0)
- {
- flags |= (UInt16)(corElementType << (UInt16)EETypeFlags.CorElementTypeShift);
- }
-
objData.EmitShort((short)flags);
}
- private static int ComputeRhCorElementType(TypeDesc type)
- {
- Debug.Assert(type.IsPrimitive);
- Debug.Assert(type.Category != TypeFlags.Unknown);
-
- switch (type.Category)
- {
- case TypeFlags.Void:
- return 0x00;
- case TypeFlags.Boolean:
- return 0x02;
- case TypeFlags.Char:
- return 0x03;
- case TypeFlags.SByte:
- return 0x04;
- case TypeFlags.Byte:
- return 0x05;
- case TypeFlags.Int16:
- return 0x06;
- case TypeFlags.UInt16:
- return 0x07;
- case TypeFlags.Int32:
- return 0x08;
- case TypeFlags.UInt32:
- return 0x09;
- case TypeFlags.Int64:
- return 0x0A;
- case TypeFlags.UInt64:
- return 0x0B;
- case TypeFlags.IntPtr:
- return 0x18;
- case TypeFlags.UIntPtr:
- return 0x19;
- case TypeFlags.Single:
- return 0x0C;
- case TypeFlags.Double:
- return 0x0D;
- default:
- break;
- }
-
- Debug.Assert(false, "Primitive type value expected.");
- return 0;
- }
-
private static bool ComputeRequiresAlign8(TypeDesc type)
{
if (type.Context.Target.Architecture != TargetArchitecture.ARM)
@@ -627,7 +520,7 @@ namespace ILCompiler.DependencyAnalysis
Debug.Assert(defType != null);
uint valueTypeFieldPadding = checked((uint)(defType.InstanceByteCount - defType.InstanceByteCountUnaligned));
- uint valueTypeFieldPaddingEncoded = EEType.ComputeValueTypeFieldPaddingFieldValue(valueTypeFieldPadding, (uint)defType.InstanceFieldAlignment);
+ uint valueTypeFieldPaddingEncoded = EETypeBuilderHelpers.ComputeValueTypeFieldPaddingFieldValue(valueTypeFieldPadding, (uint)defType.InstanceFieldAlignment);
if (valueTypeFieldPaddingEncoded != 0)
{
diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs
index 4b3cb7b14..2808f29c9 100644
--- a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs
+++ b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.Globalization;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -13,6 +14,8 @@ using ILCompiler.DependencyAnalysisFramework;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
+using Internal.Runtime;
+
using Internal.IL;
using ILCompiler.DependencyAnalysis;
@@ -612,30 +615,9 @@ namespace ILCompiler.CppCodeGen
{
Out.WriteLine(GetCodeForDelegate(t));
}
- foreach (var field in t.GetFields())
- {
- if (field.IsStatic)
- {
- TypeDesc fieldType = GetFieldTypeOrPlaceholder(field);
- StringBuilder builder;
- if (!fieldType.IsValueType)
- {
- _gcStatics.Append(GetCppSignatureTypeName(fieldType));
- builder = _gcStatics;
- }
- else
- {
- // TODO: Valuetype statics with GC references
- _statics.Append(GetCppSignatureTypeName(fieldType));
- builder = _statics;
- }
- builder.AppendLine(" " + GetCppStaticFieldName(field) + ";");
- }
- else
- {
- Out.WriteLine(GetCppSignatureTypeName(GetFieldTypeOrPlaceholder(field)) + " " + GetCppFieldName(field) + ";");
- }
- }
+
+ OutputTypeFields(t);
+
if (t.HasStaticConstructor)
{
_statics.AppendLine("bool __cctor_" + GetCppTypeName(t).Replace("::", "__") + ";");
@@ -664,6 +646,67 @@ namespace ILCompiler.CppCodeGen
Out.WriteLine();
}
+ private void OutputTypeFields(TypeDesc t)
+ {
+ bool explicitLayout = false;
+ ClassLayoutMetadata classLayoutMetadata = default(ClassLayoutMetadata);
+
+ if (t.IsValueType)
+ {
+ MetadataType metadataType = (MetadataType)t;
+ if (metadataType.IsExplicitLayout)
+ {
+ explicitLayout = true;
+ classLayoutMetadata = metadataType.GetClassLayout();
+ }
+ }
+
+ int instanceFieldIndex = 0;
+
+ if (explicitLayout)
+ Out.WriteLine("union {");
+
+ foreach (var field in t.GetFields())
+ {
+ if (field.IsStatic)
+ {
+ TypeDesc fieldType = GetFieldTypeOrPlaceholder(field);
+ StringBuilder builder;
+ if (!fieldType.IsValueType)
+ {
+ _gcStatics.Append(GetCppSignatureTypeName(fieldType));
+ builder = _gcStatics;
+ }
+ else
+ {
+ // TODO: Valuetype statics with GC references
+ _statics.Append(GetCppSignatureTypeName(fieldType));
+ builder = _statics;
+ }
+ builder.AppendLine(" " + GetCppStaticFieldName(field) + ";");
+ }
+ else
+ {
+ if (explicitLayout)
+ {
+ Out.WriteLine("struct {");
+ int offset = classLayoutMetadata.Offsets[instanceFieldIndex].Offset;
+ if (offset > 0)
+ Out.WriteLine("char __pad" + instanceFieldIndex + "[" + offset + "];");
+ }
+ Out.WriteLine(GetCppSignatureTypeName(GetFieldTypeOrPlaceholder(field)) + " " + GetCppFieldName(field) + ";");
+ if (explicitLayout)
+ {
+ Out.WriteLine("};");
+ }
+ instanceFieldIndex++;
+ }
+ }
+
+ if (explicitLayout)
+ Out.WriteLine("};");
+ }
+
private void OutputMethod(MethodDesc m)
{
Out.WriteLine(GetCppMethodDeclaration(m, false));
@@ -803,6 +846,17 @@ namespace ILCompiler.CppCodeGen
t = t.BaseType;
}
+ UInt16 flags = 0;
+ try
+ {
+ flags = EETypeBuilderHelpers.ComputeFlags(type);
+ }
+ catch
+ {
+ // TODO: Handling of missing dependencies
+ flags = 0;
+ }
+
sb.Append("MethodTable * ");
sb.Append(GetCppTypeName(type));
sb.AppendLine("::__getMethodTable() {");
@@ -821,30 +875,37 @@ namespace ILCompiler.CppCodeGen
if (type.IsString)
{
// String has non-standard layout
- // component size = 2, flags = 0, base size = 2 ptrs + dword + first char
- sb.Append("{ sizeof(uint16_t), 0, 2 * sizeof(void*) + sizeof(int32_t) + 2, ");
+ sb.Append("{ sizeof(uint16_t), 0x"); // EEType::_usComponentSize
+ sb.Append(flags.ToString("x4", CultureInfo.InvariantCulture)); // EEType::_usFlags
+ sb.Append(", 2 * sizeof(void*) + sizeof(int32_t) + 2, "); // EEType::_uBaseSize
}
else
if (type.IsArray && ((ArrayType)type).Rank == 1)
{
sb.Append("{ sizeof(");
- sb.Append(GetCppSignatureTypeName(((ArrayType)type).ElementType)); // component size
- sb.Append("), 4 /* MTFlag_IsArray */, 3 * sizeof(void*), "); // flags, baseSize
+ sb.Append(GetCppSignatureTypeName(((ArrayType)type).ElementType)); // EEType::_usComponentSize
+ sb.Append("), 0x");
+ sb.Append(flags.ToString("x4", CultureInfo.InvariantCulture)); // EEType::_usFlags
+ sb.Append(", 3 * sizeof(void*), "); // EEType::_uBaseSize
}
else
if (type.IsArray)
{
Debug.Assert(((ArrayType)type).Rank > 1);
sb.Append("{ sizeof(");
- sb.Append(GetCppSignatureTypeName(((ArrayType)type).ElementType)); // component size
- sb.Append("), 4 /* MTFlag_IsArray */, 3 * sizeof(void*) + "); // flags, baseSize
+ sb.Append(GetCppSignatureTypeName(((ArrayType)type).ElementType)); // EEType::_usComponentSize
+ sb.Append("), 0x");
+ sb.Append(flags.ToString("x4", CultureInfo.InvariantCulture)); // EEType::_usFlags
+ sb.Append(", 3 * sizeof(void*) + "); // EEType::_uBaseSize
sb.Append(((ArrayType)type).Rank.ToString());
sb.Append("* sizeof(int32_t) * 2, ");
}
else
{
// sizeof(void*) == size of object header
- sb.Append("{ 0, 0, AlignBaseSize(sizeof(void*)+sizeof("); // component size, flags, baseSize
+ sb.Append("{ 0, 0x"); // EEType::_usComponentSize
+ sb.Append(flags.ToString("x", CultureInfo.InvariantCulture)); // EEType::_usFlags
+ sb.Append(", AlignBaseSize(sizeof(void*)+sizeof("); // EEType::_uBaseSize
sb.Append(GetCppTypeName(type));
sb.Append(")), ");
}
diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
index c10e3629e..4a864fe6b 100644
--- a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
+++ b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
@@ -946,7 +946,7 @@ namespace Internal.IL
thisArgument = thisArgument.MakeByRefType();
}
- string typeDefName = "__calli__" + token.ToString("X8", CultureInfo.InvariantCulture);
+ string typeDefName = "__calli__" + token.ToString("x8", CultureInfo.InvariantCulture);
_writer.AppendSignatureTypeDef(_builder, typeDefName, methodSignature, thisArgument);
TypeDesc retType = methodSignature.ReturnType;
@@ -1016,14 +1016,14 @@ namespace Internal.IL
if (value == Int64.MinValue)
val = "(int64_t)(0x8000000000000000" + (_msvc ? "i64" : "LL") + ")";
else
- val = value.ToString() + (_msvc ? "i64" : "LL");
+ val = value.ToString(CultureInfo.InvariantCulture) + (_msvc ? "i64" : "LL");
}
else
{
if (value == Int32.MinValue)
val = "(int32_t)(0x80000000)";
else
- val = ((int)value).ToString();
+ val = ((int)value).ToString(CultureInfo.InvariantCulture);
}
Push(kind, new Value(val));
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index d0091a8f7..43af2acab 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -89,7 +89,7 @@
<Compile Include="..\..\Common\src\Internal\Runtime\EETypeOptionalFieldsBuilder.cs">
<Link>Common\EETypeOptionalFieldsBuilder.cs</Link>
</Compile>
- <Compile Include="..\..\Common\src\Internal\Runtime\EEType.cs">
+ <Compile Include="..\..\Common\src\Internal\Runtime\EETypeBuilderHelpers.cs">
<Link>Common\EEType.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\Internal\NativeFormat\NativeFormatWriter.Primitives.cs">