Static = 0x0010,
}
+ public enum EmbeddedSignatureDataKind
+ {
+ RequiredCustomModifier = 0,
+ OptionalCustomModifier = 1
+ }
+
+ public struct EmbeddedSignatureData
+ {
+ public string index;
+ public EmbeddedSignatureDataKind kind;
+ public TypeDesc type;
+ }
+
/// <summary>
/// Represents the parameter types, the return type, and flags of a method.
/// </summary>
internal int _genericParameterCount;
internal TypeDesc _returnType;
internal TypeDesc[] _parameters;
+ internal EmbeddedSignatureData[] _embeddedSignatureData;
- public MethodSignature(MethodSignatureFlags flags, int genericParameterCount, TypeDesc returnType, TypeDesc[] parameters)
+ public MethodSignature(MethodSignatureFlags flags, int genericParameterCount, TypeDesc returnType, TypeDesc[] parameters, EmbeddedSignatureData[] embeddedSignatureData = null)
{
_flags = flags;
_genericParameterCount = genericParameterCount;
_returnType = returnType;
_parameters = parameters;
+ _embeddedSignatureData = embeddedSignatureData;
Debug.Assert(parameters != null, "Parameters must not be null");
}
return false;
}
- return true;
+ if (this._embeddedSignatureData == null && otherSignature._embeddedSignatureData == null)
+ {
+ return true;
+ }
+
+ if (this._embeddedSignatureData != null && otherSignature._embeddedSignatureData != null)
+ {
+ if (this._embeddedSignatureData.Length != otherSignature._embeddedSignatureData.Length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < this._embeddedSignatureData.Length; i++)
+ {
+ if (this._embeddedSignatureData[i].index != otherSignature._embeddedSignatureData[i].index)
+ return false;
+ if (this._embeddedSignatureData[i].kind != otherSignature._embeddedSignatureData[i].kind)
+ return false;
+ if (this._embeddedSignatureData[i].type != otherSignature._embeddedSignatureData[i].type)
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
}
public override bool Equals(object obj)
private int _genericParameterCount;
private TypeDesc _returnType;
private TypeDesc[] _parameters;
+ private EmbeddedSignatureData[] _customModifiers;
public MethodSignatureBuilder(MethodSignature template)
{
_genericParameterCount = template._genericParameterCount;
_returnType = template._returnType;
_parameters = template._parameters;
+ _customModifiers = template._embeddedSignatureData;
}
public MethodSignatureFlags Flags
_returnType != _template._returnType ||
_parameters != _template._parameters)
{
- _template = new MethodSignature(_flags, _genericParameterCount, _returnType, _parameters);
+ _template = new MethodSignature(_flags, _genericParameterCount, _returnType, _parameters, _customModifiers);
}
return _template;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Diagnostics;
+using System.Linq;
using Internal.TypeSystem;
+using System.Collections.Generic;
namespace Internal.TypeSystem.Ecma
{
private EcmaModule _module;
private BlobReader _reader;
- // TODO
- // bool _hasModifiers;
+ private Stack<int> _indexStack;
+ private List<EmbeddedSignatureData> _embeddedSignatureDataList;
+
public EcmaSignatureParser(EcmaModule module, BlobReader reader)
{
_module = module;
_reader = reader;
+ _indexStack = null;
+ _embeddedSignatureDataList = null;
}
private TypeDesc GetWellKnownType(WellKnownType wellKnownType)
private TypeDesc ParseType(SignatureTypeCode typeCode)
{
+
+ if (_indexStack != null)
+ {
+ int was = _indexStack.Pop();
+ _indexStack.Push(was + 1);
+ _indexStack.Push(0);
+ }
+ TypeDesc result = ParseTypeImpl(typeCode);
+ if (_indexStack != null)
+ {
+ _indexStack.Pop();
+ }
+ return result;
+ }
+
+ private TypeDesc ParseTypeImpl(SignatureTypeCode typeCode)
+ {
// Switch on the type.
switch (typeCode)
{
case SignatureTypeCode.TypedReference:
return GetWellKnownType(WellKnownType.TypedReference);
case SignatureTypeCode.FunctionPointer:
- return _module.Context.GetFunctionPointerType(ParseMethodSignature());
+ return _module.Context.GetFunctionPointerType(ParseMethodSignatureInternal(skipEmbeddedSignatureData: true));
default:
throw new BadImageFormatException();
}
private SignatureTypeCode ParseTypeCode(bool skipPinned = true)
{
- for (;;)
+ if (_indexStack != null)
+ {
+ int was = _indexStack.Pop();
+ _indexStack.Push(was + 1);
+ _indexStack.Push(0);
+ }
+ SignatureTypeCode result = ParseTypeCodeImpl(skipPinned);
+ if (_indexStack != null)
+ {
+ _indexStack.Pop();
+ }
+ return result;
+ }
+
+ private SignatureTypeCode ParseTypeCodeImpl(bool skipPinned = true)
+ {
+ for (; ; )
{
SignatureTypeCode typeCode = _reader.ReadSignatureTypeCode();
- // TODO: actually consume modopts
- if (typeCode == SignatureTypeCode.RequiredModifier ||
- typeCode == SignatureTypeCode.OptionalModifier)
+ if (typeCode == SignatureTypeCode.RequiredModifier)
+ {
+ EntityHandle typeHandle = _reader.ReadTypeHandle();
+ if (_embeddedSignatureDataList != null)
+ {
+ _embeddedSignatureDataList.Add(new EmbeddedSignatureData { index = string.Join(".", _indexStack), kind = EmbeddedSignatureDataKind.RequiredCustomModifier, type = _module.GetType(typeHandle) });
+ }
+ continue;
+ }
+
+ if (typeCode == SignatureTypeCode.OptionalModifier)
{
- _reader.ReadTypeHandle();
+ EntityHandle typeHandle = _reader.ReadTypeHandle();
+ if (_embeddedSignatureDataList != null)
+ {
+ _embeddedSignatureDataList.Add(new EmbeddedSignatureData { index = string.Join(".", _indexStack), kind = EmbeddedSignatureDataKind.OptionalCustomModifier, type = _module.GetType(typeHandle) });
+ }
continue;
}
public TypeDesc ParseType()
{
+ if (_indexStack != null)
+ {
+ int was = _indexStack.Pop();
+ _indexStack.Push(was + 1);
+ _indexStack.Push(0);
+ }
+ TypeDesc result = ParseTypeImpl();
+ if (_indexStack != null)
+ {
+ _indexStack.Pop();
+ }
+ return result;
+ }
+
+ private TypeDesc ParseTypeImpl()
+ {
return ParseType(ParseTypeCode());
}
public MethodSignature ParseMethodSignature()
{
+ try
+ {
+ _indexStack = new Stack<int>();
+ _indexStack.Push(0);
+ _embeddedSignatureDataList = new List<EmbeddedSignatureData>();
+ return ParseMethodSignatureInternal(skipEmbeddedSignatureData: false);
+ }
+ finally
+ {
+ _indexStack = null;
+ _embeddedSignatureDataList = null;
+ }
+
+ }
+
+ private MethodSignature ParseMethodSignatureInternal(bool skipEmbeddedSignatureData)
+ {
+ if (_indexStack != null)
+ {
+ int was = _indexStack.Pop();
+ _indexStack.Push(was + 1);
+ _indexStack.Push(0);
+ }
+ MethodSignature result = ParseMethodSignatureImpl(skipEmbeddedSignatureData);
+ if (_indexStack != null)
+ {
+ _indexStack.Pop();
+ }
+ return result;
+ }
+
+ private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData)
+ {
SignatureHeader header = _reader.ReadSignatureHeader();
MethodSignatureFlags flags = 0;
parameters = TypeDesc.EmptyTypes;
}
- return new MethodSignature(flags, arity, returnType, parameters);
+ EmbeddedSignatureData[] embeddedSignatureDataArray = (_embeddedSignatureDataList == null || _embeddedSignatureDataList.Count == 0 || skipEmbeddedSignatureData) ? null : _embeddedSignatureDataList.ToArray();
+
+ return new MethodSignature(flags, arity, returnType, parameters, embeddedSignatureDataArray);
+
}
public PropertySignature ParsePropertySignature()