diff options
Diffstat (limited to 'runtime/MemberWrapper.cs')
-rw-r--r-- | runtime/MemberWrapper.cs | 2127 |
1 files changed, 0 insertions, 2127 deletions
diff --git a/runtime/MemberWrapper.cs b/runtime/MemberWrapper.cs deleted file mode 100644 index 420a2dcc..00000000 --- a/runtime/MemberWrapper.cs +++ /dev/null @@ -1,2127 +0,0 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -#if STATIC_COMPILER || STUB_GENERATOR -using IKVM.Reflection; -using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; -#else -using System.Reflection; -using System.Reflection.Emit; -#endif -using System.Diagnostics; -using IKVM.Attributes; -using System.Threading; -using System.Runtime.InteropServices; - -namespace IKVM.Internal -{ - [Flags] - enum MemberFlags : short - { - None = 0, - HideFromReflection = 1, - ExplicitOverride = 2, - MirandaMethod = 8, - AccessStub = 16, - InternalAccess = 32, // member has "internal" access (@ikvm.lang.Internal) - PropertyAccessor = 64, - Intrinsic = 128, - CallerID = 256, - NonPublicTypeInSignature = 512, // this flag is only available after linking and is not set for access stubs - DelegateInvokeWithByRefParameter = 1024, - Type2FinalField = 2048, - } - - abstract class MemberWrapper - { - private HandleWrapper handle; - private readonly TypeWrapper declaringType; - protected readonly Modifiers modifiers; - private MemberFlags flags; - private readonly string name; - private readonly string sig; - - private sealed class HandleWrapper - { - internal readonly IntPtr Value; - - [System.Security.SecurityCritical] - internal HandleWrapper(MemberWrapper obj) - { - Value = (IntPtr)GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection); - } - -#if CLASSGC - [System.Security.SecuritySafeCritical] - ~HandleWrapper() - { - if (!Environment.HasShutdownStarted) - { - GCHandle h = (GCHandle)Value; - if (h.Target == null) - { - h.Free(); - } - else - { - GC.ReRegisterForFinalize(this); - } - } - } -#endif - } - - protected MemberWrapper(TypeWrapper declaringType, string name, string sig, Modifiers modifiers, MemberFlags flags) - { - Debug.Assert(declaringType != null); - this.declaringType = declaringType; - this.name = String.Intern(name); - this.sig = String.Intern(sig); - this.modifiers = modifiers; - this.flags = flags; - } - - internal IntPtr Cookie - { - [System.Security.SecurityCritical] - get - { - lock(this) - { - if(handle == null) - { - handle = new HandleWrapper(this); - } - } - return handle.Value; - } - } - - [System.Security.SecurityCritical] - internal static MemberWrapper FromCookieImpl(IntPtr cookie) - { - return (MemberWrapper)GCHandle.FromIntPtr(cookie).Target; - } - - internal TypeWrapper DeclaringType - { - get - { - return declaringType; - } - } - - internal string Name - { - get - { - return name; - } - } - - internal string Signature - { - get - { - return sig; - } - } - - internal bool IsAccessibleFrom(TypeWrapper referencedType, TypeWrapper caller, TypeWrapper instance) - { - if(referencedType.IsAccessibleFrom(caller)) - { - return ( - caller == DeclaringType || - IsPublicOrProtectedMemberAccessible(caller, instance) || - (IsInternal && DeclaringType.InternalsVisibleTo(caller)) || - (!IsPrivate && DeclaringType.IsPackageAccessibleFrom(caller))) - // The JVM supports accessing members that have non-public types in their signature from another package, - // but the CLI doesn't. It would be nice if we worked around that by emitting extra accessors, but for now - // we'll simply disallow such access across assemblies (unless the appropriate InternalsVisibleToAttribute exists). - && (!(HasNonPublicTypeInSignature || IsType2FinalField) || InPracticeInternalsVisibleTo(caller)); - } - return false; - } - - private bool IsPublicOrProtectedMemberAccessible(TypeWrapper caller, TypeWrapper instance) - { - if (IsPublic || (IsProtected && caller.IsSubTypeOf(DeclaringType) && (IsStatic || instance.IsUnloadable || instance.IsSubTypeOf(caller)))) - { - return DeclaringType.IsPublic || InPracticeInternalsVisibleTo(caller); - } - return false; - } - - private bool InPracticeInternalsVisibleTo(TypeWrapper caller) - { -#if !STATIC_COMPILER - if (DeclaringType.TypeAsTBD.Assembly.Equals(caller.TypeAsTBD.Assembly)) - { - // both the caller and the declaring type are in the same assembly - // so we know that the internals are visible - // (this handles the case where we're running in dynamic mode) - return true; - } -#endif -#if CLASSGC - if (DeclaringType.IsDynamic) - { - // if we are dynamic, we can just become friends with the caller - DeclaringType.GetClassLoader().GetTypeWrapperFactory().AddInternalsVisibleTo(caller.TypeAsTBD.Assembly); - return true; - } -#endif - return DeclaringType.InternalsVisibleTo(caller); - } - - internal bool IsHideFromReflection - { - get - { - return (flags & MemberFlags.HideFromReflection) != 0; - } - } - - internal bool IsExplicitOverride - { - get - { - return (flags & MemberFlags.ExplicitOverride) != 0; - } - } - - internal bool IsMirandaMethod - { - get - { - return (flags & MemberFlags.MirandaMethod) != 0; - } - } - - internal bool IsAccessStub - { - get - { - return (flags & MemberFlags.AccessStub) != 0; - } - } - - internal bool IsPropertyAccessor - { - get - { - return (flags & MemberFlags.PropertyAccessor) != 0; - } - set - { - // this is unsynchronized, so it may only be called during the JavaTypeImpl constructor - if(value) - { - flags |= MemberFlags.PropertyAccessor; - } - else - { - flags &= ~MemberFlags.PropertyAccessor; - } - } - } - - internal bool IsIntrinsic - { - get - { - return (flags & MemberFlags.Intrinsic) != 0; - } - } - - protected void SetIntrinsicFlag() - { - flags |= MemberFlags.Intrinsic; - } - - protected void SetNonPublicTypeInSignatureFlag() - { - flags |= MemberFlags.NonPublicTypeInSignature; - } - - internal bool HasNonPublicTypeInSignature - { - get { return (flags & MemberFlags.NonPublicTypeInSignature) != 0; } - } - - protected void SetType2FinalField() - { - flags |= MemberFlags.Type2FinalField; - } - - internal bool IsType2FinalField - { - get { return (flags & MemberFlags.Type2FinalField) != 0; } - } - - internal bool HasCallerID - { - get - { - return (flags & MemberFlags.CallerID) != 0; - } - } - - internal bool IsDelegateInvokeWithByRefParameter - { - get { return (flags & MemberFlags.DelegateInvokeWithByRefParameter) != 0; } - } - - internal Modifiers Modifiers - { - get - { - return modifiers; - } - } - - internal bool IsStatic - { - get - { - return (modifiers & Modifiers.Static) != 0; - } - } - - internal bool IsInternal - { - get - { - return (flags & MemberFlags.InternalAccess) != 0; - } - } - - internal bool IsPublic - { - get - { - return (modifiers & Modifiers.Public) != 0; - } - } - - internal bool IsPrivate - { - get - { - return (modifiers & Modifiers.Private) != 0; - } - } - - internal bool IsProtected - { - get - { - return (modifiers & Modifiers.Protected) != 0; - } - } - - internal bool IsFinal - { - get - { - return (modifiers & Modifiers.Final) != 0; - } - } - } - - abstract class MethodWrapper : MemberWrapper - { -#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR - private volatile java.lang.reflect.Executable reflectionMethod; -#endif - internal static readonly MethodWrapper[] EmptyArray = new MethodWrapper[0]; - private MethodBase method; - private string[] declaredExceptions; - private TypeWrapper returnTypeWrapper; - private TypeWrapper[] parameterTypeWrappers; - -#if EMITTERS - internal virtual void EmitCall(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } - - internal virtual void EmitCallvirt(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } - - internal virtual void EmitCallvirtReflect(CodeEmitter ilgen) - { - EmitCallvirt(ilgen); - } - - internal virtual void EmitNewobj(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } - - internal virtual bool EmitIntrinsic(EmitIntrinsicContext context) - { - return Intrinsics.Emit(context); - } -#endif // EMITTERS - - internal virtual bool IsDynamicOnly - { - get - { - return false; - } - } - - internal MethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, modifiers, flags) - { - Profiler.Count("MethodWrapper"); - this.method = method; - Debug.Assert(((returnType == null) == (parameterTypes == null)) || (returnType == PrimitiveTypeWrapper.VOID)); - this.returnTypeWrapper = returnType; - this.parameterTypeWrappers = parameterTypes; - if (Intrinsics.IsIntrinsic(this)) - { - SetIntrinsicFlag(); - } - UpdateNonPublicTypeInSignatureFlag(); - } - - private void UpdateNonPublicTypeInSignatureFlag() - { - if ((IsPublic || IsProtected) && (returnTypeWrapper != null && parameterTypeWrappers != null) && !(this is AccessStubMethodWrapper) && !(this is AccessStubConstructorMethodWrapper)) - { - if (!returnTypeWrapper.IsPublic && !returnTypeWrapper.IsUnloadable) - { - SetNonPublicTypeInSignatureFlag(); - } - else - { - foreach (TypeWrapper tw in parameterTypeWrappers) - { - if (!tw.IsPublic && !tw.IsUnloadable) - { - SetNonPublicTypeInSignatureFlag(); - break; - } - } - } - } - } - - internal void SetDeclaredExceptions(string[] exceptions) - { - if(exceptions == null) - { - exceptions = new string[0]; - } - this.declaredExceptions = (string[])exceptions.Clone(); - } - - internal string[] GetDeclaredExceptions() - { - return declaredExceptions; - } - -#if !STATIC_COMPILER && !STUB_GENERATOR - internal java.lang.reflect.Executable ToMethodOrConstructor(bool copy) - { -#if FIRST_PASS - return null; -#else - java.lang.reflect.Executable method = reflectionMethod; - if (method == null) - { - Link(); - ClassLoaderWrapper loader = this.DeclaringType.GetClassLoader(); - TypeWrapper[] argTypes = GetParameters(); - java.lang.Class[] parameterTypes = new java.lang.Class[argTypes.Length]; - for (int i = 0; i < argTypes.Length; i++) - { - parameterTypes[i] = argTypes[i].EnsureLoadable(loader).ClassObject; - } - java.lang.Class[] checkedExceptions = GetExceptions(); - if (this.IsConstructor) - { - method = new java.lang.reflect.Constructor( - this.DeclaringType.ClassObject, - parameterTypes, - checkedExceptions, - (int)this.Modifiers | (this.IsInternal ? 0x40000000 : 0), - Array.IndexOf(this.DeclaringType.GetMethods(), this), - this.DeclaringType.GetGenericMethodSignature(this), - null, - null - ); - } - else - { - method = new java.lang.reflect.Method( - this.DeclaringType.ClassObject, - this.Name, - parameterTypes, - this.ReturnType.EnsureLoadable(loader).ClassObject, - checkedExceptions, - (int)this.Modifiers | (this.IsInternal ? 0x40000000 : 0), - Array.IndexOf(this.DeclaringType.GetMethods(), this), - this.DeclaringType.GetGenericMethodSignature(this), - null, - null, - null - ); - } - lock (this) - { - if (reflectionMethod == null) - { - reflectionMethod = method; - } - else - { - method = reflectionMethod; - } - } - } - if (copy) - { - java.lang.reflect.Constructor ctor = method as java.lang.reflect.Constructor; - if (ctor != null) - { - return ctor.copy(); - } - return ((java.lang.reflect.Method)method).copy(); - } - return method; -#endif - } - -#if !FIRST_PASS - private java.lang.Class[] GetExceptions() - { - string[] classes = declaredExceptions; - Type[] types = Type.EmptyTypes; - if (classes == null) - { - // NOTE if method is a MethodBuilder, GetCustomAttributes doesn't work (and if - // the method had any declared exceptions, the declaredExceptions field would have - // been set) - if (method != null && !(method is MethodBuilder)) - { - ThrowsAttribute attr = AttributeHelper.GetThrows(method); - if (attr != null) - { - classes = attr.classes; - types = attr.types; - } - } - } - if (classes != null) - { - java.lang.Class[] array = new java.lang.Class[classes.Length]; - for (int i = 0; i < classes.Length; i++) - { - array[i] = this.DeclaringType.GetClassLoader().LoadClassByDottedName(classes[i]).ClassObject; - } - return array; - } - else - { - java.lang.Class[] array = new java.lang.Class[types.Length]; - for (int i = 0; i < types.Length; i++) - { - array[i] = types[i]; - } - return array; - } - } -#endif // !FIRST_PASS - - internal static MethodWrapper FromExecutable(java.lang.reflect.Executable executable) - { -#if FIRST_PASS - return null; -#else - return TypeWrapper.FromClass(executable.getDeclaringClass()).GetMethods()[executable._slot()]; -#endif - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR - - [System.Security.SecurityCritical] - internal static MethodWrapper FromCookie(IntPtr cookie) - { - return (MethodWrapper)FromCookieImpl(cookie); - } - - internal bool IsLinked - { - get - { - return parameterTypeWrappers != null; - } - } - - internal void Link() - { - lock(this) - { - if(parameterTypeWrappers != null) - { - return; - } - } - ClassLoaderWrapper loader = this.DeclaringType.GetClassLoader(); - TypeWrapper ret = loader.RetTypeWrapperFromSigNoThrow(Signature); - TypeWrapper[] parameters = loader.ArgTypeWrapperListFromSigNoThrow(Signature); - lock(this) - { - try - { - // critical code in the finally block to avoid Thread.Abort interrupting the thread - } - finally - { - if(parameterTypeWrappers == null) - { - Debug.Assert(returnTypeWrapper == null || returnTypeWrapper == PrimitiveTypeWrapper.VOID); - returnTypeWrapper = ret; - parameterTypeWrappers = parameters; - UpdateNonPublicTypeInSignatureFlag(); - if(method == null) - { - try - { - DoLinkMethod(); - } - catch - { - // HACK if linking fails, we unlink to make sure - // that the next link attempt will fail again - returnTypeWrapper = null; - parameterTypeWrappers = null; - throw; - } - } - } - } - } - } - - protected virtual void DoLinkMethod() - { - method = this.DeclaringType.LinkMethod(this); - } - - [Conditional("DEBUG")] - internal void AssertLinked() - { - if(!(parameterTypeWrappers != null && returnTypeWrapper != null)) - { - Tracer.Error(Tracer.Runtime, "AssertLinked failed: " + this.DeclaringType.Name + "::" + this.Name + this.Signature); - } - Debug.Assert(parameterTypeWrappers != null && returnTypeWrapper != null, this.DeclaringType.Name + "::" + this.Name + this.Signature); - } - - internal TypeWrapper ReturnType - { - get - { - AssertLinked(); - return returnTypeWrapper; - } - } - - internal TypeWrapper[] GetParameters() - { - AssertLinked(); - return parameterTypeWrappers; - } - -#if !STUB_GENERATOR - internal DefineMethodHelper GetDefineMethodHelper() - { - return new DefineMethodHelper(this); - } -#endif - - internal Type ReturnTypeForDefineMethod - { - get - { - return ReturnType.TypeAsSignatureType; - } - } - - internal Type[] GetParametersForDefineMethod() - { - TypeWrapper[] wrappers = GetParameters(); - int len = wrappers.Length; - if(HasCallerID) - { - len++; - } - Type[] temp = new Type[len]; - for(int i = 0; i < wrappers.Length; i++) - { - temp[i] = wrappers[i].TypeAsSignatureType; - } - if(HasCallerID) - { - temp[len - 1] = CoreClasses.ikvm.@internal.CallerID.Wrapper.TypeAsSignatureType; - } - return temp; - } - - // we expose the underlying MethodBase object, - // for Java types, this is the method that contains the compiled Java bytecode - // for remapped types, this is the mbCore method (not the helper) - // Note that for some artificial methods (notably wrap() in enums), method is null - internal MethodBase GetMethod() - { - AssertLinked(); - return method; - } - - internal string RealName - { - get - { - AssertLinked(); - return method.Name; - } - } - - internal bool IsAbstract - { - get - { - return (Modifiers & Modifiers.Abstract) != 0; - } - } - - internal bool RequiresNonVirtualDispatcher - { - get - { - return !IsConstructor - && !IsStatic - && !IsPrivate - && !IsAbstract - && !IsFinal - && !DeclaringType.IsFinal; - } - } - -#if !STATIC_COMPILER && !STUB_GENERATOR - internal Type GetDelegateType() - { - TypeWrapper[] paramTypes = GetParameters(); - if (paramTypes.Length > MethodHandleUtil.MaxArity) - { - Type type = DeclaringType.TypeAsBaseType.Assembly.GetType( - ReturnType == PrimitiveTypeWrapper.VOID ? "__<>NVIV`" + paramTypes.Length : "__<>NVI`" + (paramTypes.Length + 1)); - if (type == null) - { - type = DeclaringType.GetClassLoader().GetTypeWrapperFactory().DefineDelegate(paramTypes.Length, ReturnType == PrimitiveTypeWrapper.VOID); - } - Type[] types = new Type[paramTypes.Length + (ReturnType == PrimitiveTypeWrapper.VOID ? 0 : 1)]; - for (int i = 0; i < paramTypes.Length; i++) - { - types[i] = paramTypes[i].TypeAsSignatureType; - } - if (ReturnType != PrimitiveTypeWrapper.VOID) - { - types[types.Length - 1] = ReturnType.TypeAsSignatureType; - } - return type.MakeGenericType(types); - } - return MethodHandleUtil.CreateMemberWrapperDelegateType(paramTypes, ReturnType); - } - - internal void ResolveMethod() - { -#if !FIRST_PASS - // if we've still got the builder object, we need to replace it with the real thing before we can call it - MethodBuilder mb = method as MethodBuilder; - if (mb != null) - { - method = mb.Module.ResolveMethod(mb.GetToken().Token); - } -#endif - } - - [HideFromJava] - internal virtual object InvokeNonvirtualRemapped(object obj, object[] args) - { - throw new InvalidOperationException(); - } - - [HideFromJava] - protected static object InvokeAndUnwrapException(MethodBase mb, object obj, object[] args) - { -#if FIRST_PASS - return null; -#else - try - { - return mb.Invoke(obj, args); - } - catch (TargetInvocationException x) - { - throw ikvm.runtime.Util.mapException(x.InnerException); - } -#endif - } - - [HideFromJava] - internal virtual object Invoke(object obj, object[] args) - { - return InvokeAndUnwrapException(method, obj, args); - } - - [HideFromJava] - internal virtual object CreateInstance(object[] args) - { -#if FIRST_PASS - return null; -#else - try - { - return ((ConstructorInfo)method).Invoke(args); - } - catch (TargetInvocationException x) - { - throw ikvm.runtime.Util.mapException(x.InnerException); - } -#endif - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR - - internal static OpCode SimpleOpCodeToOpCode(SimpleOpCode opc) - { - switch(opc) - { - case SimpleOpCode.Call: - return OpCodes.Call; - case SimpleOpCode.Callvirt: - return OpCodes.Callvirt; - case SimpleOpCode.Newobj: - return OpCodes.Newobj; - default: - throw new InvalidOperationException(); - } - } - - internal virtual bool IsOptionalAttributeAnnotationValue - { - get { return false; } - } - - internal bool IsConstructor - { - get { return (object)Name == (object)StringConstants.INIT; } - } - - internal bool IsVirtual - { - get - { - return (modifiers & (Modifiers.Static | Modifiers.Private)) == 0 - && !IsConstructor; - } - } - } - - // placeholder for <clinit> method that exist in ClassFile but not in TypeWrapper - // (because it is optimized away) - sealed class DummyMethodWrapper : MethodWrapper - { - internal DummyMethodWrapper(TypeWrapper tw) - : base(tw, StringConstants.CLINIT, StringConstants.SIG_VOID, null, PrimitiveTypeWrapper.VOID, TypeWrapper.EmptyArray, Modifiers.Static, MemberFlags.None) - { - } - - protected override void DoLinkMethod() - { - // we're pre-linked (because we pass the signature types to the base constructor) - throw new InvalidOperationException(); - } - } - - abstract class SmartMethodWrapper : MethodWrapper - { - internal SmartMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) - { - } - -#if EMITTERS - internal sealed override void EmitCall(CodeEmitter ilgen) - { - AssertLinked(); - CallImpl(ilgen); - } - - protected virtual void CallImpl(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } - - internal sealed override void EmitCallvirt(CodeEmitter ilgen) - { - AssertLinked(); - if(DeclaringType.IsNonPrimitiveValueType) - { - // callvirt isn't allowed on a value type - // (we don't need to check for a null reference, because we're always dealing with an unboxed value) - CallImpl(ilgen); - } - else - { - CallvirtImpl(ilgen); - } - } - - protected virtual void CallvirtImpl(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } - - internal sealed override void EmitNewobj(CodeEmitter ilgen) - { - AssertLinked(); - NewobjImpl(ilgen); - if(DeclaringType.IsNonPrimitiveValueType) - { - DeclaringType.EmitBox(ilgen); - } - } - - protected virtual void NewobjImpl(CodeEmitter ilgen) - { - throw new InvalidOperationException(); - } -#endif // EMITTERS - } - - enum SimpleOpCode : byte - { - Call, - Callvirt, - Newobj - } - - sealed class SimpleCallMethodWrapper : MethodWrapper - { - private readonly SimpleOpCode call; - private readonly SimpleOpCode callvirt; - - internal SimpleCallMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags, SimpleOpCode call, SimpleOpCode callvirt) - : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) - { - this.call = call; - this.callvirt = callvirt; - } - -#if EMITTERS - internal override void EmitCall(CodeEmitter ilgen) - { - ilgen.Emit(SimpleOpCodeToOpCode(call), GetMethod()); - } - - internal override void EmitCallvirt(CodeEmitter ilgen) - { - ilgen.Emit(SimpleOpCodeToOpCode(callvirt), GetMethod()); - } -#endif // EMITTERS - } - - sealed class TypicalMethodWrapper : SmartMethodWrapper - { - internal TypicalMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) - { - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, GetMethod()); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Callvirt, GetMethod()); - } - - protected override void NewobjImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Newobj, GetMethod()); - } -#endif // EMITTERS - } - - abstract class MirandaMethodWrapper : SmartMethodWrapper - { - private readonly MethodWrapper ifmethod; - - private MirandaMethodWrapper(TypeWrapper declaringType, MethodWrapper ifmethod, Modifiers modifiers) - : base(declaringType, ifmethod.Name, ifmethod.Signature, null, null, null, modifiers, MemberFlags.HideFromReflection | MemberFlags.MirandaMethod) - { - this.ifmethod = ifmethod; - } - - private sealed class AbstractMirandaMethodWrapper : MirandaMethodWrapper - { - internal AbstractMirandaMethodWrapper(TypeWrapper declaringType, MethodWrapper ifmethod) - : base(declaringType, ifmethod, Modifiers.Public | Modifiers.Abstract) - { - } - } - - private sealed class DefaultMirandaMethodWrapper : MirandaMethodWrapper - { - internal DefaultMirandaMethodWrapper(TypeWrapper declaringType, MethodWrapper ifmethod) - : base(declaringType, ifmethod, Modifiers.Public) - { - } - } - - private sealed class ErrorMirandaMethodWrapper : MirandaMethodWrapper - { - private string error; - - internal ErrorMirandaMethodWrapper(TypeWrapper declaringType, MethodWrapper ifmethod, string error) - : base(declaringType, ifmethod, Modifiers.Public) - { - this.error = error; - } - - protected override MirandaMethodWrapper AddConflictError(MethodWrapper mw) - { - error += " " + mw.DeclaringType.Name + "." + mw.Name; - return this; - } - - internal override string Error - { - get { return error; } - } - } - - internal static MirandaMethodWrapper Create(TypeWrapper declaringType, MethodWrapper ifmethod) - { - DefaultMirandaMethodWrapper dmmw = ifmethod as DefaultMirandaMethodWrapper; - if (dmmw != null) - { - return new DefaultMirandaMethodWrapper(declaringType, dmmw.BaseMethod); - } - return ifmethod.IsAbstract - ? (MirandaMethodWrapper)new AbstractMirandaMethodWrapper(declaringType, ifmethod) - : (MirandaMethodWrapper)new DefaultMirandaMethodWrapper(declaringType, ifmethod); - } - - internal MirandaMethodWrapper Update(MethodWrapper mw) - { - if (ifmethod == mw) - { - // an interface can be implemented multiple times - return this; - } - else if (ifmethod.DeclaringType.ImplementsInterface(mw.DeclaringType)) - { - // we can override a base interface without problems - return this; - } - else if (mw.DeclaringType.ImplementsInterface(ifmethod.DeclaringType)) - { - return Create(DeclaringType, mw); - } - else if (!ifmethod.IsAbstract && !mw.IsAbstract) - { - return AddConflictError(mw); - } - else if (!ifmethod.IsAbstract && mw.IsAbstract) - { - return new ErrorMirandaMethodWrapper(DeclaringType, mw, DeclaringType.Name + "." + Name + Signature); - } - else - { - return this; - } - } - - protected virtual MirandaMethodWrapper AddConflictError(MethodWrapper mw) - { - return new ErrorMirandaMethodWrapper(DeclaringType, ifmethod, "Conflicting default methods:") - .AddConflictError(ifmethod) - .AddConflictError(mw); - } - - internal bool IsConflictError - { - get { return Error != null && Error.StartsWith("Conflicting default methods:"); } - } - - internal MethodWrapper BaseMethod - { - get { return ifmethod; } - } - - internal virtual string Error - { - get { return null; } - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, GetMethod()); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Callvirt, GetMethod()); - } -#endif // EMITTERS - } - - sealed class GhostMethodWrapper : SmartMethodWrapper - { - private MethodInfo ghostMethod; - private MethodInfo defaultImpl; - - internal GhostMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, MethodInfo ghostMethod, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) - { - // make sure we weren't handed the ghostMethod in the wrapper value type - Debug.Assert(method == null || method.DeclaringType.IsInterface); - this.ghostMethod = ghostMethod; - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, defaultImpl); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, ghostMethod); - } -#endif - -#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - [HideFromJava] - internal override object Invoke(object obj, object[] args) - { - return InvokeAndUnwrapException(ghostMethod, DeclaringType.GhostWrap(obj), args); - } -#endif - - internal void SetDefaultImpl(MethodInfo impl) - { - this.defaultImpl = impl; - } - - internal MethodInfo GetDefaultImpl() - { - return defaultImpl; - } - -#if STATIC_COMPILER - internal void SetGhostMethod(MethodBuilder mb) - { - this.ghostMethod = mb; - } - - internal MethodBuilder GetGhostMethod() - { - return (MethodBuilder)ghostMethod; - } -#endif - } - - sealed class AccessStubMethodWrapper : SmartMethodWrapper - { - private readonly MethodInfo stubVirtual; - private readonly MethodInfo stubNonVirtual; - - internal AccessStubMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo core, MethodInfo stubVirtual, MethodInfo stubNonVirtual, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, core, returnType, parameterTypes, modifiers, flags) - { - this.stubVirtual = stubVirtual; - this.stubNonVirtual = stubNonVirtual; - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, stubNonVirtual); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Callvirt, stubVirtual); - } -#endif // EMITTERS - } - - sealed class AccessStubConstructorMethodWrapper : SmartMethodWrapper - { - private readonly ConstructorInfo stub; - - internal AccessStubConstructorMethodWrapper(TypeWrapper declaringType, string sig, ConstructorInfo core, ConstructorInfo stub, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, StringConstants.INIT, sig, core, PrimitiveTypeWrapper.VOID, parameterTypes, modifiers, flags) - { - this.stub = stub; - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, stub); - } - - protected override void NewobjImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Newobj, stub); - } -#endif // EMITTERS - } - - sealed class DefaultInterfaceMethodWrapper : SmartMethodWrapper - { - private MethodInfo impl; - - internal DefaultInterfaceMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodInfo ifmethod, MethodInfo impl, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, ifmethod, returnType, parameterTypes, modifiers, flags) - { - this.impl = impl; - } - - internal static MethodInfo GetImpl(MethodWrapper mw) - { - DefaultInterfaceMethodWrapper dimw = mw as DefaultInterfaceMethodWrapper; - if (dimw != null) - { - return dimw.impl; - } - else - { - return ((GhostMethodWrapper)mw).GetDefaultImpl(); - } - } - - internal static void SetImpl(MethodWrapper mw, MethodInfo impl) - { - DefaultInterfaceMethodWrapper dimw = mw as DefaultInterfaceMethodWrapper; - if (dimw != null) - { - dimw.impl = impl; - } - else - { - ((GhostMethodWrapper)mw).SetDefaultImpl(impl); - } - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, impl); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Callvirt, GetMethod()); - } -#endif // EMITTERS - } - - sealed class PrivateInterfaceMethodWrapper : SmartMethodWrapper - { - internal PrivateInterfaceMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, MemberFlags flags) - : base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, flags) - { - } - -#if EMITTERS - protected override void CallImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, GetMethod()); - } - - protected override void CallvirtImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, GetMethod()); - } -#endif // EMITTERS - } - - abstract class FieldWrapper : MemberWrapper - { -#if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR - private volatile java.lang.reflect.Field reflectionField; - private sun.reflect.FieldAccessor jniAccessor; -#endif - internal static readonly FieldWrapper[] EmptyArray = new FieldWrapper[0]; - private FieldInfo field; - private TypeWrapper fieldType; - - internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, MemberFlags flags) - : base(declaringType, name, sig, modifiers, flags) - { - Debug.Assert(name != null); - Debug.Assert(sig != null); - this.fieldType = fieldType; - this.field = field; - UpdateNonPublicTypeInSignatureFlag(); -#if STATIC_COMPILER - if (IsFinal - && DeclaringType.IsPublic - && !DeclaringType.IsInterface - && (IsPublic || (IsProtected && !DeclaringType.IsFinal)) - && !DeclaringType.GetClassLoader().StrictFinalFieldSemantics - && DeclaringType.IsDynamic - && !(this is ConstantFieldWrapper) - && !(this is DynamicPropertyFieldWrapper)) - { - SetType2FinalField(); - } -#endif - } - - internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, ExModifiers modifiers, FieldInfo field) - : this(declaringType, fieldType, name, sig, modifiers.Modifiers, field, - (modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None)) - { - } - - private void UpdateNonPublicTypeInSignatureFlag() - { - if ((IsPublic || IsProtected) && fieldType != null && !IsAccessStub) - { - if (!fieldType.IsPublic && !fieldType.IsUnloadable) - { - SetNonPublicTypeInSignatureFlag(); - } - } - } - - internal FieldInfo GetField() - { - AssertLinked(); - return field; - } - - [Conditional("DEBUG")] - internal void AssertLinked() - { - if(fieldType == null) - { - Tracer.Error(Tracer.Runtime, "AssertLinked failed: " + this.DeclaringType.Name + "::" + this.Name + " (" + this.Signature + ")"); - } - Debug.Assert(fieldType != null, this.DeclaringType.Name + "::" + this.Name + " (" + this.Signature+ ")"); - } - -#if !STATIC_COMPILER && !STUB_GENERATOR - internal static FieldWrapper FromField(java.lang.reflect.Field field) - { -#if FIRST_PASS - return null; -#else - int slot = field._slot(); - if (slot == -1) - { - // it's a Field created by Unsafe.objectFieldOffset(Class,String) so we must resolve based on the name - foreach (FieldWrapper fw in TypeWrapper.FromClass(field.getDeclaringClass()).GetFields()) - { - if (fw.Name == field.getName()) - { - return fw; - } - } - } - return TypeWrapper.FromClass(field.getDeclaringClass()).GetFields()[slot]; -#endif - } - - internal object ToField(bool copy) - { - return ToField(copy, null); - } - - internal object ToField(bool copy, int? fieldIndex) - { -#if FIRST_PASS - return null; -#else - java.lang.reflect.Field field = reflectionField; - if (field == null) - { - const Modifiers ReflectionFieldModifiersMask = Modifiers.Public | Modifiers.Private | Modifiers.Protected | Modifiers.Static - | Modifiers.Final | Modifiers.Volatile | Modifiers.Transient | Modifiers.Synthetic | Modifiers.Enum; - Link(); - field = new java.lang.reflect.Field( - this.DeclaringType.ClassObject, - this.Name, - this.FieldTypeWrapper.EnsureLoadable(this.DeclaringType.GetClassLoader()).ClassObject, - (int)(this.Modifiers & ReflectionFieldModifiersMask) | (this.IsInternal ? 0x40000000 : 0), - fieldIndex ?? Array.IndexOf(this.DeclaringType.GetFields(), this), - this.DeclaringType.GetGenericFieldSignature(this), - null - ); - } - lock (this) - { - if (reflectionField == null) - { - reflectionField = field; - } - else - { - field = reflectionField; - } - } - if (copy) - { - field = field.copy(); - } - return field; -#endif // FIRST_PASS - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR - - [System.Security.SecurityCritical] - internal static FieldWrapper FromCookie(IntPtr cookie) - { - return (FieldWrapper)FromCookieImpl(cookie); - } - - internal TypeWrapper FieldTypeWrapper - { - get - { - AssertLinked(); - return fieldType; - } - } - -#if EMITTERS - internal void EmitGet(CodeEmitter ilgen) - { - AssertLinked(); - EmitGetImpl(ilgen); - } - - protected abstract void EmitGetImpl(CodeEmitter ilgen); - - internal void EmitSet(CodeEmitter ilgen) - { - AssertLinked(); - EmitSetImpl(ilgen); - } - - protected abstract void EmitSetImpl(CodeEmitter ilgen); -#endif // EMITTERS - - -#if STATIC_COMPILER - internal bool IsLinked - { - get { return fieldType != null; } - } -#endif - - internal void Link() - { - lock(this) - { - if(fieldType != null) - { - return; - } - } - TypeWrapper fld = this.DeclaringType.GetClassLoader().FieldTypeWrapperFromSigNoThrow(Signature); - lock(this) - { - try - { - // critical code in the finally block to avoid Thread.Abort interrupting the thread - } - finally - { - if(fieldType == null) - { - fieldType = fld; - UpdateNonPublicTypeInSignatureFlag(); - try - { - field = this.DeclaringType.LinkField(this); - } - catch - { - // HACK if linking fails, we unlink to make sure - // that the next link attempt will fail again - fieldType = null; - throw; - } - } - } - } - } - - internal bool IsVolatile - { - get - { - return (Modifiers & Modifiers.Volatile) != 0; - } - } - - internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) - { - // volatile long & double field accesses must be made atomic - if((modifiers.Modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D")) - { - return new VolatileLongDoubleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers); - } - return new SimpleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers); - } - -#if !STATIC_COMPILER && !STUB_GENERATOR - internal virtual void ResolveField() - { - FieldBuilder fb = field as FieldBuilder; - if(fb != null) - { - field = fb.Module.ResolveField(fb.GetToken().Token); - } - } - - internal object GetFieldAccessorJNI() - { -#if FIRST_PASS - return null; -#else - if (jniAccessor == null) - { - Interlocked.CompareExchange(ref jniAccessor, Java_sun_reflect_ReflectionFactory.NewFieldAccessorJNI(this), null); - } - return jniAccessor; -#endif - } - -#if !FIRST_PASS - internal abstract object GetValue(object obj); - internal abstract void SetValue(object obj, object value); -#endif -#endif // !STATIC_COMPILER && !STUB_GENERATOR - } - - sealed class SimpleFieldWrapper : FieldWrapper - { - internal SimpleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) - : base(declaringType, fieldType, name, sig, modifiers, fi) - { - Debug.Assert(!(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG) || !IsVolatile); - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - if(!IsStatic && DeclaringType.IsNonPrimitiveValueType) - { - ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD); - } - if(IsVolatile) - { - ilgen.Emit(OpCodes.Volatile); - } - ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField()); - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - FieldInfo fi = GetField(); - if(!IsStatic && DeclaringType.IsNonPrimitiveValueType) - { - CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temp); - ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD); - ilgen.Emit(OpCodes.Ldloc, temp); - } - if(IsVolatile) - { - ilgen.Emit(OpCodes.Volatile); - } - ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi); - if(IsVolatile) - { - ilgen.EmitMemoryBarrier(); - } - } -#endif // EMITTERS - -#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - internal override object GetValue(object obj) - { - return GetField().GetValue(obj); - } - - internal override void SetValue(object obj, object value) - { - GetField().SetValue(obj, value); - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - } - - sealed class VolatileLongDoubleFieldWrapper : FieldWrapper - { - internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) - : base(declaringType, fieldType, name, sig, modifiers, fi) - { - Debug.Assert(IsVolatile); - Debug.Assert(sig == "J" || sig == "D"); - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - FieldInfo fi = GetField(); - if(fi.IsStatic) - { - ilgen.Emit(OpCodes.Ldsflda, fi); - } - else - { - if(DeclaringType.IsNonPrimitiveValueType) - { - ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD); - } - ilgen.Emit(OpCodes.Ldflda, fi); - } - if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) - { - ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadDouble); - } - else - { - Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); - ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadLong); - } - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - FieldInfo fi = GetField(); - CodeEmitterLocal temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsSignatureType); - ilgen.Emit(OpCodes.Stloc, temp); - if(fi.IsStatic) - { - ilgen.Emit(OpCodes.Ldsflda, fi); - } - else - { - if(DeclaringType.IsNonPrimitiveValueType) - { - ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD); - } - ilgen.Emit(OpCodes.Ldflda, fi); - } - ilgen.Emit(OpCodes.Ldloc, temp); - if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) - { - ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteDouble); - } - else - { - Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); - ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteLong); - } - } -#endif // EMITTERS - -#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS -#if NO_REF_EMIT - internal static readonly object lockObject = new object(); -#endif - - internal override object GetValue(object obj) - { -#if NO_REF_EMIT - lock (lockObject) - { - return GetField().GetValue(obj); - } -#else - throw new InvalidOperationException(); -#endif - } - - internal override void SetValue(object obj, object value) - { -#if NO_REF_EMIT - lock (lockObject) - { - GetField().SetValue(obj, value); - } -#else - throw new InvalidOperationException(); -#endif - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - } - -#if !STUB_GENERATOR - // this class represents a .NET property defined in Java with the ikvm.lang.Property annotation - sealed class DynamicPropertyFieldWrapper : FieldWrapper - { - private readonly MethodWrapper getter; - private readonly MethodWrapper setter; - private PropertyBuilder pb; - - private MethodWrapper GetMethod(string name, string sig, bool isstatic) - { - if(name != null) - { - MethodWrapper mw = this.DeclaringType.GetMethodWrapper(name, sig, false); - if(mw != null && mw.IsStatic == isstatic) - { - mw.IsPropertyAccessor = true; - return mw; - } - Tracer.Error(Tracer.Compiler, "Property '{0}' accessor '{1}' not found in class '{2}'", this.Name, name, this.DeclaringType.Name); - } - return null; - } - - internal DynamicPropertyFieldWrapper(TypeWrapper declaringType, ClassFile.Field fld) - : base(declaringType, null, fld.Name, fld.Signature, new ExModifiers(fld.Modifiers, fld.IsInternal), null) - { - getter = GetMethod(fld.PropertyGetter, "()" + fld.Signature, fld.IsStatic); - setter = GetMethod(fld.PropertySetter, "(" + fld.Signature + ")V", fld.IsStatic); - } - -#if !STATIC_COMPILER && !FIRST_PASS - internal override void ResolveField() - { - if (getter != null) - { - getter.ResolveMethod(); - } - if (setter != null) - { - setter.ResolveMethod(); - } - } -#endif - - internal PropertyBuilder GetPropertyBuilder() - { - AssertLinked(); - return pb; - } - - internal void DoLink(TypeBuilder tb) - { - if(getter != null) - { - getter.Link(); - } - if(setter != null) - { - setter.Link(); - } - pb = tb.DefineProperty(this.Name, PropertyAttributes.None, this.FieldTypeWrapper.TypeAsSignatureType, Type.EmptyTypes); - if(getter != null) - { - pb.SetGetMethod((MethodBuilder)getter.GetMethod()); - } - if(setter != null) - { - pb.SetSetMethod((MethodBuilder)setter.GetMethod()); - } -#if STATIC_COMPILER - AttributeHelper.SetModifiers(pb, this.Modifiers, this.IsInternal); -#endif - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - if(getter == null) - { - EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic); - } - else if(getter.IsStatic) - { - getter.EmitCall(ilgen); - } - else - { - getter.EmitCallvirt(ilgen); - } - } - - internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, TypeWrapper type, bool isStatic) - { - // HACK the branch around the throw is to keep the verifier happy - CodeEmitterLabel label = ilgen.DefineLabel(); - ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.EmitBrtrue(label); - ilgen.EmitThrow("java.lang.NoSuchMethodError"); - ilgen.MarkLabel(label); - if (!isStatic) - { - ilgen.Emit(OpCodes.Pop); - } - ilgen.Emit(OpCodes.Ldloc, ilgen.DeclareLocal(type.TypeAsLocalOrStackType)); - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - if(setter == null) - { - if(this.IsFinal) - { - ilgen.Emit(OpCodes.Pop); - if(!this.IsStatic) - { - ilgen.Emit(OpCodes.Pop); - } - } - else - { - EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic); - } - } - else if(setter.IsStatic) - { - setter.EmitCall(ilgen); - } - else - { - setter.EmitCallvirt(ilgen); - } - } - - internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, bool isStatic) - { - // HACK the branch around the throw is to keep the verifier happy - CodeEmitterLabel label = ilgen.DefineLabel(); - ilgen.Emit(OpCodes.Ldc_I4_0); - ilgen.EmitBrtrue(label); - ilgen.EmitThrow("java.lang.NoSuchMethodError"); - ilgen.MarkLabel(label); - ilgen.Emit(OpCodes.Pop); - if (!isStatic) - { - ilgen.Emit(OpCodes.Pop); - } - } -#endif // EMITTERS - -#if !STATIC_COMPILER && !FIRST_PASS - internal override object GetValue(object obj) - { - if (getter == null) - { - throw new java.lang.NoSuchMethodError(); - } - return getter.Invoke(obj, new object[0]); - } - - internal override void SetValue(object obj, object value) - { - if (setter == null) - { - throw new java.lang.NoSuchMethodError(); - } - setter.Invoke(obj, new object[] { value }); - } -#endif - } -#endif // !STUB_GENERATOR - - // this class represents a .NET property defined in Java with the ikvm.lang.Property annotation - sealed class CompiledPropertyFieldWrapper : FieldWrapper - { - private readonly PropertyInfo property; - - internal CompiledPropertyFieldWrapper(TypeWrapper declaringType, PropertyInfo property, ExModifiers modifiers) - : base(declaringType, ClassLoaderWrapper.GetWrapperFromType(property.PropertyType), property.Name, ClassLoaderWrapper.GetWrapperFromType(property.PropertyType).SigName, modifiers, null) - { - this.property = property; - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - MethodInfo getter = property.GetGetMethod(true); - if(getter == null) - { - DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForGetter(ilgen, this.FieldTypeWrapper, this.IsStatic); - } - else if(getter.IsStatic) - { - ilgen.Emit(OpCodes.Call, getter); - } - else - { - ilgen.Emit(OpCodes.Callvirt, getter); - } - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - MethodInfo setter = property.GetSetMethod(true); - if (setter == null) - { - if(this.IsFinal) - { - ilgen.Emit(OpCodes.Pop); - if(!this.IsStatic) - { - ilgen.Emit(OpCodes.Pop); - } - } - else - { - DynamicPropertyFieldWrapper.EmitThrowNoSuchMethodErrorForSetter(ilgen, this.IsStatic); - } - } - else if(setter.IsStatic) - { - ilgen.Emit(OpCodes.Call, setter); - } - else - { - ilgen.Emit(OpCodes.Callvirt, setter); - } - } -#endif // EMITTERS - -#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - internal override object GetValue(object obj) - { - MethodInfo getter = property.GetGetMethod(true); - if (getter == null) - { - throw new java.lang.NoSuchMethodError(); - } - return getter.Invoke(obj, new object[0]); - } - - internal override void SetValue(object obj, object value) - { - MethodInfo setter = property.GetSetMethod(true); - if (setter == null) - { - throw new java.lang.NoSuchMethodError(); - } - setter.Invoke(obj, new object[] { value }); - } -#endif - - internal PropertyInfo GetProperty() - { - return property; - } - } - - sealed class ConstantFieldWrapper : FieldWrapper - { - // 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) - private object constant; - - internal ConstantFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field, object constant, MemberFlags flags) - : base(declaringType, fieldType, name, sig, modifiers, field, flags) - { - Debug.Assert(IsStatic); - Debug.Assert(constant == null || constant.GetType().IsPrimitive || constant is string); - this.constant = constant; - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - // Reading a field should trigger the cctor, but since we're inlining the value - // we have to trigger it explicitly - DeclaringType.EmitRunClassConstructor(ilgen); - - // NOTE even though you're not supposed to access a constant static final (the compiler is supposed - // to inline them), we have to support it (because it does happen, e.g. if the field becomes final - // after the referencing class was compiled, or when we're accessing an unsigned primitive .NET field) - object v = GetConstantValue(); - if(v == null) - { - ilgen.Emit(OpCodes.Ldnull); - } - else if(constant is int || - constant is short || - constant is ushort || - constant is byte || - constant is sbyte || - constant is char || - constant is bool) - { - ilgen.EmitLdc_I4(((IConvertible)constant).ToInt32(null)); - } - else if(constant is string) - { - ilgen.Emit(OpCodes.Ldstr, (string)constant); - } - else if(constant is float) - { - ilgen.EmitLdc_R4((float)constant); - } - else if(constant is double) - { - ilgen.EmitLdc_R8((double)constant); - } - else if(constant is long) - { - ilgen.EmitLdc_I8((long)constant); - } - else if(constant is uint) - { - ilgen.EmitLdc_I4(unchecked((int)((IConvertible)constant).ToUInt32(null))); - } - else if(constant is ulong) - { - ilgen.EmitLdc_I8(unchecked((long)(ulong)constant)); - } - else - { - throw new InvalidOperationException(constant.GetType().FullName); - } - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - // when constant static final fields are updated, the JIT normally doesn't see that (because the - // constant value is inlined), so we emulate that behavior by emitting a Pop - ilgen.Emit(OpCodes.Pop); - } -#endif // EMITTERS - - internal object GetConstantValue() - { - if(constant == null) - { - FieldInfo field = GetField(); - constant = field.GetRawConstantValue(); - } - return constant; - } - -#if !STUB_GENERATOR && !STATIC_COMPILER && !FIRST_PASS - internal override object GetValue(object obj) - { - FieldInfo field = GetField(); - return FieldTypeWrapper.IsPrimitive || field == null - ? GetConstantValue() - : field.GetValue(null); - } - - internal override void SetValue(object obj, object value) - { - } -#endif - } - - sealed class CompiledAccessStubFieldWrapper : FieldWrapper - { - private readonly MethodInfo getter; - private readonly MethodInfo setter; - - private static Modifiers GetModifiers(PropertyInfo property) - { - // NOTE we only support the subset of modifiers that is expected for "access stub" properties - MethodInfo getter = property.GetGetMethod(true); - Modifiers modifiers = getter.IsPublic ? Modifiers.Public : Modifiers.Protected; - if(!property.CanWrite) - { - modifiers |= Modifiers.Final; - } - if(getter.IsStatic) - { - modifiers |= Modifiers.Static; - } - return modifiers; - } - - // constructor for type 1 access stubs - internal CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, TypeWrapper propertyType) - : this(wrapper, property, null, propertyType, GetModifiers(property), MemberFlags.HideFromReflection | MemberFlags.AccessStub) - { - } - - // constructor for type 2 access stubs - internal CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, FieldInfo field, TypeWrapper propertyType) - : this(wrapper, property, field, propertyType, AttributeHelper.GetModifiersAttribute(property).Modifiers, MemberFlags.AccessStub) - { - } - - private CompiledAccessStubFieldWrapper(TypeWrapper wrapper, PropertyInfo property, FieldInfo field, TypeWrapper propertyType, Modifiers modifiers, MemberFlags flags) - : base(wrapper, propertyType, property.Name, propertyType.SigName, modifiers, field, flags) - { - this.getter = property.GetGetMethod(true); - this.setter = property.GetSetMethod(true); - } - -#if EMITTERS - protected override void EmitGetImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, getter); - } - - protected override void EmitSetImpl(CodeEmitter ilgen) - { - ilgen.Emit(OpCodes.Call, setter); - } -#endif // EMITTERS - -#if !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - internal override object GetValue(object obj) - { - // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - return GetField().GetValue(obj); - } - - internal override void SetValue(object obj, object value) - { - // we can only be invoked on type 2 access stubs (because type 1 access stubs are HideFromReflection), so we know we have a field - GetField().SetValue(obj, value); - } -#endif // !STATIC_COMPILER && !STUB_GENERATOR && !FIRST_PASS - } -} |