|
1 | | -// |
2 | | -// Copyright (c) .NET Foundation and Contributors |
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | + |
3 | 4 | // Original work from Oleg Rakhmatulin. |
4 | | -// See LICENSE file in the project root for full license information. |
5 | | -// |
6 | 5 |
|
7 | | -using Mono.Cecil; |
8 | | -using Mono.Cecil.Cil; |
9 | | -using Mono.Collections.Generic; |
10 | | -using nanoFramework.Tools.MetadataProcessor.Core.Extensions; |
11 | 6 | using System; |
12 | 7 | using System.Collections.Generic; |
13 | 8 | using System.Diagnostics; |
14 | 9 | using System.IO; |
15 | 10 | using System.Linq; |
| 11 | +using Mono.Cecil; |
| 12 | +using Mono.Cecil.Cil; |
| 13 | +using Mono.Collections.Generic; |
| 14 | +using nanoFramework.Tools.MetadataProcessor.Core.Extensions; |
16 | 15 |
|
17 | 16 | namespace nanoFramework.Tools.MetadataProcessor |
18 | 17 | { |
@@ -41,35 +40,67 @@ public int GetHashCode(byte[] that) |
41 | 40 | } |
42 | 41 | } |
43 | 42 |
|
44 | | - internal static readonly IDictionary<string, nanoCLR_DataType> PrimitiveTypes = |
| 43 | + private static readonly IDictionary<string, nanoCLR_DataType> s_primitiveTypes = |
45 | 44 | new Dictionary<string, nanoCLR_DataType>(StringComparer.Ordinal); |
46 | 45 |
|
47 | | - static nanoSignaturesTable() |
48 | | - { |
49 | | - PrimitiveTypes.Add(typeof(void).FullName, nanoCLR_DataType.DATATYPE_VOID); |
50 | | - |
51 | | - PrimitiveTypes.Add(typeof(sbyte).FullName, nanoCLR_DataType.DATATYPE_I1); |
52 | | - PrimitiveTypes.Add(typeof(short).FullName, nanoCLR_DataType.DATATYPE_I2); |
53 | | - PrimitiveTypes.Add(typeof(int).FullName, nanoCLR_DataType.DATATYPE_I4); |
54 | | - PrimitiveTypes.Add(typeof(long).FullName, nanoCLR_DataType.DATATYPE_I8); |
55 | | - |
56 | | - PrimitiveTypes.Add(typeof(byte).FullName, nanoCLR_DataType.DATATYPE_U1); |
57 | | - PrimitiveTypes.Add(typeof(ushort).FullName, nanoCLR_DataType.DATATYPE_U2); |
58 | | - PrimitiveTypes.Add(typeof(uint).FullName, nanoCLR_DataType.DATATYPE_U4); |
59 | | - PrimitiveTypes.Add(typeof(ulong).FullName, nanoCLR_DataType.DATATYPE_U8); |
60 | | - |
61 | | - PrimitiveTypes.Add(typeof(float).FullName, nanoCLR_DataType.DATATYPE_R4); |
62 | | - PrimitiveTypes.Add(typeof(double).FullName, nanoCLR_DataType.DATATYPE_R8); |
63 | | - |
64 | | - PrimitiveTypes.Add(typeof(char).FullName, nanoCLR_DataType.DATATYPE_CHAR); |
65 | | - PrimitiveTypes.Add(typeof(string).FullName, nanoCLR_DataType.DATATYPE_STRING); |
66 | | - PrimitiveTypes.Add(typeof(bool).FullName, nanoCLR_DataType.DATATYPE_BOOLEAN); |
| 46 | + /// <summary> |
| 47 | + /// Built-in types (see flags in c_CLR_RT_DataTypeLookup at CLR Core code) |
| 48 | + /// </summary> |
| 49 | + private static readonly IDictionary<string, nanoCLR_DataType> s_builtInTypes = |
| 50 | + new Dictionary<string, nanoCLR_DataType>(StringComparer.Ordinal); |
67 | 51 |
|
68 | | - PrimitiveTypes.Add(typeof(object).FullName, nanoCLR_DataType.DATATYPE_OBJECT); |
69 | | - PrimitiveTypes.Add(typeof(IntPtr).FullName, nanoCLR_DataType.DATATYPE_I4); |
70 | | - PrimitiveTypes.Add(typeof(UIntPtr).FullName, nanoCLR_DataType.DATATYPE_U4); |
| 52 | + public static IDictionary<string, nanoCLR_DataType> PrimitiveTypes => s_primitiveTypes; |
71 | 53 |
|
72 | | - PrimitiveTypes.Add(typeof(WeakReference).FullName, nanoCLR_DataType.DATATYPE_WEAKCLASS); |
| 54 | + static nanoSignaturesTable() |
| 55 | + { |
| 56 | + s_primitiveTypes.Add(typeof(void).FullName, nanoCLR_DataType.DATATYPE_VOID); |
| 57 | + |
| 58 | + s_primitiveTypes.Add(typeof(sbyte).FullName, nanoCLR_DataType.DATATYPE_I1); |
| 59 | + s_primitiveTypes.Add(typeof(short).FullName, nanoCLR_DataType.DATATYPE_I2); |
| 60 | + s_primitiveTypes.Add(typeof(int).FullName, nanoCLR_DataType.DATATYPE_I4); |
| 61 | + s_primitiveTypes.Add(typeof(long).FullName, nanoCLR_DataType.DATATYPE_I8); |
| 62 | + |
| 63 | + s_primitiveTypes.Add(typeof(byte).FullName, nanoCLR_DataType.DATATYPE_U1); |
| 64 | + s_primitiveTypes.Add(typeof(ushort).FullName, nanoCLR_DataType.DATATYPE_U2); |
| 65 | + s_primitiveTypes.Add(typeof(uint).FullName, nanoCLR_DataType.DATATYPE_U4); |
| 66 | + s_primitiveTypes.Add(typeof(ulong).FullName, nanoCLR_DataType.DATATYPE_U8); |
| 67 | + |
| 68 | + s_primitiveTypes.Add(typeof(float).FullName, nanoCLR_DataType.DATATYPE_R4); |
| 69 | + s_primitiveTypes.Add(typeof(double).FullName, nanoCLR_DataType.DATATYPE_R8); |
| 70 | + |
| 71 | + s_primitiveTypes.Add(typeof(char).FullName, nanoCLR_DataType.DATATYPE_CHAR); |
| 72 | + s_primitiveTypes.Add(typeof(string).FullName, nanoCLR_DataType.DATATYPE_STRING); |
| 73 | + s_primitiveTypes.Add(typeof(bool).FullName, nanoCLR_DataType.DATATYPE_BOOLEAN); |
| 74 | + |
| 75 | + s_primitiveTypes.Add(typeof(object).FullName, nanoCLR_DataType.DATATYPE_OBJECT); |
| 76 | + s_primitiveTypes.Add(typeof(IntPtr).FullName, nanoCLR_DataType.DATATYPE_I4); |
| 77 | + s_primitiveTypes.Add(typeof(UIntPtr).FullName, nanoCLR_DataType.DATATYPE_U4); |
| 78 | + |
| 79 | + s_primitiveTypes.Add(typeof(WeakReference).FullName, nanoCLR_DataType.DATATYPE_WEAKCLASS); |
| 80 | + |
| 81 | + // from c_CLR_RT_DataTypeLookup at CLR Core code |
| 82 | + s_builtInTypes.Add(typeof(bool).FullName, nanoCLR_DataType.DATATYPE_BOOLEAN); |
| 83 | + s_builtInTypes.Add(typeof(char).FullName, nanoCLR_DataType.DATATYPE_CHAR); |
| 84 | + s_builtInTypes.Add(typeof(sbyte).FullName, nanoCLR_DataType.DATATYPE_I1); |
| 85 | + s_builtInTypes.Add(typeof(byte).FullName, nanoCLR_DataType.DATATYPE_U1); |
| 86 | + s_builtInTypes.Add(typeof(short).FullName, nanoCLR_DataType.DATATYPE_I2); |
| 87 | + s_builtInTypes.Add(typeof(ushort).FullName, nanoCLR_DataType.DATATYPE_U2); |
| 88 | + s_builtInTypes.Add(typeof(int).FullName, nanoCLR_DataType.DATATYPE_I4); |
| 89 | + s_builtInTypes.Add(typeof(uint).FullName, nanoCLR_DataType.DATATYPE_U4); |
| 90 | + s_builtInTypes.Add(typeof(long).FullName, nanoCLR_DataType.DATATYPE_I8); |
| 91 | + s_builtInTypes.Add(typeof(ulong).FullName, nanoCLR_DataType.DATATYPE_U8); |
| 92 | + s_builtInTypes.Add(typeof(float).FullName, nanoCLR_DataType.DATATYPE_R4); |
| 93 | + s_builtInTypes.Add(typeof(double).FullName, nanoCLR_DataType.DATATYPE_R8); |
| 94 | + |
| 95 | + s_builtInTypes.Add(typeof(DateTime).FullName, nanoCLR_DataType.DATATYPE_DATETIME); |
| 96 | + s_builtInTypes.Add(typeof(TimeSpan).FullName, nanoCLR_DataType.DATATYPE_TIMESPAN); |
| 97 | + s_builtInTypes.Add(typeof(string).FullName, nanoCLR_DataType.DATATYPE_STRING); |
| 98 | + |
| 99 | + s_builtInTypes.Add("System.RuntimeTypeHandle", nanoCLR_DataType.DATATYPE_REFLECTION); |
| 100 | + s_builtInTypes.Add("System.RuntimeFieldHandle", nanoCLR_DataType.DATATYPE_REFLECTION); |
| 101 | + s_builtInTypes.Add("System.RuntimeMethodHandle", nanoCLR_DataType.DATATYPE_REFLECTION); |
| 102 | + |
| 103 | + s_builtInTypes.Add(typeof(WeakReference).FullName, nanoCLR_DataType.DATATYPE_WEAKCLASS); |
73 | 104 | } |
74 | 105 |
|
75 | 106 | /// <summary> |
@@ -273,8 +304,9 @@ public void WriteDataType( |
273 | 304 | return; |
274 | 305 | } |
275 | 306 |
|
276 | | - nanoCLR_DataType dataType; |
277 | | - if (PrimitiveTypes.TryGetValue(typeDefinition.FullName, out dataType)) |
| 307 | + if (s_primitiveTypes.TryGetValue( |
| 308 | + typeDefinition.FullName, |
| 309 | + out nanoCLR_DataType dataType)) |
278 | 310 | { |
279 | 311 | writer.WriteByte((byte)dataType); |
280 | 312 | return; |
@@ -387,6 +419,51 @@ public void WriteDataType( |
387 | 419 | writer.WriteByte(0x00); |
388 | 420 | } |
389 | 421 |
|
| 422 | + /// <summary> |
| 423 | + /// Writes data type for type reference. |
| 424 | + /// </summary> |
| 425 | + /// <param name="typeDefinition">Type reference or definition in Mono.Cecil format.</param> |
| 426 | + /// <param name="writer">Target binary writer for writing signature information.</param> |
| 427 | + public void WriteDataTypeForTypeDef(TypeDefinition typeDefinition, nanoBinaryWriter writer) |
| 428 | + { |
| 429 | + // start checking with the built-in types |
| 430 | + if (s_builtInTypes.TryGetValue( |
| 431 | + typeDefinition.FullName, |
| 432 | + out nanoCLR_DataType dataType)) |
| 433 | + { |
| 434 | + writer.WriteByte((byte)dataType); |
| 435 | + } |
| 436 | + else |
| 437 | + { |
| 438 | + // check order matters because some types are derived from others |
| 439 | + if (typeDefinition.IsEnum) |
| 440 | + { |
| 441 | + FieldDefinition baseTypeValue = typeDefinition.Fields.FirstOrDefault(item => item.IsSpecialName); |
| 442 | + |
| 443 | + if (baseTypeValue != null) |
| 444 | + { |
| 445 | + WriteTypeInfo(baseTypeValue.FieldType, writer); |
| 446 | + } |
| 447 | + else |
| 448 | + { |
| 449 | + writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_I4); |
| 450 | + } |
| 451 | + } |
| 452 | + else if (typeDefinition.IsValueType) |
| 453 | + { |
| 454 | + writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_VALUETYPE); |
| 455 | + } |
| 456 | + else if (typeDefinition.IsClass || typeDefinition.IsInterface) |
| 457 | + { |
| 458 | + writer.WriteByte((byte)nanoCLR_DataType.DATATYPE_CLASS); |
| 459 | + } |
| 460 | + else |
| 461 | + { |
| 462 | + Debug.Fail("Gotcha!"); |
| 463 | + } |
| 464 | + } |
| 465 | + } |
| 466 | + |
390 | 467 | /// <inheritdoc/> |
391 | 468 | public void Write( |
392 | 469 | nanoBinaryWriter writer) |
@@ -567,7 +644,7 @@ private void WriteAttributeArgumentValue( |
567 | 644 | CustomAttributeArgument argument) |
568 | 645 | { |
569 | 646 | nanoCLR_DataType dataType; |
570 | | - if (PrimitiveTypes.TryGetValue(argument.Type.FullName, out dataType)) |
| 647 | + if (s_primitiveTypes.TryGetValue(argument.Type.FullName, out dataType)) |
571 | 648 | { |
572 | 649 | switch (dataType) |
573 | 650 | { |
|
0 commit comments