2
Copyright (C) 2002-2012 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Collections.Generic;
26
#if STATIC_COMPILER || STUB_GENERATOR
27
using IKVM.Reflection;
28
using IKVM.Reflection.Emit;
29
using Type = IKVM.Reflection.Type;
31
using System.Reflection;
32
using System.Reflection.Emit;
34
using System.Diagnostics;
35
using IKVM.Attributes;
36
using System.Threading;
37
using System.Runtime.InteropServices;
39
namespace IKVM.Internal
42
enum MemberFlags : short
45
HideFromReflection = 1,
49
InternalAccess = 32, // member has "internal" access (@ikvm.lang.Internal)
50
PropertyAccessor = 64,
53
NonPublicTypeInSignature = 512, // this flag is only available after linking and is not set for access stubs
54
DelegateInvokeWithByRefParameter = 1024,
55
Type2FinalField = 2048,
58
abstract class MemberWrapper
60
private HandleWrapper handle;
61
private TypeWrapper declaringType;
62
private Modifiers modifiers;
63
private MemberFlags flags;
67
private sealed class HandleWrapper
69
internal readonly IntPtr Value;
71
[System.Security.SecurityCritical]
72
internal HandleWrapper(MemberWrapper obj)
74
Value = (IntPtr)GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);
78
[System.Security.SecuritySafeCritical]
81
if (!Environment.HasShutdownStarted)
83
GCHandle h = (GCHandle)Value;
90
GC.ReRegisterForFinalize(this);
97
protected MemberWrapper(TypeWrapper declaringType, string name, string sig, Modifiers modifiers, MemberFlags flags)
99
Debug.Assert(declaringType != null);
100
this.declaringType = declaringType;
101
this.name = String.Intern(name);
102
this.sig = String.Intern(sig);
103
this.modifiers = modifiers;
107
internal IntPtr Cookie
109
[System.Security.SecurityCritical]
116
handle = new HandleWrapper(this);
123
[System.Security.SecurityCritical]
124
internal static MemberWrapper FromCookieImpl(IntPtr cookie)
126
return (MemberWrapper)GCHandle.FromIntPtr(cookie).Target;
129
internal TypeWrapper DeclaringType
133
return declaringType;
145
internal string Signature
153
internal bool IsAccessibleFrom(TypeWrapper referencedType, TypeWrapper caller, TypeWrapper instance)
155
if(referencedType.IsAccessibleFrom(caller))
158
caller == DeclaringType ||
159
IsPublicOrProtectedMemberAccessible(caller, instance) ||
160
(IsInternal && DeclaringType.InternalsVisibleTo(caller)) ||
161
(!IsPrivate && DeclaringType.IsPackageAccessibleFrom(caller)))
162
// The JVM supports accessing members that have non-public types in their signature from another package,
163
// but the CLI doesn't. It would be nice if we worked around that by emitting extra accessors, but for now
164
// we'll simply disallow such access across assemblies (unless the appropriate InternalsVisibleToAttribute exists).
165
&& (!(HasNonPublicTypeInSignature || IsType2FinalField) || InPracticeInternalsVisibleTo(caller));
170
private bool IsPublicOrProtectedMemberAccessible(TypeWrapper caller, TypeWrapper instance)
172
if (IsPublic || (IsProtected && caller.IsSubTypeOf(DeclaringType) && (IsStatic || instance.IsSubTypeOf(caller))))
174
return DeclaringType.IsPublic || InPracticeInternalsVisibleTo(caller);
179
private bool InPracticeInternalsVisibleTo(TypeWrapper caller)
182
if (DeclaringType.TypeAsTBD.Assembly.Equals(caller.TypeAsTBD.Assembly))
184
// both the caller and the declaring type are in the same assembly
185
// so we know that the internals are visible
186
// (this handles the case where we're running in dynamic mode)
191
if (DeclaringType is DynamicTypeWrapper)
193
// if we are dynamic, we can just become friends with the caller
194
DeclaringType.GetClassLoader().GetTypeWrapperFactory().AddInternalsVisibleTo(caller.TypeAsTBD.Assembly);
198
return DeclaringType.InternalsVisibleTo(caller);
201
internal bool IsHideFromReflection
205
return (flags & MemberFlags.HideFromReflection) != 0;
209
internal bool IsExplicitOverride
213
return (flags & MemberFlags.ExplicitOverride) != 0;
217
internal bool IsMirandaMethod
221
return (flags & MemberFlags.MirandaMethod) != 0;
225
internal bool IsAccessStub
229
return (flags & MemberFlags.AccessStub) != 0;
233
internal bool IsPropertyAccessor
237
return (flags & MemberFlags.PropertyAccessor) != 0;
241
// this is unsynchronized, so it may only be called during the JavaTypeImpl constructor
244
flags |= MemberFlags.PropertyAccessor;
248
flags &= ~MemberFlags.PropertyAccessor;
253
internal bool IsIntrinsic
257
return (flags & MemberFlags.Intrinsic) != 0;
261
protected void SetIntrinsicFlag()
263
flags |= MemberFlags.Intrinsic;
266
protected void SetNonPublicTypeInSignatureFlag()
268
flags |= MemberFlags.NonPublicTypeInSignature;
271
internal bool HasNonPublicTypeInSignature
273
get { return (flags & MemberFlags.NonPublicTypeInSignature) != 0; }
276
protected void SetType2FinalField()
278
flags |= MemberFlags.Type2FinalField;
281
internal bool IsType2FinalField
283
get { return (flags & MemberFlags.Type2FinalField) != 0; }
286
internal bool HasCallerID
290
return (flags & MemberFlags.CallerID) != 0;
294
internal bool IsDelegateInvokeWithByRefParameter
296
get { return (flags & MemberFlags.DelegateInvokeWithByRefParameter) != 0; }
299
internal Modifiers Modifiers
307
internal bool IsStatic
311
return (modifiers & Modifiers.Static) != 0;
315
internal bool IsInternal
319
return (flags & MemberFlags.InternalAccess) != 0;
323
internal bool IsPublic
327
return (modifiers & Modifiers.Public) != 0;
331
internal bool IsPrivate
335
return (modifiers & Modifiers.Private) != 0;
339
internal bool IsProtected
343
return (modifiers & Modifiers.Protected) != 0;
347
internal bool IsFinal
351
return (modifiers & Modifiers.Final) != 0;
356
interface ICustomInvoke
358
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
359
object Invoke(object obj, object[] args, ikvm.@internal.CallerID callerID);
363
abstract class MethodWrapper : MemberWrapper
365
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
366
private static Dictionary<MethodWrapper, sun.reflect.MethodAccessor> invokenonvirtualCache;
367
private volatile object reflectionMethod;
369
internal static readonly MethodWrapper[] EmptyArray = new MethodWrapper[0];
370
private MethodBase method;
371
private string[] declaredExceptions;
372
private TypeWrapper returnTypeWrapper;
373
private TypeWrapper[] parameterTypeWrappers;
376
internal virtual void EmitCall(CodeEmitter ilgen)
378
throw new InvalidOperationException();
381
internal virtual void EmitCallvirt(CodeEmitter ilgen)
383
throw new InvalidOperationException();
386
internal virtual void EmitCallvirtReflect(CodeEmitter ilgen)
391
internal virtual void EmitNewobj(CodeEmitter ilgen)
393
throw new InvalidOperationException();
396
internal virtual bool EmitIntrinsic(EmitIntrinsicContext context)
398
return Intrinsics.Emit(context);
400
#endif // STUB_GENERATOR
402
internal virtual bool IsDynamicOnly
410
internal MethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
411
: base(declaringType, name, sig, modifiers, flags)
413
Profiler.Count("MethodWrapper");
414
this.method = method;
415
Debug.Assert(((returnType == null) == (parameterTypes == null)) || (returnType == PrimitiveTypeWrapper.VOID));
416
this.returnTypeWrapper = returnType;
417
this.parameterTypeWrappers = parameterTypes;
418
if (Intrinsics.IsIntrinsic(this))
422
UpdateNonPublicTypeInSignatureFlag();
425
private void UpdateNonPublicTypeInSignatureFlag()
427
if ((IsPublic || IsProtected) && (returnTypeWrapper != null && parameterTypeWrappers != null) && !(this is AccessStubMethodWrapper) && !(this is AccessStubConstructorMethodWrapper))
429
if (!returnTypeWrapper.IsPublic && !returnTypeWrapper.IsUnloadable)
431
SetNonPublicTypeInSignatureFlag();
435
foreach (TypeWrapper tw in parameterTypeWrappers)
437
if (!tw.IsPublic && !tw.IsUnloadable)
439
SetNonPublicTypeInSignatureFlag();
447
internal void SetDeclaredExceptions(string[] exceptions)
449
if(exceptions == null)
451
exceptions = new string[0];
453
this.declaredExceptions = (string[])exceptions.Clone();
456
internal string[] GetDeclaredExceptions()
458
return declaredExceptions;
461
#if !STATIC_COMPILER && !STUB_GENERATOR
462
internal object ToMethodOrConstructor(bool copy)
467
object method = reflectionMethod;
471
ClassLoaderWrapper loader = this.DeclaringType.GetClassLoader();
472
TypeWrapper[] argTypes = GetParameters();
473
java.lang.Class[] parameterTypes = new java.lang.Class[argTypes.Length];
474
for (int i = 0; i < argTypes.Length; i++)
476
parameterTypes[i] = argTypes[i].EnsureLoadable(loader).ClassObject;
478
java.lang.Class[] checkedExceptions = GetExceptions();
479
if (this.Name == StringConstants.INIT)
481
method = new java.lang.reflect.Constructor(
482
this.DeclaringType.ClassObject,
485
(int)this.Modifiers | (this.IsInternal ? 0x40000000 : 0),
486
Array.IndexOf(this.DeclaringType.GetMethods(), this),
487
this.DeclaringType.GetGenericMethodSignature(this),
494
method = new java.lang.reflect.Method(
495
this.DeclaringType.ClassObject,
498
this.ReturnType.EnsureLoadable(loader).ClassObject,
500
(int)this.Modifiers | (this.IsInternal ? 0x40000000 : 0),
501
Array.IndexOf(this.DeclaringType.GetMethods(), this),
502
this.DeclaringType.GetGenericMethodSignature(this),
510
if (reflectionMethod == null)
512
reflectionMethod = method;
516
method = reflectionMethod;
522
java.lang.reflect.Constructor ctor = method as java.lang.reflect.Constructor;
527
return ((java.lang.reflect.Method)method).copy();
534
private java.lang.Class[] GetExceptions()
536
string[] classes = declaredExceptions;
537
Type[] types = Type.EmptyTypes;
540
// NOTE if method is a MethodBuilder, GetCustomAttributes doesn't work (and if
541
// the method had any declared exceptions, the declaredExceptions field would have
543
if (method != null && !(method is MethodBuilder))
545
ThrowsAttribute attr = AttributeHelper.GetThrows(method);
548
classes = attr.classes;
555
java.lang.Class[] array = new java.lang.Class[classes.Length];
556
for (int i = 0; i < classes.Length; i++)
558
array[i] = this.DeclaringType.GetClassLoader().LoadClassByDottedName(classes[i]).ClassObject;
564
java.lang.Class[] array = new java.lang.Class[types.Length];
565
for (int i = 0; i < types.Length; i++)
572
#endif // !FIRST_PASS
574
internal static MethodWrapper FromMethodOrConstructor(object methodOrConstructor)
579
java.lang.reflect.Method method = methodOrConstructor as java.lang.reflect.Method;
582
return TypeWrapper.FromClass(method.getDeclaringClass()).GetMethods()[method._slot()];
584
java.lang.reflect.Constructor constructor = (java.lang.reflect.Constructor)methodOrConstructor;
585
return TypeWrapper.FromClass(constructor.getDeclaringClass()).GetMethods()[constructor._slot()];
588
#endif // !STATIC_COMPILER && !STUB_GENERATOR
590
[System.Security.SecurityCritical]
591
internal static MethodWrapper FromCookie(IntPtr cookie)
593
return (MethodWrapper)FromCookieImpl(cookie);
596
internal bool IsLinked
600
return parameterTypeWrappers != null;
608
if(parameterTypeWrappers != null)
613
ClassLoaderWrapper loader = this.DeclaringType.GetClassLoader();
614
TypeWrapper ret = loader.RetTypeWrapperFromSigNoThrow(Signature);
615
TypeWrapper[] parameters = loader.ArgTypeWrapperListFromSigNoThrow(Signature);
620
// critical code in the finally block to avoid Thread.Abort interrupting the thread
624
if(parameterTypeWrappers == null)
626
Debug.Assert(returnTypeWrapper == null || returnTypeWrapper == PrimitiveTypeWrapper.VOID);
627
returnTypeWrapper = ret;
628
parameterTypeWrappers = parameters;
629
UpdateNonPublicTypeInSignatureFlag();
638
// HACK if linking fails, we unlink to make sure
639
// that the next link attempt will fail again
640
returnTypeWrapper = null;
641
parameterTypeWrappers = null;
650
protected virtual void DoLinkMethod()
652
method = this.DeclaringType.LinkMethod(this);
655
[Conditional("DEBUG")]
656
internal void AssertLinked()
658
if(!(parameterTypeWrappers != null && returnTypeWrapper != null))
660
Tracer.Error(Tracer.Runtime, "AssertLinked failed: " + this.DeclaringType.Name + "::" + this.Name + this.Signature);
662
Debug.Assert(parameterTypeWrappers != null && returnTypeWrapper != null, this.DeclaringType.Name + "::" + this.Name + this.Signature);
665
internal TypeWrapper ReturnType
670
return returnTypeWrapper;
674
internal TypeWrapper[] GetParameters()
677
return parameterTypeWrappers;
681
internal DefineMethodHelper GetDefineMethodHelper()
683
return new DefineMethodHelper(this);
687
internal Type ReturnTypeForDefineMethod
691
return ReturnType.TypeAsSignatureType;
695
internal Type[] GetParametersForDefineMethod()
697
TypeWrapper[] wrappers = GetParameters();
698
int len = wrappers.Length;
703
Type[] temp = new Type[len];
704
for(int i = 0; i < wrappers.Length; i++)
706
temp[i] = wrappers[i].TypeAsSignatureType;
710
temp[len - 1] = CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType;
715
// we expose the underlying MethodBase object,
716
// for Java types, this is the method that contains the compiled Java bytecode
717
// for remapped types, this is the mbCore method (not the helper)
718
// Note that for some artificial methods (notably wrap() in enums), method is null
719
internal MethodBase GetMethod()
725
internal string RealName
734
// this returns the Java method's attributes in .NET terms (e.g. used to create stubs for this method)
735
internal MethodAttributes GetMethodAttributes()
737
MethodAttributes attribs = MethodAttributes.HideBySig;
740
attribs |= MethodAttributes.Static;
744
attribs |= MethodAttributes.Public;
748
attribs |= MethodAttributes.Private;
752
attribs |= MethodAttributes.FamORAssem;
756
attribs |= MethodAttributes.Family;
758
// constructors aren't virtual
759
if(!IsStatic && !IsPrivate && Name != "<init>")
761
attribs |= MethodAttributes.Virtual;
765
attribs |= MethodAttributes.Final;
769
attribs |= MethodAttributes.Abstract;
774
internal bool IsAbstract
778
return (Modifiers & Modifiers.Abstract) != 0;
782
#if !STATIC_COMPILER && !STUB_GENERATOR
784
internal object InvokeJNI(object obj, object[] args, bool nonVirtual, object callerID)
789
if (ReferenceEquals(Name, StringConstants.INIT))
791
java.lang.reflect.Constructor cons = (java.lang.reflect.Constructor)ToMethodOrConstructor(false);
794
sun.reflect.ConstructorAccessor acc = cons.getConstructorAccessor();
797
acc = (sun.reflect.ConstructorAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newConstructorAccessor0(null, cons);
798
cons.setConstructorAccessor(acc);
800
return acc.newInstance(args);
802
else if (!ReflectUtil.IsConstructor(method))
804
Debug.Assert(method.IsStatic);
805
// we're dealing with a constructor on a remapped type, if obj is supplied, it means
806
// that we should call the constructor on an already existing instance, but that isn't
807
// possible with remapped types
808
// the type of this exception is a bit random (note that this can only happen through JNI reflection)
809
throw new java.lang.IncompatibleClassChangeError(string.Format("Remapped type {0} doesn't support constructor invocation on an existing instance", DeclaringType.Name));
811
else if (!method.DeclaringType.IsInstanceOfType(obj))
813
// we're trying to initialize an existing instance of a remapped type
814
throw new NotSupportedException("Unable to partially construct object of type " + obj.GetType().FullName + " to type " + method.DeclaringType.FullName);
821
InvokeArgsProcessor proc = new InvokeArgsProcessor(this, method, obj, UnboxArgs(args), (ikvm.@internal.CallerID)callerID);
822
object o = method.Invoke(proc.GetObj(), proc.GetArgs());
823
TypeWrapper retType = this.ReturnType;
824
if (!retType.IsUnloadable && retType.IsGhost)
826
o = retType.GhostRefField.GetValue(o);
830
catch (ArgumentException x1)
832
throw new java.lang.IllegalArgumentException(x1.Message);
834
catch (TargetInvocationException x)
836
throw new java.lang.reflect.InvocationTargetException(ikvm.runtime.Util.mapException(x.InnerException));
845
&& !this.DeclaringType.IsFinal)
847
if (this.DeclaringType.IsRemapped && !this.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj))
850
return InvokeNonvirtualRemapped(obj, UnboxArgs(args));
854
if (invokenonvirtualCache == null)
856
Interlocked.CompareExchange(ref invokenonvirtualCache, new Dictionary<MethodWrapper, sun.reflect.MethodAccessor>(), null);
858
sun.reflect.MethodAccessor acc;
859
lock (invokenonvirtualCache)
861
if (!invokenonvirtualCache.TryGetValue(this, out acc))
863
acc = new IKVM.NativeCode.sun.reflect.ReflectionFactory.FastMethodAccessorImpl((java.lang.reflect.Method)ToMethodOrConstructor(false), true);
864
invokenonvirtualCache.Add(this, acc);
867
object val = acc.invoke(obj, args, (ikvm.@internal.CallerID)callerID);
868
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
870
val = JVM.Unbox(val);
877
java.lang.reflect.Method method = (java.lang.reflect.Method)ToMethodOrConstructor(false);
878
sun.reflect.MethodAccessor acc = method.getMethodAccessor();
881
acc = (sun.reflect.MethodAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newMethodAccessor(null, method);
882
method.setMethodAccessor(acc);
884
object val = acc.invoke(obj, args, (ikvm.@internal.CallerID)callerID);
885
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
887
val = JVM.Unbox(val);
894
private object[] UnboxArgs(object[] args)
896
TypeWrapper[] paramTypes = GetParameters();
897
for (int i = 0; i < paramTypes.Length; i++)
899
if (paramTypes[i].IsPrimitive)
901
args[i] = JVM.Unbox(args[i]);
906
#endif // !STATIC_COMPILER && !STUB_GENERATOR
908
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
909
internal void ResolveMethod()
911
// if we've still got the builder object, we need to replace it with the real thing before we can call it
912
if(method is MethodBuilder)
914
method = method.Module.ResolveMethod(((MethodBuilder)method).GetToken().Token);
919
protected virtual object InvokeNonvirtualRemapped(object obj, object[] args)
921
throw new InvalidOperationException();
924
private struct InvokeArgsProcessor
927
private object[] args;
929
internal InvokeArgsProcessor(MethodWrapper mw, MethodBase method, object original_obj, object[] original_args, ikvm.@internal.CallerID callerID)
931
TypeWrapper[] argTypes = mw.GetParameters();
933
if(!mw.IsStatic && method.IsStatic && mw.Name != "<init>")
935
// we've been redirected to a static method, so we have to copy the 'obj' into the args
936
object[] nargs = new object[original_args.Length + 1];
937
nargs[0] = original_obj;
938
original_args.CopyTo(nargs, 1);
941
for(int i = 0; i < argTypes.Length; i++)
943
if(!argTypes[i].IsUnloadable && argTypes[i].IsGhost)
945
object v = Activator.CreateInstance(argTypes[i].TypeAsSignatureType);
946
argTypes[i].GhostRefField.SetValue(v, args[i + 1]);
953
this.obj = original_obj;
954
this.args = original_args;
955
for(int i = 0; i < argTypes.Length; i++)
957
if(!argTypes[i].IsUnloadable && argTypes[i].IsGhost)
959
if(this.args == original_args)
961
this.args = (object[])args.Clone();
963
object v = Activator.CreateInstance(argTypes[i].TypeAsSignatureType);
964
argTypes[i].GhostRefField.SetValue(v, args[i]);
972
object[] nargs = new object[args.Length + 1];
973
Array.Copy(args, nargs, args.Length);
974
nargs[args.Length] = callerID;
979
internal object GetObj()
984
internal object[] GetArgs()
989
#endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
991
internal static OpCode SimpleOpCodeToOpCode(SimpleOpCode opc)
995
case SimpleOpCode.Call:
997
case SimpleOpCode.Callvirt:
998
return OpCodes.Callvirt;
999
case SimpleOpCode.Newobj:
1000
return OpCodes.Newobj;
1002
throw new InvalidOperationException();
1006
internal virtual bool IsOptionalAttributeAnnotationValue
1008
get { return false; }
1012
// placeholder for <clinit> method that exist in ClassFile but not in TypeWrapper
1013
// (because it is optimized away)
1014
sealed class DummyMethodWrapper : MethodWrapper
1016
internal DummyMethodWrapper(TypeWrapper tw)
1017
: base(tw, StringConstants.CLINIT, StringConstants.SIG_VOID, null, PrimitiveTypeWrapper.VOID, TypeWrapper.EmptyArray, Modifiers.Static, MemberFlags.None)
1021
protected override void DoLinkMethod()
1023
// we're pre-linked (because we pass the signature types to the base constructor)
1024
throw new InvalidOperationException();
1028
abstract class SmartMethodWrapper : MethodWrapper
1030
internal SmartMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
1031
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
1036
internal sealed override void EmitCall(CodeEmitter ilgen)
1042
protected virtual void CallImpl(CodeEmitter ilgen)
1044
throw new InvalidOperationException();
1047
internal sealed override void EmitCallvirt(CodeEmitter ilgen)
1050
if(DeclaringType.IsNonPrimitiveValueType)
1052
// callvirt isn't allowed on a value type
1053
// (we don't need to check for a null reference, because we're always dealing with an unboxed value)
1058
CallvirtImpl(ilgen);
1062
protected virtual void CallvirtImpl(CodeEmitter ilgen)
1064
throw new InvalidOperationException();
1067
internal sealed override void EmitNewobj(CodeEmitter ilgen)
1071
if(DeclaringType.IsNonPrimitiveValueType)
1073
DeclaringType.EmitBox(ilgen);
1077
protected virtual void NewobjImpl(CodeEmitter ilgen)
1079
throw new InvalidOperationException();
1081
#endif // STUB_GENERATOR
1084
enum SimpleOpCode : byte
1091
sealed class SimpleCallMethodWrapper : MethodWrapper
1093
private SimpleOpCode call;
1094
private SimpleOpCode callvirt;
1096
internal SimpleCallMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags, SimpleOpCode call, SimpleOpCode callvirt)
1097
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
1100
this.callvirt = callvirt;
1104
internal override void EmitCall(CodeEmitter ilgen)
1106
ilgen.Emit(SimpleOpCodeToOpCode(call), GetMethod());
1109
internal override void EmitCallvirt(CodeEmitter ilgen)
1111
ilgen.Emit(SimpleOpCodeToOpCode(callvirt), GetMethod());
1113
#endif // !STUB_GENERATOR
1116
sealed class TypicalMethodWrapper : SmartMethodWrapper
1118
internal TypicalMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
1119
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
1124
protected override void CallImpl(CodeEmitter ilgen)
1126
ilgen.Emit(OpCodes.Call, GetMethod());
1129
protected override void CallvirtImpl(CodeEmitter ilgen)
1131
ilgen.Emit(OpCodes.Callvirt, GetMethod());
1134
protected override void NewobjImpl(CodeEmitter ilgen)
1136
ilgen.Emit(OpCodes.Newobj, GetMethod());
1138
#endif // !STUB_GENERATOR
1141
sealed class GhostMethodWrapper : SmartMethodWrapper
1143
private MethodInfo ghostMethod;
1145
internal GhostMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, MethodInfo ghostMethod, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
1146
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags)
1148
// make sure we weren't handed the ghostMethod in the wrapper value type
1149
Debug.Assert(method == null || method.DeclaringType.IsInterface);
1150
this.ghostMethod = ghostMethod;
1153
private void ResolveGhostMethod()
1155
if (ghostMethod == null)
1157
ghostMethod = DeclaringType.TypeAsSignatureType.GetMethod(this.Name, this.GetParametersForDefineMethod());
1158
if (ghostMethod == null)
1160
throw new InvalidOperationException("Unable to resolve ghost method");
1166
protected override void CallvirtImpl(CodeEmitter ilgen)
1168
ResolveGhostMethod();
1169
ilgen.Emit(OpCodes.Call, ghostMethod);
1174
sealed class AccessStubMethodWrapper : SmartMethodWrapper
1176
private readonly MethodInfo stubVirtual;
1177
private readonly MethodInfo stubNonVirtual;
1179
internal AccessStubMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo core, MethodInfo stubVirtual, MethodInfo stubNonVirtual, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
1180
: base(declaringType, name, sig, core, returnType, parameterTypes, modifiers, flags)
1182
this.stubVirtual = stubVirtual;
1183
this.stubNonVirtual = stubNonVirtual;
1187
protected override void CallImpl(CodeEmitter ilgen)
1189
ilgen.Emit(OpCodes.Call, stubNonVirtual);
1192
protected override void CallvirtImpl(CodeEmitter ilgen)
1194
ilgen.Emit(OpCodes.Callvirt, stubVirtual);
1196
#endif // !STUB_GENERATOR
1199
sealed class AccessStubConstructorMethodWrapper : SmartMethodWrapper
1201
private readonly ConstructorInfo stub;
1203
internal AccessStubConstructorMethodWrapper(TypeWrapper declaringType, string sig, ConstructorInfo core, ConstructorInfo stub, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags)
1204
: base(declaringType, StringConstants.INIT, sig, core, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, flags)
1210
protected override void CallImpl(CodeEmitter ilgen)
1212
ilgen.Emit(OpCodes.Call, stub);
1215
protected override void NewobjImpl(CodeEmitter ilgen)
1217
ilgen.Emit(OpCodes.Newobj, stub);
1219
#endif // !STUB_GENERATOR
1222
abstract class FieldWrapper : MemberWrapper
1224
#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR
1225
private volatile java.lang.reflect.Field reflectionField;
1226
private sun.reflect.FieldAccessor jniAccessor;
1228
internal static readonly FieldWrapper[] EmptyArray = new FieldWrapper[0];
1229
private FieldInfo field;
1230
private TypeWrapper fieldType;
1232
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, MemberFlags flags)
1233
: base(declaringType, name, sig, modifiers, flags)
1235
Debug.Assert(name != null);
1236
Debug.Assert(sig != null);
1237
this.fieldType = fieldType;
1239
UpdateNonPublicTypeInSignatureFlag();
1242
&& DeclaringType.IsPublic
1243
&& !DeclaringType.IsInterface
1244
&& (IsPublic || (IsProtected && !DeclaringType.IsFinal))
1245
&& !DeclaringType.GetClassLoader().StrictFinalFieldSemantics
1246
&& DeclaringType is DynamicTypeWrapper
1247
&& !(this is ConstantFieldWrapper)
1248
&& !(this is DynamicPropertyFieldWrapper))
1250
SetType2FinalField();
1255
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, ExModifiers modifiers, FieldInfo field)
1256
: this(declaringType, fieldType, name, sig, modifiers.Modifiers, field,
1257
(modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None))
1261
private void UpdateNonPublicTypeInSignatureFlag()
1263
if ((IsPublic || IsProtected) && fieldType != null && !IsAccessStub)
1265
if (!fieldType.IsPublic && !fieldType.IsUnloadable)
1267
SetNonPublicTypeInSignatureFlag();
1272
internal FieldInfo GetField()
1278
[Conditional("DEBUG")]
1279
internal void AssertLinked()
1281
if(fieldType == null)
1283
Tracer.Error(Tracer.Runtime, "AssertLinked failed: " + this.DeclaringType.Name + "::" + this.Name + " (" + this.Signature + ")");
1285
Debug.Assert(fieldType != null, this.DeclaringType.Name + "::" + this.Name + " (" + this.Signature+ ")");
1288
#if !STATIC_COMPILER && !STUB_GENERATOR
1289
// NOTE used (thru IKVM.Runtime.Util.GetFieldConstantValue) by ikvmstub to find out if the
1290
// field is a constant (and if it is, to get its value)
1291
internal object GetConstant()
1294
// only primitives and string can be literals in Java (because the other "primitives" (like uint),
1295
// are treated as NonPrimitiveValueTypes)
1296
if(field != null && field.IsLiteral && (fieldType.IsPrimitive || fieldType == CoreClasses.java.lang.String.Wrapper))
1298
object val = field.GetRawConstantValue();
1299
if(field.FieldType.IsEnum)
1301
val = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(field.FieldType), val);
1303
if(fieldType.IsPrimitive)
1305
return JVM.Box(val);
1312
internal static FieldWrapper FromField(object field)
1317
java.lang.reflect.Field f = (java.lang.reflect.Field)field;
1318
int slot = f._slot();
1321
// it's a Field created by Unsafe.objectFieldOffset(Class,String) so we must resolve based on the name
1322
foreach (FieldWrapper fw in TypeWrapper.FromClass(f.getDeclaringClass()).GetFields())
1324
if (fw.Name == f.getName())
1330
return TypeWrapper.FromClass(f.getDeclaringClass()).GetFields()[slot];
1334
internal object ToField(bool copy)
1336
return ToField(copy, null);
1339
internal object ToField(bool copy, int? fieldIndex)
1344
java.lang.reflect.Field field = reflectionField;
1347
const Modifiers ReflectionFieldModifiersMask = Modifiers.Public | Modifiers.Private | Modifiers.Protected | Modifiers.Static
1348
| Modifiers.Final | Modifiers.Volatile | Modifiers.Transient | Modifiers.Synthetic | Modifiers.Enum;
1350
field = new java.lang.reflect.Field(
1351
this.DeclaringType.ClassObject,
1353
this.FieldTypeWrapper.EnsureLoadable(this.DeclaringType.GetClassLoader()).ClassObject,
1354
(int)(this.Modifiers & ReflectionFieldModifiersMask) | (this.IsInternal ? 0x40000000 : 0),
1355
fieldIndex ?? Array.IndexOf(this.DeclaringType.GetFields(), this),
1356
this.DeclaringType.GetGenericFieldSignature(this),
1362
if (reflectionField == null)
1364
reflectionField = field;
1368
field = reflectionField;
1373
field = field.copy();
1376
#endif // FIRST_PASS
1378
#endif // !STATIC_COMPILER && !STUB_GENERATOR
1380
[System.Security.SecurityCritical]
1381
internal static FieldWrapper FromCookie(IntPtr cookie)
1383
return (FieldWrapper)FromCookieImpl(cookie);
1386
internal TypeWrapper FieldTypeWrapper
1396
internal void EmitGet(CodeEmitter ilgen)
1402
protected abstract void EmitGetImpl(CodeEmitter ilgen);
1404
internal void EmitSet(CodeEmitter ilgen)
1410
protected abstract void EmitSetImpl(CodeEmitter ilgen);
1411
#endif // !STUB_GENERATOR
1415
internal bool IsLinked
1417
get { return fieldType != null; }
1421
internal void Link()
1425
if(fieldType != null)
1430
TypeWrapper fld = this.DeclaringType.GetClassLoader().FieldTypeWrapperFromSigNoThrow(Signature);
1435
// critical code in the finally block to avoid Thread.Abort interrupting the thread
1439
if(fieldType == null)
1442
UpdateNonPublicTypeInSignatureFlag();
1445
field = this.DeclaringType.LinkField(this);
1449
// HACK if linking fails, we unlink to make sure
1450
// that the next link attempt will fail again
1459
internal bool IsVolatile
1463
return (Modifiers & Modifiers.Volatile) != 0;
1467
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
1469
// volatile long & double field accesses must be made atomic
1470
if((modifiers.Modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D"))
1472
return new VolatileLongDoubleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
1474
return new SimpleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
1477
#if !STATIC_COMPILER && !STUB_GENERATOR
1478
internal virtual void ResolveField()
1480
FieldBuilder fb = field as FieldBuilder;
1483
field = field.Module.ResolveField(fb.GetToken().Token);
1487
internal object GetFieldAccessorJNI()
1492
if (jniAccessor == null)
1494
jniAccessor = IKVM.NativeCode.sun.reflect.ReflectionFactory.NewFieldAccessorJNI(this);
1499
#endif // !STATIC_COMPILER && !STUB_GENERATOR
1502
sealed class SimpleFieldWrapper : FieldWrapper
1504
internal SimpleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
1505
: base(declaringType, fieldType, name, sig, modifiers, fi)
1507
Debug.Assert(!(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG) || !IsVolatile);
1511
protected override void EmitGetImpl(CodeEmitter ilgen)
1513
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
1515
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
1519
ilgen.Emit(OpCodes.Volatile);
1521
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
1524
protected override void EmitSetImpl(CodeEmitter ilgen)
1526
FieldInfo fi = GetField();
1527
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
1529
CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType);
1530
ilgen.Emit(OpCodes.Stloc, temp);
1531
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
1532
ilgen.Emit(OpCodes.Ldloc, temp);
1536
ilgen.Emit(OpCodes.Volatile);
1538
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
1541
ilgen.EmitMemoryBarrier();
1544
#endif // !STUB_GENERATOR
1547
sealed class VolatileLongDoubleFieldWrapper : FieldWrapper
1549
internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
1550
: base(declaringType, fieldType, name, sig, modifiers, fi)
1552
Debug.Assert(IsVolatile);
1553
Debug.Assert(sig == "J" || sig == "D");
1557
protected override void EmitGetImpl(CodeEmitter ilgen)
1559
FieldInfo fi = GetField();
1562
ilgen.Emit(OpCodes.Ldsflda, fi);
1566
if(DeclaringType.IsNonPrimitiveValueType)
1568
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
1570
ilgen.Emit(OpCodes.Ldflda, fi);
1572
if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
1574
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadDouble);
1578
Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG);
1579
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadLong);
1583
protected override void EmitSetImpl(CodeEmitter ilgen)
1585
FieldInfo fi = GetField();
1586
CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType);
1587
ilgen.Emit(OpCodes.Stloc, temp);
1590
ilgen.Emit(OpCodes.Ldsflda, fi);
1594
if(DeclaringType.IsNonPrimitiveValueType)
1596
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
1598
ilgen.Emit(OpCodes.Ldflda, fi);
1600
ilgen.Emit(OpCodes.Ldloc, temp);
1601
if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
1603
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteDouble);
1607
Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG);
1608
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteLong);
1611
#endif // !STUB_GENERATOR
1615
// this class represents a .NET property defined in Java with the ikvm.lang.Property annotation
1616
sealed class DynamicPropertyFieldWrapper : FieldWrapper
1618
private readonly MethodWrapper getter;
1619
private readonly MethodWrapper setter;
1620
private PropertyBuilder pb;
1622
private MethodWrapper GetMethod(string name, string sig, bool isstatic)
1626
MethodWrapper mw = this.DeclaringType.GetMethodWrapper(name, sig, false);
1627
if(mw != null && mw.IsStatic == isstatic)
1629
mw.IsPropertyAccessor = true;
1632
Tracer.Error(Tracer.Compiler, "Property '{0}' accessor '{1}' not found in class '{2}'", this.Name, name, this.DeclaringType.Name);
1637
internal DynamicPropertyFieldWrapper(TypeWrapper declaringType, ClassFile.Field fld)
1638
: base(declaringType, null, fld.Name, fld.Signature, new ExModifiers(fld.Modifiers, fld.IsInternal), null)
1640
getter = GetMethod(fld.PropertyGetter, "()" + fld.Signature, fld.IsStatic);
1641
setter = GetMethod(fld.PropertySetter, "(" + fld.Signature + ")V", fld.IsStatic);
1644
#if !STATIC_COMPILER && !FIRST_PASS
1645
internal override void ResolveField()
1649
getter.ResolveMethod();
1653
setter.ResolveMethod();
1658
internal PropertyBuilder GetPropertyBuilder()
1664
internal void DoLink(TypeBuilder tb)
1674
pb = tb.DefineProperty(this.Name, PropertyAttributes.None, this.FieldTypeWrapper.TypeAsSignatureType, Type.EmptyTypes);
1677
pb.SetGetMethod((MethodBuilder)getter.GetMethod());
1681
pb.SetSetMethod((MethodBuilder)setter.GetMethod());
1684
AttributeHelper.SetModifiers(pb, this.Modifiers, this.IsInternal);
1688
protected override void EmitGetImpl(CodeEmitter ilgen)
1692
EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
1694
else if(getter.IsStatic)
1696
getter.EmitCall(ilgen);
1700
getter.EmitCallvirt(ilgen);
1704
internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, bool isStatic)
1706
// HACK the branch around the throw is to keep the verifier happy
1707
CodeEmitterLabel label = ilgen.DefineLabel();
1708
ilgen.Emit(OpCodes.Ldc_I4_0);
1709
ilgen.EmitBrtrue(label);
1710
ilgen.EmitThrow("java.lang.NoSuchMethodError");
1711
ilgen.MarkLabel(label);
1714
ilgen.Emit(OpCodes.Pop);
1716
ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(type.TypeAsLocalOrStackType));
1719
protected override void EmitSetImpl(CodeEmitter ilgen)
1725
ilgen.Emit(OpCodes.Pop);
1728
ilgen.Emit(OpCodes.Pop);
1733
EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
1736
else if(setter.IsStatic)
1738
setter.EmitCall(ilgen);
1742
setter.EmitCallvirt(ilgen);
1746
internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, bool isStatic)
1748
// HACK the branch around the throw is to keep the verifier happy
1749
CodeEmitterLabel label = ilgen.DefineLabel();
1750
ilgen.Emit(OpCodes.Ldc_I4_0);
1751
ilgen.EmitBrtrue(label);
1752
ilgen.EmitThrow("java.lang.NoSuchMethodError");
1753
ilgen.MarkLabel(label);
1754
ilgen.Emit(OpCodes.Pop);
1757
ilgen.Emit(OpCodes.Pop);
1761
#endif // !STUB_GENERATOR
1763
// this class represents a .NET property defined in Java with the ikvm.lang.Property annotation
1764
sealed class CompiledPropertyFieldWrapper : FieldWrapper
1766
private readonly PropertyInfo property;
1768
internal CompiledPropertyFieldWrapper(TypeWrapper declaringType, PropertyInfo property, ExModifiers modifiers)
1769
: base(declaringType, ClassLoaderWrapper.GetWrapperFromType(property.PropertyType), property.Name, ClassLoaderWrapper.GetWrapperFromType(property.PropertyType).SigName, modifiers, null)
1771
this.property = property;
1775
protected override void EmitGetImpl(CodeEmitter ilgen)
1777
MethodInfo getter = property.GetGetMethod(true);
1780
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic);
1782
else if(getter.IsStatic)
1784
ilgen.Emit(OpCodes.Call, getter);
1788
ilgen.Emit(OpCodes.Callvirt, getter);
1792
protected override void EmitSetImpl(CodeEmitter ilgen)
1794
MethodInfo setter = property.GetSetMethod(true);
1799
ilgen.Emit(OpCodes.Pop);
1802
ilgen.Emit(OpCodes.Pop);
1807
DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic);
1810
else if(setter.IsStatic)
1812
ilgen.Emit(OpCodes.Call, setter);
1816
ilgen.Emit(OpCodes.Callvirt, setter);
1819
#endif // !STUB_GENERATOR
1821
internal PropertyInfo GetProperty()
1827
sealed class ConstantFieldWrapper : FieldWrapper
1829
// NOTE this field wrapper can resprent a .NET enum, but in that case "constant" contains the raw constant value (i.e. the boxed underlying primitive value, not a boxed enum)
1830
private object constant;
1832
internal ConstantFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, object constant, MemberFlags flags)
1833
: base(declaringType, fieldType, name, sig, modifiers, field, flags)
1835
Debug.Assert(IsStatic);
1836
Debug.Assert(constant == null || constant.GetType().IsPrimitive || constant is string);
1837
this.constant = constant;
1841
protected override void EmitGetImpl(CodeEmitter ilgen)
1843
// Reading a field should trigger the cctor, but since we're inlining the value
1844
// we have to trigger it explicitly
1845
DeclaringType.EmitRunClassConstructor(ilgen);
1847
// NOTE even though you're not supposed to access a constant static final (the compiler is supposed
1848
// to inline them), we have to support it (because it does happen, e.g. if the field becomes final
1849
// after the referencing class was compiled, or when we're accessing an unsigned primitive .NET field)
1850
object v = GetConstantValue();
1853
ilgen.Emit(OpCodes.Ldnull);
1855
else if(constant is int ||
1856
constant is short ||
1857
constant is ushort ||
1859
constant is sbyte ||
1863
ilgen.EmitLdc_I4(((IConvertible)constant).ToInt32(null));
1865
else if(constant is string)
1867
ilgen.Emit(OpCodes.Ldstr, (string)constant);
1869
else if(constant is float)
1871
ilgen.EmitLdc_R4((float)constant);
1873
else if(constant is double)
1875
ilgen.EmitLdc_R8((double)constant);
1877
else if(constant is long)
1879
ilgen.EmitLdc_I8((long)constant);
1881
else if(constant is uint)
1883
ilgen.EmitLdc_I4(unchecked((int)((IConvertible)constant).ToUInt32(null)));
1885
else if(constant is ulong)
1887
ilgen.EmitLdc_I8(unchecked((long)(ulong)constant));
1891
throw new InvalidOperationException(constant.GetType().FullName);
1895
protected override void EmitSetImpl(CodeEmitter ilgen)
1897
// when constant static final fields are updated, the JIT normally doesn't see that (because the
1898
// constant value is inlined), so we emulate that behavior by emitting a Pop
1899
ilgen.Emit(OpCodes.Pop);
1901
#endif // !STUB_GENERATOR
1903
internal object GetConstantValue()
1905
if(constant == null)
1907
FieldInfo field = GetField();
1908
constant = field.GetRawConstantValue();
1914
sealed class CompiledAccessStubFieldWrapper : FieldWrapper
1916
private MethodInfo getter;
1917
private MethodInfo setter;
1919
private static Modifiers GetModifiers(PropertyInfo property)
1921
// NOTE we only support the subset of modifiers that is expected for "access stub" properties
1922
MethodInfo getter = property.GetGetMethod(true);
1923
Modifiers modifiers = getter.IsPublic ? Modifiers.Public : Modifiers.Protected;
1924
if(!property.CanWrite)
1926
modifiers |= Modifiers.Final;
1930
modifiers |= Modifiers.Static;
1935
// constructor for type 1 access stubs
1936
internal CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, TypeWrapper propertyType)
1937
: this(wrapper, property, null, propertyType, GetModifiers(property), MemberFlags.HideFromReflection | MemberFlags.AccessStub)
1941
// constructor for type 2 access stubs
1942
internal CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, FieldInfo field, TypeWrapper propertyType)
1943
: this(wrapper, property, field, propertyType, AttributeHelper.GetModifiersAttribute(property).Modifiers, MemberFlags.AccessStub)
1947
private CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, FieldInfo field, TypeWrapper propertyType, Modifiers modifiers, MemberFlags flags)
1948
: base(wrapper, propertyType, property.Name, propertyType.SigName, modifiers, field, flags)
1950
this.getter = property.GetGetMethod(true);
1951
this.setter = property.GetSetMethod(true);
1955
protected override void EmitGetImpl(CodeEmitter ilgen)
1957
ilgen.Emit(OpCodes.Call, getter);
1960
protected override void EmitSetImpl(CodeEmitter ilgen)
1962
ilgen.Emit(OpCodes.Call, setter);
1964
#endif // !STUB_GENERATOR