IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
MethodHandleUtil.jniexport.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2011-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*/
24#if IMPORTER == false
25using System;
26using System.Diagnostics;
27using System.Reflection;
28using System.Reflection.Emit;
30
31namespace IKVM.Runtime
32{
33
34 partial class MethodHandleUtil
35 {
36
37 internal Type GetMemberWrapperDelegateType(global::java.lang.invoke.MethodType type)
38 {
39#if FIRST_PASS
40 throw new NotImplementedException();
41#else
42 return GetDelegateTypeForInvokeExact(type.basicType());
43#endif
44 }
45
46#if FIRST_PASS == false
47
48 Type CreateMethodHandleDelegateType(java.lang.invoke.MethodType type)
49 {
50 var args = new RuntimeJavaType[type.parameterCount()];
51 for (int i = 0; i < args.Length; i++)
52 {
53 args[i] = RuntimeJavaType.FromClass(type.parameterType(i));
54 args[i].Finish();
55 }
56 var ret = RuntimeJavaType.FromClass(type.returnType());
57 ret.Finish();
58 return CreateMethodHandleDelegateType(args, ret);
59 }
60
61 static Type[] GetParameterTypes(MethodBase mb)
62 {
63 var pi = mb.GetParameters();
64 var args = new Type[pi.Length];
65 for (int i = 0; i < args.Length; i++)
66 args[i] = pi[i].ParameterType;
67
68 return args;
69 }
70
71 internal static Type[] GetParameterTypes(Type thisType, MethodBase mb)
72 {
73 var pi = mb.GetParameters();
74 var args = new Type[pi.Length + 1];
75 args[0] = thisType;
76 for (int i = 1; i < args.Length; i++)
77 args[i] = pi[i - 1].ParameterType;
78
79 return args;
80 }
81
82 internal java.lang.invoke.MethodType GetDelegateMethodType(Type type)
83 {
84 java.lang.Class[] types;
85 var mi = GetDelegateInvokeMethod(type);
86 var pi = mi.GetParameters();
87 if (pi.Length > 0 && IsPackedArgsContainer(pi[pi.Length - 1].ParameterType))
88 {
89 var list = new System.Collections.Generic.List<java.lang.Class>();
90 for (int i = 0; i < pi.Length - 1; i++)
91 list.Add(context.ClassLoaderFactory.GetJavaTypeFromType(pi[i].ParameterType).ClassObject);
92
93 var args = pi[pi.Length - 1].ParameterType.GetGenericArguments();
94 while (IsPackedArgsContainer(args[args.Length - 1]))
95 {
96 for (int i = 0; i < args.Length - 1; i++)
97 list.Add(context.ClassLoaderFactory.GetJavaTypeFromType(args[i]).ClassObject);
98
99 args = args[args.Length - 1].GetGenericArguments();
100 }
101
102 for (int i = 0; i < args.Length; i++)
103 list.Add(context.ClassLoaderFactory.GetJavaTypeFromType(args[i]).ClassObject);
104
105 types = list.ToArray();
106 }
107 else
108 {
109 types = new java.lang.Class[pi.Length];
110 for (int i = 0; i < types.Length; i++)
111 types[i] = context.ClassLoaderFactory.GetJavaTypeFromType(pi[i].ParameterType).ClassObject;
112 }
113
114 return java.lang.invoke.MethodType.methodType(context.ClassLoaderFactory.GetJavaTypeFromType(mi.ReturnType).ClassObject, types);
115 }
116
117 internal sealed class DynamicMethodBuilder
118 {
119
120 const string METHOD_HANDLE_FORM_FIELD = "form";
121 const string LAMBDA_FORM_VMENTRY_FIELD = "vmentry";
122 const string MEMBER_NAME_VMTARGET_FIELD = "vmtarget";
123
124 readonly RuntimeContext context;
125 readonly java.lang.invoke.MethodType type;
126 readonly int firstArg;
127 readonly Type delegateType;
128 readonly object firstBoundValue;
129 readonly object secondBoundValue;
130 readonly Type container;
131 readonly DynamicMethod dm;
132 readonly CodeEmitter ilgen;
133 readonly Type packedArgType;
134 readonly int packedArgPos;
135
136 sealed class Container<T1, T2>
137 {
138
139 public T1 target;
140 public T2 value;
141
142 public Container(T1 target, T2 value)
143 {
144 this.target = target;
145 this.value = value;
146 }
147
148 }
149
162 DynamicMethodBuilder(RuntimeContext context, string name, java.lang.invoke.MethodType type, Type container, object target, object value, Type owner, bool useBasicTypes)
163 {
164 this.context = context ?? throw new ArgumentNullException(nameof(context));
165 this.type = type;
166 this.container = container;
167
168 delegateType = useBasicTypes ? context.MethodHandleUtil.GetMemberWrapperDelegateType(type) : context.MethodHandleUtil.GetDelegateTypeForInvokeExact(type);
169 firstBoundValue = target;
170 secondBoundValue = value;
171
172 var mi = context.MethodHandleUtil.GetDelegateInvokeMethod(delegateType);
173
174 Type[] paramTypes;
175 if (container != null)
176 {
177 firstArg = 1;
178 paramTypes = GetParameterTypes(container, mi);
179 }
180 else if (target != null)
181 {
182 firstArg = 1;
183 paramTypes = GetParameterTypes(target.GetType(), mi);
184 }
185 else
186 {
187 paramTypes = GetParameterTypes(mi);
188 }
189
190 if (!ReflectUtil.CanOwnDynamicMethod(owner))
191 owner = typeof(DynamicMethodBuilder);
192
193 dm = new DynamicMethod(name, mi.ReturnType, paramTypes, owner, true);
194 ilgen = context.CodeEmitterFactory.Create(dm);
195
196 if (type.parameterCount() > MaxArity)
197 {
198 var pi = mi.GetParameters();
199 packedArgType = pi[pi.Length - 1].ParameterType;
200 packedArgPos = pi.Length - 1 + firstArg;
201 }
202 else
203 {
204 packedArgPos = int.MaxValue;
205 }
206 }
207
208 internal static Delegate CreateVoidAdapter(RuntimeContext context, global::java.lang.invoke.MethodType type)
209 {
210 var dm = new DynamicMethodBuilder(context, "VoidAdapter", type.changeReturnType(global::java.lang.Void.TYPE), null, null, null, null, true);
211 var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type);
212 dm.Ldarg(0);
213 dm.EmitCheckcast(context.JavaBase.TypeOfJavaLangInvokeMethodHandle);
214 dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
215 dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
216 dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
217 dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
218 for (int i = 0; i < type.parameterCount(); i++)
219 dm.Ldarg(i);
220
221 dm.CallDelegate(targetDelegateType);
222 dm.ilgen.Emit(OpCodes.Pop);
223
224 dm.Ret();
225 return dm.CreateDelegate();
226 }
227
228 internal static DynamicMethod CreateInvokeExact(RuntimeContext context, global::java.lang.invoke.MethodType type)
229 {
230 FinishTypes(type);
231
232 var dm = new DynamicMethodBuilder(context, "InvokeExact", type, typeof(java.lang.invoke.MethodHandle), null, null, null, false);
233 var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type.insertParameterTypes(0, context.JavaBase.TypeOfJavaLangInvokeMethodHandle.ClassObject));
234 dm.ilgen.Emit(OpCodes.Ldarg_0);
235 dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.MethodHandle).GetField(METHOD_HANDLE_FORM_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
236 dm.ilgen.Emit(OpCodes.Ldfld, typeof(global::java.lang.invoke.LambdaForm).GetField(LAMBDA_FORM_VMENTRY_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
237 if (type.returnType() == java.lang.Void.TYPE)
238 dm.ilgen.Emit(OpCodes.Call, typeof(MethodHandleUtil).GetMethod(nameof(GetVoidAdapter), BindingFlags.Static | BindingFlags.NonPublic));
239 else
240 dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
241
242 dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType);
243 dm.ilgen.Emit(OpCodes.Ldarg_0);
244 for (int i = 0; i < type.parameterCount(); i++)
245 {
246 dm.Ldarg(i);
247 var tw = RuntimeJavaType.FromClass(type.parameterType(i));
248 if (tw.IsNonPrimitiveValueType)
249 tw.EmitBox(dm.ilgen);
250 else if (tw.IsGhost)
251 tw.EmitConvSignatureTypeToStackType(dm.ilgen);
252 else if (tw == context.PrimitiveJavaTypeFactory.BYTE)
253 dm.ilgen.Emit(OpCodes.Conv_I1);
254 }
255 dm.CallDelegate(targetDelegateType);
256
257 var retType = RuntimeJavaType.FromClass(type.returnType());
258 if (retType.IsNonPrimitiveValueType)
259 retType.EmitUnbox(dm.ilgen);
260 else if (retType.IsGhost)
261 retType.EmitConvStackTypeToSignatureType(dm.ilgen, null);
262 else if (!retType.IsPrimitive && retType != context.JavaBase.TypeOfJavaLangObject)
263 dm.EmitCheckcast(retType);
264
265 dm.Ret();
266 dm.ilgen.DoEmit();
267 return dm.dm;
268 }
269
270 internal static Delegate CreateMethodHandleLinkTo(RuntimeContext context, java.lang.invoke.MemberName mn)
271 {
272 var type = mn.getMethodType();
273 var delegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type.dropParameterTypes(type.parameterCount() - 1, type.parameterCount()));
274 var dm = new DynamicMethodBuilder(context, "DirectMethodHandle." + mn.getName() + type, type, null, null, null, null, true);
275 dm.Ldarg(type.parameterCount() - 1);
276 dm.ilgen.EmitCastclass(typeof(java.lang.invoke.MemberName));
277 dm.ilgen.Emit(OpCodes.Ldfld, typeof(java.lang.invoke.MemberName).GetField(MEMBER_NAME_VMTARGET_FIELD, BindingFlags.Instance | BindingFlags.NonPublic));
278 dm.ilgen.Emit(OpCodes.Castclass, delegateType);
279 for (int i = 0, count = type.parameterCount() - 1; i < count; i++)
280 dm.Ldarg(i);
281 dm.CallDelegate(delegateType);
282
283 dm.Ret();
284 return dm.CreateDelegate();
285 }
286
287 internal static Delegate CreateMethodHandleInvoke(RuntimeContext context, java.lang.invoke.MemberName mn)
288 {
289 var type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass());
290 var targetDelegateType = context.MethodHandleUtil.GetMemberWrapperDelegateType(type);
291 var dm = new DynamicMethodBuilder(context, "DirectMethodHandle." + mn.getName() + type, type, typeof(Container<,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache<>).MakeGenericType(targetDelegateType)), null, null, null, true);
292 dm.Ldarg(0);
293 dm.EmitCheckcast(context.JavaBase.TypeOfJavaLangInvokeMethodHandle);
294 switch (mn.getName())
295 {
296 case "invokeExact":
297 dm.Call(context.ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType));
298 break;
299 case "invoke":
300 dm.LoadValueAddress();
301 dm.Call(context.ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType));
302 break;
303 case "invokeBasic":
304 dm.Call(context.ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(targetDelegateType));
305 break;
306 default:
307 throw new InvalidOperationException();
308 }
309
310 dm.Ldarg(0);
311 for (int i = 1, count = type.parameterCount(); i < count; i++)
312 dm.Ldarg(i);
313 dm.CallDelegate(targetDelegateType);
314
315 dm.Ret();
316 return dm.CreateDelegate();
317 }
318
319 internal static Delegate CreateDynamicOnly(RuntimeContext context, RuntimeJavaMethod mw, java.lang.invoke.MethodType type)
320 {
321 FinishTypes(type);
322
323 var dm = new DynamicMethodBuilder(context, "CustomInvoke:" + mw.Name, type, null, mw, null, null, true);
324 dm.ilgen.Emit(OpCodes.Ldarg_0);
325 if (mw.IsStatic)
326 {
327 dm.LoadNull();
328 dm.BoxArgs(0);
329 }
330 else
331 {
332 dm.Ldarg(0);
333 dm.BoxArgs(1);
334 }
335 dm.Callvirt(typeof(RuntimeJavaMethod).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic));
336 dm.UnboxReturnValue();
337
338 dm.Ret();
339 return dm.CreateDelegate();
340 }
341
342 internal static Delegate CreateMemberName(RuntimeContext context, RuntimeJavaMethod mw, global::java.lang.invoke.MethodType type, bool doDispatch)
343 {
344 FinishTypes(type);
345
346 var tw = mw.DeclaringType;
347 var owner = tw.TypeAsBaseType;
348 var dm = new DynamicMethodBuilder(context, "MemberName:" + mw.DeclaringType.Name + "::" + mw.Name + mw.Signature, type, null, mw.HasCallerID ? DynamicCallerIDProvider.Instance : null, null, owner, true);
349 for (int i = 0, count = type.parameterCount(); i < count; i++)
350 {
351 if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType || tw.IsRemapped) && (!mw.IsConstructor || tw != context.JavaBase.TypeOfJavaLangString))
352 {
353 if (tw.IsGhost || tw.IsNonPrimitiveValueType)
354 {
355 dm.LoadFirstArgAddress(tw);
356 }
357 else
358 {
359 Debug.Assert(tw.IsRemapped);
360
361 // TODO this must be checked
362 dm.Ldarg(0);
363 if (mw.IsConstructor)
364 dm.EmitCastclass(tw.TypeAsBaseType);
365 else if (tw != context.JavaBase.TypeOfCliSystemObject)
366 dm.EmitCheckcast(tw);
367 }
368 }
369 else
370 {
371 dm.Ldarg(i);
372 var argType = RuntimeJavaType.FromClass(type.parameterType(i));
373 if (!argType.IsPrimitive)
374 {
375 if (argType.IsUnloadable)
376 {
377
378 }
379 else if (argType.IsNonPrimitiveValueType)
380 {
381 dm.Unbox(argType);
382 }
383 else if (argType.IsGhost)
384 {
385 dm.UnboxGhost(argType);
386 }
387 else
388 {
389 dm.EmitCheckcast(argType);
390 }
391 }
392 }
393 }
394
395 if (mw.HasCallerID)
396 dm.LoadCallerID();
397
398 // special case for Object.clone() and Object.finalize()
399 if (mw.IsFinalizeOrClone)
400 {
401 if (doDispatch)
402 {
403 mw.EmitCallvirtReflect(dm.ilgen);
404 }
405 else
406 {
407 // we can re-use the implementations from cli.System.Object (even though the object may not in-fact extend cli.System.Object)
408 context.JavaBase.TypeOfCliSystemObject.GetMethod(mw.Name, mw.Signature, false).EmitCall(dm.ilgen);
409 }
410 }
411 else if (doDispatch && !mw.IsStatic)
412 {
413 dm.Callvirt(mw);
414 }
415 else
416 {
417 dm.Call(mw);
418 }
419
420 var retType = RuntimeJavaType.FromClass(type.returnType());
421 if (retType.IsUnloadable)
422 {
423
424 }
425 else if (retType.IsNonPrimitiveValueType)
426 {
427 dm.Box(retType);
428 }
429 else if (retType.IsGhost)
430 {
431 dm.BoxGhost(retType);
432 }
433 else if (retType == context.PrimitiveJavaTypeFactory.BYTE)
434 {
435 dm.CastByte();
436 }
437
438 dm.Ret();
439 return dm.CreateDelegate();
440 }
441
442 internal void Call(MethodInfo method)
443 {
444 ilgen.Emit(OpCodes.Call, method);
445 }
446
447 internal void Callvirt(MethodInfo method)
448 {
449 ilgen.Emit(OpCodes.Callvirt, method);
450 }
451
452 internal void Call(RuntimeJavaMethod mw)
453 {
454 mw.EmitCall(ilgen);
455 }
456
457 internal void Callvirt(RuntimeJavaMethod mw)
458 {
459 mw.EmitCallvirt(ilgen);
460 }
461
462 internal void CallDelegate(Type delegateType)
463 {
464 context.MethodHandleUtil.EmitCallDelegateInvokeMethod(ilgen, delegateType);
465 }
466
467 internal void LoadFirstArgAddress(RuntimeJavaType tw)
468 {
469 ilgen.EmitLdarg(0);
470 if (tw.IsGhost)
471 {
472 tw.EmitConvStackTypeToSignatureType(ilgen, null);
473 var local = ilgen.DeclareLocal(tw.TypeAsSignatureType);
474 ilgen.Emit(OpCodes.Stloc, local);
475 ilgen.Emit(OpCodes.Ldloca, local);
476 }
477 else if (tw.IsNonPrimitiveValueType)
478 {
479 ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
480 }
481 else
482 {
483 throw new InvalidOperationException();
484 }
485 }
486
487 internal void Ldarg(int i)
488 {
489 context.MethodHandleUtil.LoadPackedArg(ilgen, i, firstArg, packedArgPos, packedArgType);
490 }
491
492 internal void LoadCallerID()
493 {
494 ilgen.Emit(OpCodes.Ldarg_0);
495 ilgen.Emit(OpCodes.Call, context.ByteCodeHelperMethods.DynamicCallerID);
496 }
497
498 internal void LoadValueAddress()
499 {
500 ilgen.Emit(OpCodes.Ldarg_0);
501 ilgen.Emit(OpCodes.Ldflda, container.GetField("value"));
502 }
503
504 internal void Ret()
505 {
506 ilgen.Emit(OpCodes.Ret);
507 }
508
509 internal Delegate CreateDelegate()
510 {
511 //Console.WriteLine(delegateType);
512 //ilgen.DumpMethod();
513 ilgen.DoEmit();
514 return ValidateDelegate(firstArg == 0
515 ? dm.CreateDelegate(delegateType)
516 : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue)));
517 }
518
519 internal void BoxArgs(int start)
520 {
521 int paramCount = type.parameterCount();
522 ilgen.EmitLdc_I4(paramCount - start);
523 ilgen.Emit(OpCodes.Newarr, context.Types.Object);
524 for (int i = start; i < paramCount; i++)
525 {
526 ilgen.Emit(OpCodes.Dup);
527 ilgen.EmitLdc_I4(i - start);
528 Ldarg(i);
529 var tw = RuntimeJavaType.FromClass(type.parameterType(i));
530 if (tw.IsPrimitive)
531 ilgen.Emit(OpCodes.Box, tw.TypeAsSignatureType);
532
533 ilgen.Emit(OpCodes.Stelem_Ref);
534 }
535 }
536
537 internal void UnboxReturnValue()
538 {
539 var tw = RuntimeJavaType.FromClass(type.returnType());
540 if (tw == context.PrimitiveJavaTypeFactory.VOID)
541 {
542 ilgen.Emit(OpCodes.Pop);
543 }
544 else if (tw.IsPrimitive)
545 {
546 ilgen.Emit(OpCodes.Unbox, tw.TypeAsSignatureType);
547 ilgen.Emit(OpCodes.Ldobj, tw.TypeAsSignatureType);
548 }
549 }
550
551 internal void LoadNull()
552 {
553 ilgen.Emit(OpCodes.Ldnull);
554 }
555
556 internal void Unbox(RuntimeJavaType tw)
557 {
558 tw.EmitUnbox(ilgen);
559 }
560
561 internal void Box(RuntimeJavaType tw)
562 {
563 tw.EmitBox(ilgen);
564 }
565
566 internal void UnboxGhost(RuntimeJavaType tw)
567 {
568 tw.EmitConvStackTypeToSignatureType(ilgen, null);
569 }
570
571 internal void BoxGhost(RuntimeJavaType tw)
572 {
573 tw.EmitConvSignatureTypeToStackType(ilgen);
574 }
575
576 internal void EmitCheckcast(RuntimeJavaType tw)
577 {
578 tw.EmitCheckcast(ilgen);
579 }
580
581 internal void EmitCastclass(Type type)
582 {
583 ilgen.EmitCastclass(type);
584 }
585
586 internal void EmitWriteLine()
587 {
588 ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }));
589 }
590
591 internal void CastByte()
592 {
593 ilgen.Emit(OpCodes.Conv_I1);
594 }
595
596 internal void DumpMethod()
597 {
598 Console.WriteLine(dm.Name + ", type = " + delegateType);
599 ilgen.DumpMethod();
600 }
601
602 private static void FinishTypes(global::java.lang.invoke.MethodType type)
603 {
604 // FXBUG(?) DynamicILGenerator doesn't like SymbolType (e.g. an array of a TypeBuilder)
605 // so we have to finish the signature types
606 RuntimeJavaType.FromClass(type.returnType()).Finish();
607 for (int i = 0; i < type.parameterCount(); i++)
608 RuntimeJavaType.FromClass(type.parameterType(i)).Finish();
609 }
610 }
611
612#if DEBUG
613 [System.Security.SecuritySafeCritical]
614#endif
615 static Delegate ValidateDelegate(Delegate d)
616 {
617#if DEBUG
618 try
619 {
620 System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(d);
621 }
622 catch (Exception e)
623 {
624 throw new InternalException("Delegate failed to JIT", e);
625 }
626#endif
627 return d;
628 }
629
630 internal Type GetDelegateTypeForInvokeExact(global::java.lang.invoke.MethodType type)
631 {
632 type._invokeExactDelegateType ??= CreateMethodHandleDelegateType(type);
633 return type._invokeExactDelegateType;
634 }
635
636 internal T GetDelegateForInvokeExact<T>(global::java.lang.invoke.MethodHandle mh)
637 where T : class, Delegate
638 {
639 var type = mh.type();
640 if (mh._invokeExactDelegate == null)
641 {
642 type._invokeExactDynamicMethod ??= DynamicMethodBuilder.CreateInvokeExact(context, type);
643 mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type), mh);
644 var del = mh._invokeExactDelegate as T;
645 if (del != null)
646 return del;
647 }
648
649 throw java.lang.invoke.Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type);
650 }
651
657 internal static object GetVoidAdapter(java.lang.invoke.MemberName mn)
658 {
659 var type = mn.getMethodType();
660 if (type.voidAdapter == null)
661 {
662 if (type.returnType() == global::java.lang.Void.TYPE)
663 return mn.vmtarget;
664
665 type.voidAdapter = DynamicMethodBuilder.CreateVoidAdapter(JVM.Context, type);
666 }
667
668 return type.voidAdapter;
669 }
670
671 internal void LoadPackedArg(CodeEmitter ilgen, int index, int firstArg, int packedArgPos, Type packedArgType)
672 {
673 index += firstArg;
674 if (index >= packedArgPos)
675 {
676 ilgen.EmitLdarga(packedArgPos);
677 var fieldPos = index - packedArgPos;
678 var type = packedArgType;
679 while (fieldPos >= MaxArity || (fieldPos == MaxArity - 1 && IsPackedArgsContainer(type.GetField("t8").FieldType)))
680 {
681 var field = type.GetField("t8");
682 type = field.FieldType;
683 ilgen.Emit(OpCodes.Ldflda, field);
684 fieldPos -= MaxArity - 1;
685 }
686 ilgen.Emit(OpCodes.Ldfld, type.GetField("t" + (1 + fieldPos)));
687 }
688 else
689 {
690 ilgen.EmitLdarg(index);
691 }
692 }
693
694#endif
695
696 }
697
698}
699
700#endif
IKVM.Reflection.Type Type
IKVM.Reflection.MethodInfo MethodInfo
IKVM.Reflection.MethodBase MethodBase
MethodHandleUtil(RuntimeContext context)
Initializes a new instance.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.