3using System.Reflection;
4using System.Reflection.Emit;
10#if FIRST_PASS == false && EXPORTER == false && IMPORTER == false
15 internal abstract class FieldAccessor
28 protected FieldAccessor(
Type type,
string name)
30 this.type = type ??
throw new ArgumentNullException(nameof(type));
31 this.name = name ??
throw new ArgumentNullException(nameof(name));
42 protected string Name => name;
47 protected FieldInfo Field => AccessorUtil.LazyGet(
ref field, () => type.GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) ??
throw new InvalidOperationException();
55 internal sealed class FieldAccessor<TField> : FieldAccessor
65 public static FieldAccessor<TField> LazyGet(
ref FieldAccessor<TField> location,
Type type,
string name)
67 return AccessorUtil.LazyGet(
ref location, () =>
new FieldAccessor<TField>(type, name));
71 Action<TField> setter;
78 public FieldAccessor(
Type type,
string name) :
87 Func<TField> Getter => AccessorUtil.LazyGet(
ref getter, MakeGetter);
92 Action<TField> Setter => AccessorUtil.LazyGet(
ref setter, MakeSetter);
99 Func<TField> MakeGetter()
102 throw new NotImplementedException();
104 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorGet>__{Type.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(TField), Array.Empty<
Type>());
105 var il = JVM.Context.CodeEmitterFactory.Create(dm);
107 il.Emit(OpCodes.Ldsfld, Field);
108 il.Emit(OpCodes.Ret);
111 return (Func<TField>)dm.CreateDelegate(typeof(Func<TField>));
120 Action<TField> MakeSetter()
123 throw new NotImplementedException();
125 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorSet>__{Type.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(
void),
new[] { typeof(TField) });
126 var il = JVM.Context.CodeEmitterFactory.Create(dm);
128 il.Emit(OpCodes.Ldarg_0);
129 il.Emit(OpCodes.Stsfld, Field);
130 il.Emit(OpCodes.Ret);
133 return (Action<TField>)dm.CreateDelegate(typeof(Action<TField>));
141 public TField GetValue() => Getter();
147 public void SetValue(TField value) => Setter(value);
156 internal sealed class FieldAccessor<TObject, TField> : FieldAccessor
159 delegate TField GetterDelegate(TObject
self);
160 delegate
void SetterDelegate(TObject
self, TField value);
161 delegate TField ExchangeDelegate(TObject
self, TField value);
162 delegate TField CompareExchangeDelegate(TObject
self, TField value, TField comparand);
164 static readonly
MethodInfo ExchangeOfInt32 = typeof(
Interlocked).GetMethod(nameof(
Interlocked.Exchange),
new[] { typeof(int).MakeByRefType(), typeof(int) });
165 static readonly
MethodInfo ExchangeOfInt64 = typeof(
Interlocked).GetMethod(nameof(
Interlocked.Exchange),
new[] { typeof(long).MakeByRefType(), typeof(long) });
166 static readonly
MethodInfo ExchangeOfSingle = typeof(
Interlocked).GetMethod(nameof(
Interlocked.Exchange),
new[] { typeof(float).MakeByRefType(), typeof(float) });
167 static readonly
MethodInfo ExchangeOfDouble = typeof(
Interlocked).GetMethod(nameof(
Interlocked.Exchange),
new[] { typeof(double).MakeByRefType(), typeof(double) });
168 static readonly
MethodInfo ExchangeOfT = typeof(
Interlocked).GetMethods().First(i => i.Name == nameof(
Interlocked.Exchange) && i.GetGenericArguments().Length == 1);
170 static readonly
MethodInfo CompareExchangeOfInt32 = typeof(
Interlocked).GetMethod(nameof(
Interlocked.CompareExchange),
new[] { typeof(int).MakeByRefType(), typeof(int), typeof(int) });
171 static readonly
MethodInfo CompareExchangeOfInt64 = typeof(
Interlocked).GetMethod(nameof(
Interlocked.CompareExchange),
new[] { typeof(long).MakeByRefType(), typeof(long), typeof(long) });
172 static readonly
MethodInfo CompareExchangeOfSingle = typeof(
Interlocked).GetMethod(nameof(
Interlocked.CompareExchange),
new[] { typeof(float).MakeByRefType(), typeof(float), typeof(float) });
173 static readonly
MethodInfo CompareExchangeOfDouble = typeof(
Interlocked).GetMethod(nameof(
Interlocked.CompareExchange),
new[] { typeof(double).MakeByRefType(), typeof(double), typeof(double) });
174 static readonly
MethodInfo CompareExchangeOfT = typeof(
Interlocked).GetMethods().First(i => i.Name == nameof(
Interlocked.CompareExchange) && i.GetGenericArguments().Length == 1);
183 public static FieldAccessor<TObject, TField> LazyGet(
ref FieldAccessor<TObject, TField> location,
Type type,
string name)
185 return AccessorUtil.LazyGet(
ref location, () =>
new FieldAccessor<TObject, TField>(type, name));
188 GetterDelegate getter;
189 SetterDelegate setter;
190 ExchangeDelegate exchange;
191 CompareExchangeDelegate compareExchange;
198 public FieldAccessor(
Type type,
string name) :
207 GetterDelegate Getter => AccessorUtil.LazyGet(
ref getter, MakeGetter);
212 SetterDelegate Setter => AccessorUtil.LazyGet(
ref setter, MakeSetter);
217 ExchangeDelegate Exchange => AccessorUtil.LazyGet(
ref exchange, MakeExchange);
222 CompareExchangeDelegate CompareExchange => AccessorUtil.LazyGet(
ref compareExchange, MakeCompareExchange);
228 GetterDelegate MakeGetter()
230#if FIRST_PASS || IMPORTER || EXPORTER
231 throw new NotImplementedException();
233 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorGet>__{Field.DeclaringType.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(TField),
new[] { typeof(TObject) });
234 var il = JVM.Context.CodeEmitterFactory.Create(dm);
236 il.Emit(OpCodes.Ldarg_0);
237 il.Emit(OpCodes.Castclass,
Type);
238 il.Emit(OpCodes.Ldfld, Field);
239 il.Emit(OpCodes.Ret);
242 return (GetterDelegate)dm.CreateDelegate(typeof(GetterDelegate));
250 SetterDelegate MakeSetter()
252#if FIRST_PASS || IMPORTER || EXPORTER
253 throw new NotImplementedException();
255 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorSet>__{Field.DeclaringType.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(
void),
new[] { typeof(TObject), typeof(TField) });
256 var il = JVM.Context.CodeEmitterFactory.Create(dm);
258 il.Emit(OpCodes.Ldarg_0);
259 il.Emit(OpCodes.Castclass,
Type);
260 il.Emit(OpCodes.Ldarg_1);
261 il.Emit(OpCodes.Stfld, Field);
262 il.Emit(OpCodes.Ret);
265 return (SetterDelegate)dm.CreateDelegate(typeof(SetterDelegate));
273 ExchangeDelegate MakeExchange()
275#if FIRST_PASS || IMPORTER || EXPORTER
276 throw new NotImplementedException();
278 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorExchange>__{Field.DeclaringType.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(TField),
new[] { typeof(TObject), typeof(TField) });
279 var il = JVM.Context.CodeEmitterFactory.Create(dm);
282 il.Emit(OpCodes.Castclass,
Type);
283 il.Emit(Field.IsStatic ? OpCodes.Ldsflda: OpCodes.Ldflda, Field);
286 switch (typeof(TField))
288 case Type t when t == typeof(
int):
289 il.Emit(OpCodes.
Call, ExchangeOfInt32);
291 case Type t when t == typeof(
long):
292 il.Emit(OpCodes.
Call, ExchangeOfInt64);
294 case Type t when t == typeof(
float):
295 il.Emit(OpCodes.
Call, ExchangeOfSingle);
297 case Type t when t == typeof(
double):
298 il.Emit(OpCodes.
Call, ExchangeOfDouble);
300 case Type t when t.IsValueType ==
false:
301 il.Emit(OpCodes.Call, ExchangeOfT.MakeGenericMethod(Field.FieldType));
304 throw new InternalException(
"No Interlocked.Exchange implementation for type.");
307 il.Emit(OpCodes.Ret);
310 return (ExchangeDelegate)dm.CreateDelegate(typeof(ExchangeDelegate));
318 CompareExchangeDelegate MakeCompareExchange()
320#if FIRST_PASS || IMPORTER || EXPORTER
321 throw new NotImplementedException();
323 var dm = DynamicMethodUtil.Create($
"__<FieldAccessorCompareExchange>__{Field.DeclaringType.Name.Replace(".
", "_
")}__{Field.Name}",
Type,
false, typeof(TField),
new[] { typeof(TObject), typeof(TField), typeof(TField) });
324 var il = JVM.Context.CodeEmitterFactory.Create(dm);
327 il.Emit(OpCodes.Castclass,
Type);
328 il.Emit(Field.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda, Field);
332 switch (typeof(TField))
334 case Type t when t == typeof(
int):
335 il.Emit(OpCodes.
Call, CompareExchangeOfInt32);
337 case Type t when t == typeof(
long):
338 il.Emit(OpCodes.
Call, CompareExchangeOfInt64);
340 case Type t when t == typeof(
float):
341 il.Emit(OpCodes.
Call, CompareExchangeOfSingle);
343 case Type t when t == typeof(
double):
344 il.Emit(OpCodes.
Call, CompareExchangeOfDouble);
346 case Type t when t.IsValueType ==
false:
347 il.Emit(OpCodes.Call, CompareExchangeOfT.MakeGenericMethod(Field.FieldType));
350 throw new InternalException(
"No Interlocked.CompareExchange implementation for type.");
353 il.Emit(OpCodes.Ret);
356 return (CompareExchangeDelegate)dm.CreateDelegate(typeof(CompareExchangeDelegate));
365 public TField GetValue(TObject
self) => Getter(
self);
372 public void SetValue(TObject
self, TField value) => Setter(
self, value);
380 public TField ExchangeValue(TObject
self, TField value) => Exchange(
self, value);
389 public TField CompareExchangeValue(TObject
self, TField value, TField comparand) => CompareExchange(
self, value, comparand);
System.Threading.Interlocked Interlocked
IKVM.Reflection.Type Type
IKVM.Reflection.FieldInfo FieldInfo
IKVM.Reflection.MethodInfo MethodInfo
global::java.lang.invoke.LambdaForm.Name Name