IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
RuntimeManagedByteCodeJavaType.RemappedJavaMethod.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2015 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.Diagnostics;
25
26using IKVM.Attributes;
27
28#if IMPORTER || EXPORTER
29using IKVM.Reflection;
31
32using Type = IKVM.Reflection.Type;
33#else
34using System.Reflection;
35using System.Reflection.Emit;
36#endif
37
38namespace IKVM.Runtime
39{
40
41 partial class RuntimeManagedByteCodeJavaType
42 {
43
44 sealed class RemappedJavaMethod : RuntimeSmartJavaMethod
45 {
46
47 readonly MethodInfo mbHelper;
48#if !IMPORTER
49 readonly MethodInfo mbNonvirtualHelper;
50#endif
51
65 internal RemappedJavaMethod(RuntimeJavaType declaringType, string name, string sig, MethodBase method, RuntimeJavaType returnType, RuntimeJavaType[] parameterTypes, ExModifiers modifiers, bool hideFromReflection, MethodInfo mbHelper, MethodInfo mbNonvirtualHelper) :
66 base(declaringType, name, sig, method, returnType, parameterTypes, modifiers.Modifiers, (modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) | (hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None))
67 {
68 this.mbHelper = mbHelper;
69#if !IMPORTER
70 this.mbNonvirtualHelper = mbNonvirtualHelper;
71#endif
72 }
73
74#if EMITTERS
75
76 protected override void CallImpl(CodeEmitter ilgen)
77 {
78 var mb = GetMethod();
79 var mi = mb as MethodInfo;
80 if (mi != null)
81 {
82 if (!IsStatic && IsFinal)
83 {
84 // When calling a final instance method on a remapped type from a class derived from a .NET class (i.e. a cli.System.Object or cli.System.Exception derived base class)
85 // then we can't call the java.lang.Object or java.lang.Throwable methods and we have to go through the instancehelper_ method. Note that since the method
86 // is final, this won't affect the semantics.
87 CallvirtImpl(ilgen);
88 }
89 else
90 {
91 ilgen.Emit(OpCodes.Call, mi);
92 }
93 }
94 else
95 {
96 ilgen.Emit(OpCodes.Call, mb);
97 }
98 }
99
100 protected override void CallvirtImpl(CodeEmitter ilgen)
101 {
102 Debug.Assert(!mbHelper.IsStatic || mbHelper.Name.StartsWith("instancehelper_") || mbHelper.DeclaringType.Name == "__Helper");
103 if (mbHelper.IsPublic)
104 {
105 ilgen.Emit(mbHelper.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mbHelper);
106 }
107 else
108 {
109 // HACK the helper is not public, this means that we're dealing with finalize or clone
110 ilgen.Emit(OpCodes.Callvirt, GetMethod());
111 }
112 }
113
114 protected override void NewobjImpl(CodeEmitter ilgen)
115 {
116 var mb = GetMethod();
117 var mi = mb as MethodInfo;
118 if (mi != null)
119 {
120 Debug.Assert(mi.Name == "newhelper");
121 ilgen.Emit(OpCodes.Call, mi);
122 }
123 else
124 {
125 ilgen.Emit(OpCodes.Newobj, mb);
126 }
127 }
128
129#endif // EMITTERS
130
131#if !IMPORTER && !FIRST_PASS && !EXPORTER
132
133 [HideFromJava]
134 internal override object Invoke(object obj, object[] args)
135 {
136 var mb = mbHelper ?? GetMethod();
137 if (mb.IsStatic && !IsStatic)
138 {
139 args = ArrayUtil.Concat(obj, args);
140 obj = null;
141 }
142
143 return InvokeAndUnwrapException(mb, obj, args);
144 }
145
146 [HideFromJava]
147 internal override object CreateInstance(object[] args)
148 {
149 var mb = mbHelper ?? GetMethod();
150 if (mb.IsStatic)
151 return InvokeAndUnwrapException(mb, null, args);
152
153 return base.CreateInstance(args);
154 }
155
156 [HideFromJava]
157 internal override object InvokeNonvirtualRemapped(object obj, object[] args)
158 {
159 var mi = mbNonvirtualHelper ?? mbHelper;
160 return mi.Invoke(null, ArrayUtil.Concat(obj, args));
161 }
162
163#endif // !IMPORTER && !FIRST_PASS && !EXPORTER
164
165#if EMITTERS
166
167 internal override void EmitCallvirtReflect(CodeEmitter ilgen)
168 {
169 var mb = mbHelper ?? GetMethod();
170 ilgen.Emit(mb.IsStatic ? OpCodes.Call : OpCodes.Callvirt, mb);
171 }
172
173#endif // EMITTERS
174
175 internal string GetGenericSignature()
176 {
177 var attr = DeclaringType.Context.AttributeHelper.GetSignature(mbHelper != null ? mbHelper : GetMethod());
178 if (attr != null)
179 return attr.Signature;
180
181 return null;
182 }
183
184 }
185
186 }
187
188}
IKVM.Reflection.Type Type
IKVM.Reflection.MethodInfo MethodInfo
IKVM.Reflection.MethodBase MethodBase
AttributeHelper AttributeHelper
Gets the AttributeHelper associated with this instance of the runtime.
static object InvokeAndUnwrapException(MethodBase mb, object obj, object[] args)
Dynamically invokes the method and potentially unwraps any exceptions.
MemberFlags
Describes various options applied to a member.
@ InternalAccess
Member should be generated with "internal" .NET access.
@ HideFromReflection
Member should be hidden from Java reflection.