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:
authorDavid Wrighton <davidwr@microsoft.com>2017-09-28 20:52:29 +0300
committerDavid Wrighton <davidwr@microsoft.com>2017-09-28 20:52:29 +0300
commit60422e48ddb2bbee2ad054b6c4fb3aa3ace0b36d (patch)
tree8c8176f07848e70811afb191db48a1549028624b
parent5eaf07fe20d985b8535552d5a6464aee04efd4bd (diff)
Refactor ecma signature encoding logic out of ManagedBinaryEmitter
- Create signature encoder that is useable with multiple sources of valid tokens [tfs-changeset: 1676780]
-rw-r--r--src/Common/src/TypeSystem/Ecma/EcmaSignatureEncoder.cs184
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/ManagedBinaryEmitter.cs158
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj5
3 files changed, 203 insertions, 144 deletions
diff --git a/src/Common/src/TypeSystem/Ecma/EcmaSignatureEncoder.cs b/src/Common/src/TypeSystem/Ecma/EcmaSignatureEncoder.cs
new file mode 100644
index 000000000..3a1d2ac67
--- /dev/null
+++ b/src/Common/src/TypeSystem/Ecma/EcmaSignatureEncoder.cs
@@ -0,0 +1,184 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Immutable;
+using System.Reflection;
+using System.Reflection.Metadata.Ecma335;
+using System.Reflection.Metadata;
+
+using Internal.TypeSystem;
+
+namespace Internal.TypeSystem.Ecma
+{
+ public interface IEntityHandleProvider
+ {
+ /// Implement to allow EcmaSignatureEncoder to encode types that need metadata references to be resolved.
+ /// only used to express non-generic references
+ EntityHandle GetTypeDefOrRefHandleForTypeDesc(TypeDesc type);
+ }
+
+ public class EcmaSignatureEncoder<TEntityHandleProvider> where TEntityHandleProvider : IEntityHandleProvider
+ {
+ TEntityHandleProvider _entityHandleProvider;
+
+ public EcmaSignatureEncoder(TEntityHandleProvider entityHandleProvider)
+ {
+ _entityHandleProvider = entityHandleProvider;
+ }
+
+ public void EncodeMethodSignature(BlobBuilder methodSignatureBlob, MethodSignature signature)
+ {
+ BlobEncoder encoder = new BlobEncoder(methodSignatureBlob);
+
+ MethodSignatureEncoder methodSigEncoder = encoder.MethodSignature(
+ SignatureCallingConvention.Default, signature.GenericParameterCount, !signature.IsStatic);
+
+ ReturnTypeEncoder returnTypeEncoder;
+ ParametersEncoder parametersEncoder;
+ methodSigEncoder.Parameters(signature.Length, out returnTypeEncoder, out parametersEncoder);
+
+ // Return Type Sig
+ EncodeTypeSignature(returnTypeEncoder.Type(), signature.ReturnType);
+
+ // Parameter Types Sig
+ for (int i = 0; i < signature.Length; i++)
+ EncodeTypeSignature(parametersEncoder.AddParameter().Type(), signature[i]);
+ }
+
+ public void EncodeTypeSignature(SignatureTypeEncoder encoder, TypeDesc type)
+ {
+ if (type is RuntimeDeterminedType)
+ {
+ EncodeTypeSignature(encoder, ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType);
+ return;
+ }
+
+ switch (type.Category)
+ {
+ case TypeFlags.Boolean:
+ encoder.Boolean(); break;
+ case TypeFlags.Byte:
+ encoder.Byte(); break;
+ case TypeFlags.SByte:
+ encoder.SByte(); break;
+ case TypeFlags.Char:
+ encoder.Char(); break;
+ case TypeFlags.Int16:
+ encoder.Int16(); break;
+ case TypeFlags.UInt16:
+ encoder.UInt16(); break;
+ case TypeFlags.Int32:
+ encoder.Int32(); break;
+ case TypeFlags.UInt32:
+ encoder.UInt32(); break;
+ case TypeFlags.Int64:
+ encoder.Int64(); break;
+ case TypeFlags.UInt64:
+ encoder.UInt64(); break;
+ case TypeFlags.Single:
+ encoder.Single(); break;
+ case TypeFlags.Double:
+ encoder.Double(); break;
+ case TypeFlags.IntPtr:
+ encoder.IntPtr(); break;
+ case TypeFlags.UIntPtr:
+ encoder.UIntPtr(); break;
+ case TypeFlags.Void:
+ encoder.Builder.WriteByte((byte)PrimitiveTypeCode.Void);
+ break;
+
+ case TypeFlags.SignatureTypeVariable:
+ encoder.GenericTypeParameter(((SignatureVariable)type).Index);
+ break;
+
+ case TypeFlags.SignatureMethodVariable:
+ encoder.GenericMethodTypeParameter(((SignatureMethodVariable)type).Index);
+ break;
+
+ case TypeFlags.GenericParameter:
+ {
+ var genericTypeDesc = (GenericParameterDesc)type;
+ if (genericTypeDesc.Kind == GenericParameterKind.Type)
+ encoder.GenericTypeParameter(genericTypeDesc.Index);
+ else
+ encoder.GenericMethodTypeParameter(genericTypeDesc.Index);
+ }
+ break;
+
+ case TypeFlags.FunctionPointer:
+ {
+ FunctionPointerType fptrType = (FunctionPointerType)type;
+ encoder.FunctionPointer(
+ SignatureCallingConvention.Default,
+ fptrType.Signature.IsStatic ? default(FunctionPointerAttributes) : FunctionPointerAttributes.HasThis,
+ fptrType.Signature.GenericParameterCount);
+
+ // Return Type Sig
+ EncodeTypeSignature(encoder, fptrType.Signature.ReturnType);
+
+ // Parameter Types Sig
+ for (int i = 0; i < fptrType.Signature.Length; i++)
+ EncodeTypeSignature(encoder, fptrType.Signature[i]);
+ }
+ break;
+
+ case TypeFlags.Array:
+ {
+ // Skip bounds and lobounds (TODO)
+ ImmutableArray<int> bounds = ImmutableArray.Create<int>();
+ ImmutableArray<int> lowerBounds = ImmutableArray.Create<int>();
+ encoder.Array(
+ elementType => EncodeTypeSignature(elementType, ((ArrayType)type).ElementType),
+ arrayShape => arrayShape.Shape(((ArrayType)type).Rank, bounds, lowerBounds));
+ }
+ break;
+
+ case TypeFlags.SzArray:
+ encoder.SZArray();
+ EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
+ break;
+
+ case TypeFlags.ByRef:
+ encoder.Builder.WriteByte((byte)SignatureTypeCode.ByReference);
+ EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
+ break;
+
+ case TypeFlags.Pointer:
+ encoder.Builder.WriteByte((byte)SignatureTypeCode.Pointer);
+ EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
+ break;
+
+ case TypeFlags.Enum:
+ case TypeFlags.Class:
+ case TypeFlags.ValueType:
+ case TypeFlags.Interface:
+ case TypeFlags.Nullable:
+ {
+ if (type == type.Context.GetWellKnownType(WellKnownType.TypedReference))
+ encoder.Builder.WriteByte((byte)PrimitiveTypeCode.TypedReference);
+ else if (type == type.Context.GetWellKnownType(WellKnownType.Object))
+ encoder.PrimitiveType(PrimitiveTypeCode.Object);
+ else if (type == type.Context.GetWellKnownType(WellKnownType.String))
+ encoder.PrimitiveType(PrimitiveTypeCode.String);
+ else if (type.HasInstantiation && !type.IsGenericDefinition)
+ {
+ encoder.GenericInstantiation(_entityHandleProvider.GetTypeDefOrRefHandleForTypeDesc(type.GetTypeDefinition()), type.Instantiation.Length, type.IsValueType);
+
+ for (int i = 0; i < type.Instantiation.Length; i++)
+ EncodeTypeSignature(encoder, type.Instantiation[i]);
+ }
+ else
+ {
+ encoder.Type(_entityHandleProvider.GetTypeDefOrRefHandleForTypeDesc(type), type.IsValueType);
+ }
+ }
+ break;
+
+ default:
+ throw new InvalidOperationException("Attempting to encode an invalid type signature.");
+ }
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/ManagedBinaryEmitter.cs b/src/ILCompiler.Compiler/src/Compiler/ManagedBinaryEmitter.cs
index f584cc03b..7e5ecbd81 100644
--- a/src/ILCompiler.Compiler/src/Compiler/ManagedBinaryEmitter.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/ManagedBinaryEmitter.cs
@@ -94,6 +94,7 @@ namespace ILCompiler
fieldList: MetadataTokens.FieldDefinitionHandle(1),
methodList: MetadataTokens.MethodDefinitionHandle(1));
+ _signatureEmitter = new EcmaSignatureEncoder<EntityProviderForEcmaSignature>(new EntityProviderForEcmaSignature(this));
}
public EmittedTypeDefinition EmitTypeDefinition(string typeName, bool isValueType)
@@ -128,7 +129,7 @@ namespace ILCompiler
public void EncodeSignatureForType(TypeDesc type, BlobBuilder blobBuilder)
{
SignatureTypeEncoder sigEncoder = new SignatureTypeEncoder(blobBuilder);
- EncodeTypeSignature(sigEncoder, type);
+ _signatureEmitter.EncodeTypeSignature(sigEncoder, type);
}
public void EmitOutputFile(string outputPath)
@@ -192,140 +193,23 @@ namespace ILCompiler
private Dictionary<MethodSignature, BlobHandle> _methodSignatureHandles = new Dictionary<MethodSignature, BlobHandle>();
private Dictionary<FieldDesc, BlobHandle> _fieldSignatureHandles = new Dictionary<FieldDesc, BlobHandle>();
- private void EncodeTypeSignature(SignatureTypeEncoder encoder, TypeDesc type)
+ private struct EntityProviderForEcmaSignature : IEntityHandleProvider
{
- if (type is RuntimeDeterminedType)
+ private ManagedBinaryEmitter _emitter;
+
+ public EntityProviderForEcmaSignature(ManagedBinaryEmitter emitter)
{
- EncodeTypeSignature(encoder, ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType);
- return;
+ _emitter = emitter;
}
- switch (type.Category)
+ public EntityHandle GetTypeDefOrRefHandleForTypeDesc(TypeDesc type)
{
- case TypeFlags.Boolean:
- encoder.Boolean(); break;
- case TypeFlags.Byte:
- encoder.Byte(); break;
- case TypeFlags.SByte:
- encoder.SByte(); break;
- case TypeFlags.Char:
- encoder.Char(); break;
- case TypeFlags.Int16:
- encoder.Int16(); break;
- case TypeFlags.UInt16:
- encoder.UInt16(); break;
- case TypeFlags.Int32:
- encoder.Int32(); break;
- case TypeFlags.UInt32:
- encoder.UInt32(); break;
- case TypeFlags.Int64:
- encoder.Int64(); break;
- case TypeFlags.UInt64:
- encoder.UInt64(); break;
- case TypeFlags.Single:
- encoder.Single(); break;
- case TypeFlags.Double:
- encoder.Double(); break;
- case TypeFlags.IntPtr:
- encoder.IntPtr(); break;
- case TypeFlags.UIntPtr:
- encoder.UIntPtr(); break;
- case TypeFlags.Void:
- encoder.Builder.WriteByte((byte)PrimitiveTypeCode.Void);
- break;
-
- case TypeFlags.SignatureTypeVariable:
- encoder.GenericTypeParameter(((SignatureVariable)type).Index);
- break;
-
- case TypeFlags.SignatureMethodVariable:
- encoder.GenericMethodTypeParameter(((SignatureMethodVariable)type).Index);
- break;
-
- case TypeFlags.GenericParameter:
- {
- var genericTypeDesc = (GenericParameterDesc)type;
- if (genericTypeDesc.Kind == GenericParameterKind.Type)
- encoder.GenericTypeParameter(genericTypeDesc.Index);
- else
- encoder.GenericMethodTypeParameter(genericTypeDesc.Index);
- }
- break;
-
- case TypeFlags.FunctionPointer:
- {
- FunctionPointerType fptrType = (FunctionPointerType)type;
- encoder.FunctionPointer(
- SignatureCallingConvention.Default,
- fptrType.Signature.IsStatic ? default(FunctionPointerAttributes) : FunctionPointerAttributes.HasThis,
- fptrType.Signature.GenericParameterCount);
-
- // Return Type Sig
- EncodeTypeSignature(encoder, fptrType.Signature.ReturnType);
-
- // Parameter Types Sig
- for (int i = 0; i < fptrType.Signature.Length; i++)
- EncodeTypeSignature(encoder, fptrType.Signature[i]);
- }
- break;
-
- case TypeFlags.Array:
- {
- // Skip bounds and lobounds (TODO)
- ImmutableArray<int> bounds = ImmutableArray.Create<int>();
- ImmutableArray<int> lowerBounds = ImmutableArray.Create<int>();
- encoder.Array(
- elementType => EncodeTypeSignature(elementType, ((ArrayType)type).ElementType),
- arrayShape => arrayShape.Shape(((ArrayType)type).Rank, bounds, lowerBounds));
- }
- break;
-
- case TypeFlags.SzArray:
- encoder.SZArray();
- EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
- break;
-
- case TypeFlags.ByRef:
- encoder.Builder.WriteByte((byte)SignatureTypeCode.ByReference);
- EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
- break;
-
- case TypeFlags.Pointer:
- encoder.Builder.WriteByte((byte)SignatureTypeCode.Pointer);
- EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
- break;
-
- case TypeFlags.Enum:
- case TypeFlags.Class:
- case TypeFlags.ValueType:
- case TypeFlags.Interface:
- case TypeFlags.Nullable:
- {
- if (type == _typeSystemContext.GetWellKnownType(WellKnownType.TypedReference))
- encoder.Builder.WriteByte((byte)PrimitiveTypeCode.TypedReference);
- else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.Object))
- encoder.PrimitiveType(PrimitiveTypeCode.Object);
- else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.String))
- encoder.PrimitiveType(PrimitiveTypeCode.String);
- else if (type.HasInstantiation && !type.IsGenericDefinition)
- {
- encoder.GenericInstantiation(MakeTypeRefOrSpecHandle(type.GetTypeDefinition()), type.Instantiation.Length, type.IsValueType);
-
- for (int i = 0; i < type.Instantiation.Length; i++)
- EncodeTypeSignature(encoder, type.Instantiation[i]);
- }
- else
- {
- encoder.Type(MakeTypeRefHandle(type), type.IsValueType);
- }
- }
- break;
-
- default:
- throw new InvalidOperationException("Attempting to encode an invalid type signature.");
+ return _emitter.MakeTypeRefHandle(type);
}
}
+ private EcmaSignatureEncoder<EntityProviderForEcmaSignature> _signatureEmitter;
+
private BlobHandle MakeSignatureHandle(MethodSignature signature)
{
BlobHandle handle;
@@ -334,19 +218,7 @@ namespace ILCompiler
{
BlobBuilder metadataSignature = new BlobBuilder();
- MethodSignatureEncoder methodSigEncoder = new BlobEncoder(metadataSignature).MethodSignature(
- SignatureCallingConvention.Default, signature.GenericParameterCount, !signature.IsStatic);
-
- ReturnTypeEncoder returnTypeEncoder;
- ParametersEncoder parametersEncoder;
- methodSigEncoder.Parameters(signature.Length, out returnTypeEncoder, out parametersEncoder);
-
- // Return Type Sig
- EncodeTypeSignature(returnTypeEncoder.Type(), signature.ReturnType);
-
- // Parameter Types Sig
- for (int i = 0; i < signature.Length; i++)
- EncodeTypeSignature(parametersEncoder.AddParameter().Type(), signature[i]);
+ _signatureEmitter.EncodeMethodSignature(metadataSignature, signature);
_methodSignatureHandles[signature] = handle = _metadataBuilder.GetOrAddBlob(metadataSignature);
}
@@ -370,7 +242,7 @@ namespace ILCompiler
BlobBuilder metadataSignature = new BlobBuilder();
SignatureTypeEncoder fieldSigEncoder = new BlobEncoder(metadataSignature).FieldSignature();
- EncodeTypeSignature(fieldSigEncoder, field.FieldType);
+ _signatureEmitter.EncodeTypeSignature(fieldSigEncoder, field.FieldType);
_fieldSignatureHandles[field] = handle = _metadataBuilder.GetOrAddBlob(metadataSignature);
}
@@ -455,7 +327,7 @@ namespace ILCompiler
if(!type.IsDefType || !type.IsTypeDefinition || type is RuntimeDeterminedType)
{
SignatureTypeEncoder sigEncoder = new SignatureTypeEncoder(new BlobBuilder());
- EncodeTypeSignature(sigEncoder, type);
+ _signatureEmitter.EncodeTypeSignature(sigEncoder, type);
handle = _metadataBuilder.AddTypeSpecification(_metadataBuilder.GetOrAddBlob(sigEncoder.Builder));
}
else
@@ -497,7 +369,7 @@ namespace ILCompiler
for (int i = 0; i < method.Instantiation.Length; i++)
{
SignatureTypeEncoder argTypeEncoder = argEncoder.AddArgument();
- EncodeTypeSignature(argTypeEncoder, method.Instantiation[i]);
+ _signatureEmitter.EncodeTypeSignature(argTypeEncoder, method.Instantiation[i]);
}
handle = _metadataBuilder.AddMethodSpecification(handle, _metadataBuilder.GetOrAddBlob(methodSpecEncoder.Builder));
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index 1e94ddbae..02763096a 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -1,4 +1,4 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="'$(IsProjectNLibrary)' != 'true'" />
<PropertyGroup>
<OutputType>Library</OutputType>
@@ -43,6 +43,9 @@
<Compile Include="..\..\Common\src\Internal\Text\Utf8StringBuilder.cs">
<Link>Common\Utf8StringBuilder.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\Ecma\EcmaSignatureEncoder.cs">
+ <Link>Ecma\EcmaSignatureEncoder.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\ILImporter.cs">
<Link>IL\ILImporter.cs</Link>
</Compile>