Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/MemberWrapper.cs')
-rw-r--r--runtime/MemberWrapper.cs2127
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
- }
-}