Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

using Internal.TypeSystem;

#if !ILTRIM
using TokenMap = System.Func<System.Reflection.Metadata.EntityHandle, System.Reflection.Metadata.EntityHandle>;
#endif

namespace ILCompiler.DependencyAnalysis
{
public struct EcmaSignatureRewriter
Expand All @@ -21,10 +25,19 @@ private EcmaSignatureRewriter(BlobReader blobReader, TokenMap tokenMap)
_tokenMap = tokenMap;
}

private EntityHandle MapToken(EntityHandle handle)
{
#if ILTRIM
return _tokenMap.MapToken(handle);
#else
return _tokenMap(handle);
#endif
}

private void RewriteCustomModifier(SignatureTypeCode typeCode, CustomModifiersEncoder encoder)
{
encoder.AddModifier(
_tokenMap.MapToken(_blobReader.ReadTypeHandle()),
MapToken(_blobReader.ReadTypeHandle()),
typeCode == SignatureTypeCode.OptionalModifier);
}

Expand All @@ -38,6 +51,10 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
again:
switch (typeCode)
{
case SignatureTypeCode.Void:
case SignatureTypeCode.TypedReference:
encoder.Builder.WriteByte((byte)typeCode);
break;
case SignatureTypeCode.Boolean:
encoder.Boolean(); break;
case SignatureTypeCode.SByte:
Expand Down Expand Up @@ -79,7 +96,7 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
byte classOrValueType = _blobReader.ReadByte();
System.Diagnostics.Debug.Assert(classOrValueType == 0x12 || classOrValueType == 0x11);
encoder.Type(
_tokenMap.MapToken(_blobReader.ReadTypeHandle()),
MapToken(_blobReader.ReadTypeHandle()),
isValueType: classOrValueType == 0x11);
}
break;
Expand Down Expand Up @@ -138,7 +155,7 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
int numGenericArgs = _blobReader.ReadCompressedInteger();

GenericTypeArgumentsEncoder genericArgsEncoder = encoder.GenericInstantiation(
_tokenMap.MapToken(genericTypeDefHandle),
MapToken(genericTypeDefHandle),
numGenericArgs,
isValueType: classOrValueType == 0x11
);
Expand All @@ -153,7 +170,10 @@ private void RewriteType(SignatureTypeCode typeCode, SignatureTypeEncoder encode
{
SignatureHeader header = _blobReader.ReadSignatureHeader();
int arity = header.IsGeneric ? _blobReader.ReadCompressedInteger() : 0;
MethodSignatureEncoder sigEncoder = encoder.FunctionPointer(header.CallingConvention, 0, arity);
FunctionPointerAttributes attributes = header.HasExplicitThis
? FunctionPointerAttributes.HasExplicitThis
: header.IsInstance ? FunctionPointerAttributes.HasThis : FunctionPointerAttributes.None;
MethodSignatureEncoder sigEncoder = encoder.FunctionPointer(header.CallingConvention, attributes, arity);
int count = _blobReader.ReadCompressedInteger();
sigEncoder.Parameters(count, out ReturnTypeEncoder retTypeEncoder, out ParametersEncoder paramEncoder);
RewriteMethodSignature(count, retTypeEncoder, paramEncoder);
Expand Down Expand Up @@ -241,8 +261,11 @@ private void RewriteMethodSignature(BlobBuilder blobBuilder)
private void RewriteMethodSignature(BlobBuilder blobBuilder, SignatureHeader header)
{
int arity = header.IsGeneric ? _blobReader.ReadCompressedInteger() : 0;
var encoder = new BlobEncoder(blobBuilder);
var sigEncoder = encoder.MethodSignature(header.CallingConvention, arity, header.IsInstance);
// Preserve all calling-convention bits, including ExplicitThis (ECMA-335 II.23.2.1).
blobBuilder.WriteByte(header.RawValue);
if (header.IsGeneric)
blobBuilder.WriteCompressedInteger(arity);
var sigEncoder = new MethodSignatureEncoder(blobBuilder, header.CallingConvention == SignatureCallingConvention.VarArgs);
RewriteMethodSignature(sigEncoder);
}

Expand All @@ -257,12 +280,11 @@ private void RewriteMethodSignature(MethodSignatureEncoder sigEncoder)

private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncoder, ParametersEncoder paramsEncoder)
{
bool isByRef = false;
againReturnType:
SignatureTypeCode typeCode = _blobReader.ReadSignatureTypeCode();
if (typeCode == SignatureTypeCode.ByReference)
{
isByRef = true;
returnTypeEncoder.Builder.WriteByte((byte)typeCode);
goto againReturnType;
}
if (typeCode == SignatureTypeCode.RequiredModifier || typeCode == SignatureTypeCode.OptionalModifier)
Expand All @@ -281,14 +303,17 @@ private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncod
}
else
{
RewriteType(typeCode, returnTypeEncoder.Type(isByRef));
RewriteType(typeCode, returnTypeEncoder.Type(isByRef: false));
}

for (int i = 0; i < count; i++)
{
ParameterTypeEncoder paramEncoder = paramsEncoder.AddParameter();
if (_blobReader.ReadByte() == (byte)SignatureTypeCode.Sentinel)
paramsEncoder = paramsEncoder.StartVarArgs();
else
_blobReader.Offset--;

isByRef = false;
ParameterTypeEncoder paramEncoder = paramsEncoder.AddParameter();

againParameter:
typeCode = _blobReader.ReadSignatureTypeCode();
Expand All @@ -299,7 +324,7 @@ private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncod
}
if (typeCode == SignatureTypeCode.ByReference)
{
isByRef = true;
paramEncoder.Builder.WriteByte((byte)typeCode);
goto againParameter;
}

Expand All @@ -309,7 +334,7 @@ private void RewriteMethodSignature(int count, ReturnTypeEncoder returnTypeEncod
}
else
{
RewriteType(typeCode, paramEncoder.Type(isByRef));
RewriteType(typeCode, paramEncoder.Type(isByRef: false));
}
}
}
Expand All @@ -330,12 +355,11 @@ private void RewriteFieldSignature(BlobBuilder blobBuilder, SignatureHeader head
var encoder = new BlobEncoder(blobBuilder);
var fieldEncoder = encoder.Field();

bool isByRef = false;
again:
SignatureTypeCode typeCode = _blobReader.ReadSignatureTypeCode();
if (typeCode == SignatureTypeCode.ByReference)
{
isByRef = true;
fieldEncoder.Builder.WriteByte((byte)typeCode);
goto again;
}
if (typeCode == SignatureTypeCode.RequiredModifier || typeCode == SignatureTypeCode.OptionalModifier)
Expand All @@ -350,7 +374,7 @@ private void RewriteFieldSignature(BlobBuilder blobBuilder, SignatureHeader head
}
else
{
RewriteType(typeCode, fieldEncoder.Type(isByRef));
RewriteType(typeCode, fieldEncoder.Type(isByRef: false));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
namespace ILCompiler.DependencyAnalysis
{
/// <summary>
/// Represents a blob of native metadata describing assemblies, the types in them, and their members.
/// The data is used at runtime to e.g. support reflection.
/// Represents concatenated ECMA-335 reflection metadata roots for experimental file-size measurements.
/// Runtime readers and mapping tables still expect NativeFormat metadata and cannot use this blob.
/// </summary>
public sealed class MetadataNode : ObjectNode, ISymbolDefinitionNode
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
namespace ILCompiler
{
/// <summary>
/// This class is responsible for managing native metadata to be emitted into the compiled
/// This class is responsible for managing reflection metadata to be emitted into the compiled
/// module. It also helps facilitate mappings between generated runtime structures or code,
/// and the native metadata.
/// </summary>
Expand All @@ -46,7 +46,8 @@ public abstract class MetadataManager : ICompilationRootProvider

protected readonly MetadataManagerOptions _options;

private byte[] _metadataBlob;
private byte[] _nativeMetadataBlob;
private byte[] _ecmaMetadataBlob;
private List<MetadataMapping<MetadataType>> _typeMappings;
private List<MetadataMapping<FieldDesc>> _fieldMappings;
private Dictionary<FieldDesc, int> _fieldHandleMap;
Expand Down Expand Up @@ -111,6 +112,8 @@ public MetadataManager(CompilerTypeSystemContext typeSystemContext, MetadataBloc

public bool IsDataDehydrated => (_options & MetadataManagerOptions.DehydrateData) != 0;

public string EcmaMetadataOutputDirectory { get; set; }

internal ObjectNode.ObjectData PrepareForDehydration(DehydratableObjectNode node, ObjectNode.ObjectData hydratedData)
{
_dehydratableData.Add((node, hydratedData));
Expand Down Expand Up @@ -710,10 +713,10 @@ public MethodDesc GetReflectionInvokeStub(MethodDesc method)

protected void EnsureMetadataGenerated(NodeFactory factory)
{
if (_metadataBlob != null)
if (_nativeMetadataBlob is not null)
return;

ComputeMetadata(factory, out _metadataBlob, out _typeMappings, out _methodMappings, out _methodHandleMap, out _fieldMappings, out _fieldHandleMap, out _stackTraceMappings, out _reflectionStackTraceMappings);
ComputeMetadata(factory, out _nativeMetadataBlob, out _typeMappings, out _methodMappings, out _methodHandleMap, out _fieldMappings, out _fieldHandleMap, out _stackTraceMappings, out _reflectionStackTraceMappings);
}

void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider)
Expand Down Expand Up @@ -817,6 +820,9 @@ protected void ComputeMetadata<TPolicy>(

metadataBlob = ms.ToArray();

_ecmaMetadataBlob = Metadata.Ecma.EcmaMetadataTransform.Run(
policy, GetCompilationModulesWithMetadata(), EcmaMetadataOutputDirectory);

const int MaxAllowedMetadataOffset = 0x1FFFFFF;
if (metadataBlob.Length > MaxAllowedMetadataOffset)
{
Expand Down Expand Up @@ -995,7 +1001,7 @@ protected StackTraceRecordData CreateStackTraceRecord(Metadata.MetadataTransform
public byte[] GetMetadataBlob(NodeFactory factory)
{
EnsureMetadataGenerated(factory);
return _metadataBlob;
return _ecmaMetadataBlob;
}

public IEnumerable<MetadataMapping<MetadataType>> GetTypeDefinitionMapping(NodeFactory factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<ItemGroup>
<ProjectReference Include="..\ILCompiler.DependencyAnalysisFramework\ILCompiler.DependencyAnalysisFramework.csproj" />
<ProjectReference Include="..\ILCompiler.Diagnostics\ILCompiler.Diagnostics.csproj" />
<ProjectReference Include="..\ILCompiler.MetadataTransform.Ecma\ILCompiler.MetadataTransform.Ecma.csproj" />
<ProjectReference Include="..\ILCompiler.MetadataTransform\ILCompiler.MetadataTransform.csproj" />
<ProjectReference Include="..\ILCompiler.TypeSystem\ILCompiler.TypeSystem.csproj" />

Expand Down
Loading
Loading