-
Notifications
You must be signed in to change notification settings - Fork 1
/
Fields.tt
149 lines (137 loc) · 9.13 KB
/
Fields.tt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".autogen.cs" #>
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using JetBrains.Annotations;
namespace ILGeneratorExtensions
{
[PublicAPI]
public static partial class Fields
{
<# foreach (var type in new [] { typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double)}) { #>
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the given field for that object
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="field">The field to store the value in</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWith(this ILGenerator generator, FieldInfo field, <#= type.Name #> value)
{
if (field.FieldType != typeof(<#= type.Name #>))
{
throw new InvalidOperationException("Type mismatch - field is of type " + field.FieldType);
}
return generator.LoadConstant(value)
.StoreInField(field);
}
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field (with the given name on the given type) for that object
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="type">The type the field is on</param>
/// <param name="fieldName">The name of the field</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWith(this ILGenerator generator, Type type, string fieldName, <#= type.Name #> value)
=> generator.OverwriteFieldWith(GetFieldInfo(type, fieldName), value);
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field (with the given name on the given type) for that object
/// </summary>
/// <typeparam name="T">The type the field is on</typeparam>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldName">The name of the field</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWith<T>(this ILGenerator generator, string fieldName, <#= type.Name #> value)
=> generator.OverwriteFieldWith(typeof(T), fieldName, value);
/// <summary>
/// Stores the given value in the static field represented by the given expression
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldExpression">An expression representing the field to load</param>
/// <param name="value">The value to overwrite the field with</param>
[PublicAPI]
public static ILGenerator OverwriteFieldWith(this ILGenerator generator, Expression<Func<<#= type.Name #>>> fieldExpression, <#= type.Name #> value)
=> generator.OverwriteFieldWith(GetFieldInfo(fieldExpression), value);
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field represented by the given expression for that object
/// </summary>
/// <typeparam name="T">The type the field is on</typeparam>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldExpression">An expression representing the field to load</param>
/// <param name="value">The value to overwrite the field with</param>
[PublicAPI]
public static ILGenerator OverwriteFieldWith<T>(this ILGenerator generator, Expression<Func<T, <#= type.Name #>>> fieldExpression, <#= type.Name #> value)
=> generator.OverwriteFieldWith(GetFieldInfo(fieldExpression), value);
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the given field for that object, with volatile semantics
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="field">The field to store the value in</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWithVolatile(this ILGenerator generator, FieldInfo field, <#= type.Name #> value)
{
if (field.FieldType != typeof(<#= type.Name #>))
{
throw new InvalidOperationException("Type mismatch - field is of type " + field.FieldType);
}
return generator.LoadConstant(value)
.FluentEmit(OpCodes.Volatile)
.StoreInField(field);
}
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field (with the given name on the given type) for that object, with volatile semantics
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="type">The type the field is on</param>
/// <param name="fieldName">The name of the field</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWithVolatile(this ILGenerator generator, Type type, string fieldName, <#= type.Name #> value)
=> generator.OverwriteFieldWithVolatile(GetFieldInfo(type, fieldName), value);
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field (with the given name on the given type) for that object, with volatile semantics
/// </summary>
/// <typeparam name="T">The type the field is on</typeparam>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldName">The name of the field</param>
/// <param name="value">The value to overwrite the field with</param>
/// <exception cref="InvalidOperationException">Thrown if the field is not of type <see cref="<#= type.Name #>" /></exception>
[PublicAPI]
public static ILGenerator OverwriteFieldWithVolatile<T>(this ILGenerator generator, string fieldName, <#= type.Name #> value)
=> generator.OverwriteFieldWithVolatile(typeof(T), fieldName, value);
/// <summary>
/// Stores the given value in the static field represented by the given expression, with volatile semantics
/// </summary>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldExpression">An expression representing the field to load</param>
/// <param name="value">The value to overwrite the field with</param>
[PublicAPI]
public static ILGenerator OverwriteFieldWithVolatile(this ILGenerator generator, Expression<Func<<#= type.Name #>>> fieldExpression, <#= type.Name #> value)
=> generator.OverwriteFieldWithVolatile(GetFieldInfo(fieldExpression), value);
/// <summary>
/// Pops a reference from the evaluation stack and stores the given value in the field represented by the given expression for that object, with volatile semantics
/// </summary>
/// <typeparam name="T">The type the field is on</typeparam>
/// <param name="generator">The <see cref="T:System.Reflection.Emit.ILGenerator" /> to emit instructions from</param>
/// <param name="fieldExpression">An expression representing the field to load</param>
/// <param name="value">The value to overwrite the field with</param>
[PublicAPI]
public static ILGenerator OverwriteFieldWithVolatile<T>(this ILGenerator generator, Expression<Func<T, <#= type.Name #>>> fieldExpression, <#= type.Name #> value)
=> generator.OverwriteFieldWithVolatile(GetFieldInfo(fieldExpression), value);
<# } #>
}
}