IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
RuntimeJavaMember.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2014 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Runtime.InteropServices;
26
27using IKVM.Attributes;
28
29#if IMPORTER || EXPORTER
30using IKVM.Reflection;
32
33using Type = IKVM.Reflection.Type;
34#else
35using System.Reflection;
36using System.Reflection.Emit;
37#endif
38
39namespace IKVM.Runtime
40{
41
42 abstract class RuntimeJavaMember
43 {
44
48 class HandleManager
49 {
50
56 public static RuntimeJavaMember FromCookie(IntPtr cookie)
57 {
58 return (RuntimeJavaMember)GCHandle.FromIntPtr(cookie).Target;
59 }
60
61 GCHandle handle;
62
67 public HandleManager(RuntimeJavaMember member)
68 {
69 handle = GCHandle.Alloc(member, GCHandleType.WeakTrackResurrection);
70 }
71
75 public IntPtr Cookie => GCHandle.ToIntPtr(handle);
76
80 ~HandleManager()
81 {
82 handle.Free();
83 }
84
85 }
86
87 readonly RuntimeJavaType declaringType;
88 readonly string name;
89 readonly string sig;
90 protected readonly Modifiers modifiers;
91 MemberFlags flags;
92
93 HandleManager handle;
94
104 protected RuntimeJavaMember(RuntimeJavaType declaringType, string name, string sig, Modifiers modifiers, MemberFlags flags)
105 {
106 this.declaringType = declaringType ?? throw new ArgumentNullException(nameof(declaringType));
107 this.name = string.Intern(name);
108 this.sig = string.Intern(sig);
109 this.modifiers = modifiers;
110 this.flags = flags;
111 }
112
116 internal nint Cookie
117 {
118 get
119 {
120 // synchronize the creation of a handle
121 lock (this)
122 handle ??= new HandleManager(this);
123
124 return handle.Cookie;
125 }
126 }
127
133 [System.Security.SecurityCritical]
134 internal static RuntimeJavaMember FromCookieImpl(nint cookie)
135 {
136 return (RuntimeJavaMember)HandleManager.FromCookie(cookie);
137 }
138
139 internal RuntimeJavaType DeclaringType => declaringType;
140
141 internal string Name => name;
142
143 internal string Signature => sig;
144
145 internal bool IsAccessibleFrom(RuntimeJavaType referencedType, RuntimeJavaType caller, RuntimeJavaType instance)
146 {
147 if (referencedType.IsAccessibleFrom(caller))
148 {
149 return (
150 caller == DeclaringType ||
151 IsNestmateOf(caller, DeclaringType) ||
152 IsPublicOrProtectedMemberAccessible(caller, instance) ||
153 (IsInternal && DeclaringType.InternalsVisibleTo(caller)) ||
154 (!IsPrivate && DeclaringType.IsPackageAccessibleFrom(caller)))
155 // The JVM supports accessing members that have non-public types in their signature from another package,
156 // but the CLI doesn't. It would be nice if we worked around that by emitting extra accessors, but for now
157 // we'll simply disallow such access across assemblies (unless the appropriate InternalsVisibleToAttribute exists).
158 && (!(HasNonPublicTypeInSignature || IsType2FinalField) || InPracticeInternalsVisibleTo(caller));
159 }
160
161 return false;
162 }
163
164 static bool IsNestmateOf(RuntimeJavaType caller, RuntimeJavaType declaringType)
165 {
166 if (caller.ClassLoader != declaringType.ClassLoader)
167 return false;
168
169 return string.Equals(GetNestHostName(caller.Name), GetNestHostName(declaringType.Name), StringComparison.Ordinal);
170 }
171
172 static string GetNestHostName(string name)
173 {
174 var separator = name.IndexOf('$');
175 return separator < 0 ? name : name.Substring(0, separator);
176 }
177 bool IsPublicOrProtectedMemberAccessible(RuntimeJavaType caller, RuntimeJavaType instance)
178 {
179 if (IsPublic || (IsProtected && caller.IsSubTypeOf(DeclaringType) && (IsStatic || instance.IsUnloadable || instance.IsSubTypeOf(caller))))
180 return DeclaringType.IsPublic || InPracticeInternalsVisibleTo(caller);
181
182 return false;
183 }
184
185 bool InPracticeInternalsVisibleTo(RuntimeJavaType caller)
186 {
187#if !IMPORTER
188 if (DeclaringType.TypeAsTBD.Assembly.Equals(caller.TypeAsTBD.Assembly))
189 {
190 // both the caller and the declaring type are in the same assembly
191 // so we know that the internals are visible
192 // (this handles the case where we're running in dynamic mode)
193 return true;
194 }
195#endif
196
197 return DeclaringType.InternalsVisibleTo(caller);
198 }
199
200 internal bool IsHideFromReflection => (flags & MemberFlags.HideFromReflection) != 0;
201
202 internal bool IsExplicitOverride => (flags & MemberFlags.ExplicitOverride) != 0;
203
204 internal bool IsMirandaMethod => (flags & MemberFlags.MirandaMethod) != 0;
205
206 internal bool IsAccessStub => (flags & MemberFlags.AccessStub) != 0;
207
208 internal bool IsPropertyAccessor
209 {
210 get
211 {
212 return (flags & MemberFlags.PropertyAccessor) != 0;
213 }
214 set
215 {
216 // this is unsynchronized, so it may only be called during the JavaTypeImpl constructor
217 if (value)
218 {
219 flags |= MemberFlags.PropertyAccessor;
220 }
221 else
222 {
223 flags &= ~MemberFlags.PropertyAccessor;
224 }
225 }
226 }
227
228 internal bool IsIntrinsic => (flags & MemberFlags.Intrinsic) != 0;
229
230 protected void SetIntrinsicFlag()
231 {
232 flags |= MemberFlags.Intrinsic;
233 }
234
236 {
237 flags |= MemberFlags.NonPublicTypeInSignature;
238 }
239
240 internal bool HasNonPublicTypeInSignature => (flags & MemberFlags.NonPublicTypeInSignature) != 0;
241
242 protected void SetType2FinalField()
243 {
244 flags |= MemberFlags.Type2FinalField;
245 }
246
247 internal bool IsType2FinalField => (flags & MemberFlags.Type2FinalField) != 0;
248
249 internal bool HasCallerID => (flags & MemberFlags.CallerID) != 0;
250
251 internal bool IsDelegateInvokeWithByRefParameter => (flags & MemberFlags.DelegateInvokeWithByRefParameter) != 0;
252
253 internal bool IsNoOp => (flags & MemberFlags.NoOp) != 0;
254
255 internal Modifiers Modifiers => modifiers;
256
257 internal bool IsStatic => (modifiers & Modifiers.Static) != 0;
258
259 internal bool IsInternal => (flags & MemberFlags.InternalAccess) != 0;
260
261 internal bool IsPublic => (modifiers & Modifiers.Public) != 0;
262
263 internal bool IsPrivate => (modifiers & Modifiers.Private) != 0;
264
265 internal bool IsProtected => (modifiers & Modifiers.Protected) != 0;
266
267 internal bool IsFinal => (modifiers & Modifiers.Final) != 0;
268
272 internal bool IsModuleInitializer => IsStatic && IsPrivate == false && (flags & MemberFlags.ModuleInitializer) != 0;
273
274 }
275
276}
IKVM.Reflection.Type Type
global::java.lang.invoke.LambdaForm.Name Name
RuntimeJavaMember(RuntimeJavaType declaringType, string name, string sig, Modifiers modifiers, MemberFlags flags)
Initializes a new instance.
MemberFlags
Describes various options applied to a member.