51 MethodBuilder getInstance;
64 var bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod);
67 if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm))
72 if (lmf.getInstance ==
null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen))
75 if (context.TypeWrapper.ClassLoader.DisableDynamicBinding)
76 context.TypeWrapper.ClassLoader.Diagnostics.UnableToCreateLambdaFactory();
82 ilgen.Emit(OpCodes.Call, lmf.getInstance);
97 if (HasUnloadable(cpi))
99 Fail(
"cpi has unloadable");
103 var serializable =
false;
104 var markers = Array.Empty<RuntimeJavaType>();
109 if (bsm.ArgumentCount > 3)
111 var flags = (AltFlags)classFile.GetConstantPoolConstantInteger((IntegerConstantHandle)bsm.GetArgument(3));
112 serializable = (flags & AltFlags.Serializable) != 0;
115 if ((flags & AltFlags.Markers) != 0)
117 markers =
new RuntimeJavaType[classFile.GetConstantPoolConstantInteger((IntegerConstantHandle)bsm.GetArgument(argpos++))];
118 for (
int i = 0; i < markers.Length; i++)
120 if ((markers[i] = classFile.GetConstantPoolClassType((ClassConstantHandle)bsm.GetArgument(argpos++))).IsUnloadable)
122 Fail(
"unloadable marker");
128 if ((flags & AltFlags.Bridges) != 0)
131 for (
int i = 0; i < bridges.Length; i++)
133 bridges[i] = classFile.GetConstantPoolConstantMethodType((MethodTypeConstantHandle)bsm.GetArgument(argpos++));
134 if (HasUnloadable(bridges[i]))
136 Fail(
"unloadable bridge");
143 var samMethodType = classFile.GetConstantPoolConstantMethodType((MethodTypeConstantHandle)bsm.GetArgument(0));
144 var implMethod = classFile.GetConstantPoolConstantMethodHandle((MethodHandleConstantHandle)bsm.GetArgument(1));
145 var instantiatedMethodType = classFile.GetConstantPoolConstantMethodType((MethodTypeConstantHandle)bsm.GetArgument(2));
146 if (HasUnloadable(samMethodType) || HasUnloadable((
ClassFile.
ConstantPoolItemMI)implMethod.MemberConstantPoolItem) || HasUnloadable(instantiatedMethodType))
148 Fail(
"bsm args has unloadable");
152 var interfaceType = cpi.GetRetType();
153 if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out var methodList))
155 Fail(
"unsupported interface");
159 if (serializable && Array.Exists(methodList, mw => mw.Name ==
"writeReplace" && mw.Signature ==
"()Ljava.lang.Object;"))
161 Fail(
"writeReplace");
165 if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType))
167 Fail(
"implMethod " + implMethod.MemberConstantPoolItem.Class +
"::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature);
172 var implParameters = GetImplParameters(implMethod);
173 CheckConstraints(instantiatedMethodType, samMethodType, cpi.GetArgTypes(), implParameters);
178 foreach (var bridge
in bridges)
180 if (bridge.Signature == samMethodType.Signature)
182 Fail(
"bridge signature matches sam");
186 if (!CheckConstraints(instantiatedMethodType, bridge, cpi.GetArgTypes(), implParameters))
188 Fail(
"bridge constraints");
195 if (instantiatedMethodType.GetRetType() != context.Context.PrimitiveJavaTypeFactory.VOID)
197 var Rt = instantiatedMethodType.GetRetType();
198 var Ra = GetImplReturnType(implMethod);
199 if (Ra == context.Context.PrimitiveJavaTypeFactory.VOID || !IsAdaptable(Ra, Rt,
true))
201 Fail(
"The return type Rt is void, or the return type Ra is not void and is adaptable to Rt");
208 var methods =
new List<RuntimeJavaMethod>();
209 foreach (var mw
in methodList)
212 if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature)
214 interfaceMethod = mw;
219 if (mw.IsAbstract && !IsObjectMethod(mw))
227 if (interfaceMethod ==
null || !interfaceMethod.IsAbstract || IsObjectMethod(interfaceMethod) || !MatchSignatures(interfaceMethod, samMethodType))
229 Fail(
"interfaceMethod");
234 var tb = context.DefineAnonymousClass();
238 tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType);
239 if (serializable && Array.IndexOf(markers, context.Context.JavaBase.TypeOfJavaIoSerializable) == -1)
240 tb.AddInterfaceImplementation(context.Context.JavaBase.TypeOfJavaIoSerializable.TypeAsBaseType);
243 foreach (var marker
in markers)
244 tb.AddInterfaceImplementation(marker.TypeAsBaseType);
246 getInstance = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
247 AddDefaultInterfaceMethods(context, methodList, tb);
251 [Conditional(
"TRACE_LAMBDA_METAFACTORY")]
252 static void Fail(
string msg)
254 Console.WriteLine(
"Fail: " + msg);
267 if (!IsSubTypeOf(instantiatedMethodType, methodType))
269 Fail(
"instantiatedMethodType <= methodType");
273 if (args.Length + methodType.GetArgTypes().Length != implParameters.Length)
279 for (
int i = 0, K = args.Length; i < K; i++)
281 if (args[i] == implParameters[i])
285 else if (args[i].IsPrimitive || implParameters[i].IsPrimitive || !args[i].IsSubTypeOf(implParameters[i]))
287 Fail(
"For i=1..K, Di = Ai");
292 for (
int i = 0, N = methodType.GetArgTypes().Length, k = args.Length; i < N; i++)
294 if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k],
false))
296 Fail(
"For i=1..N, Ti is adaptable to Aj, where j=i+k");
307 var parameters = mw.GetParameters();
308 if (mw.IsStatic || mw.IsConstructor)
311 return ArrayUtil.Concat(mw.DeclaringType, parameters);
316 return implMethod.Kind == MethodHandleKind.NewInvokeSpecial ? implMethod.Member.DeclaringType : ((
RuntimeJavaMethod)implMethod.Member).ReturnType;
319 static bool IsAdaptable(RuntimeJavaType Q, RuntimeJavaType S,
bool isReturn)
329 switch (Q.SigName[0] | S.SigName[0] << 8)
358 return GetBoxedPrimitiveType(Q).IsAssignableTo(S);
370 var primitive = GetUnboxedPrimitiveType(Q);
371 return primitive !=
null && IsAdaptable(primitive, S, isReturn);
376 return Q.IsAssignableTo(S);
387 static RuntimeJavaType GetBoxedPrimitiveType(RuntimeJavaType primitive)
389 Debug.Assert(primitive.IsPrimitive);
390 switch (primitive.SigName[0])
409 throw new InvalidOperationException();
418 static RuntimeJavaType GetUnboxedPrimitiveType(RuntimeJavaType wrapper)
420 switch (wrapper.Name)
422 case "java.lang.Boolean":
424 case "java.lang.Byte":
426 case "java.lang.Short":
428 case "java.lang.Character":
430 case "java.lang.Integer":
432 case "java.lang.Long":
434 case "java.lang.Float":
436 case "java.lang.Double":
445 var T = instantiatedMethodType.GetArgTypes();
446 var U = samMethodType.GetArgTypes();
447 if (T.Length != U.Length)
450 for (
int i = 0; i < T.Length; i++)
451 if (!T[i].IsAssignableTo(U[i]))
454 var Rt = instantiatedMethodType.GetRetType();
455 var Ru = samMethodType.GetRetType();
456 return Rt.IsAssignableTo(Ru);
474 var args = cpi.GetArgTypes();
477 var capturedTypes =
new Type[args.Length];
478 var capturedFields =
new FieldBuilder[capturedTypes.Length];
479 for (
int i = 0; i < capturedTypes.Length; i++)
481 capturedTypes[i] = args[i].TypeAsSignatureType;
482 var attr = FieldAttributes.Private;
483 if (i > 0 || !args[0].IsGhost)
484 attr |= FieldAttributes.InitOnly;
486 capturedFields[i] = tb.DefineField(
"arg$" + (i + 1), capturedTypes[i], attr);
490 var ctor =
ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes);
492 ilgen.Emit(OpCodes.Ldarg_0);
493 ilgen.Emit(OpCodes.Call, context.Context.Types.Object.GetConstructor(
Type.EmptyTypes));
494 for (
int i = 0; i < capturedTypes.Length; i++)
497 ilgen.EmitLdarg(i + 1);
498 ilgen.Emit(OpCodes.Stfld, capturedFields[i]);
500 ilgen.Emit(OpCodes.Ret);
504 var getInstance = tb.DefineMethod(
"__<GetInstance>", MethodAttributes.Assembly | MethodAttributes.Static, cpi.GetRetType().TypeAsBaseType, capturedTypes);
505 var ilgenGet = context.Context.CodeEmitterFactory.Create(getInstance);
507 if (capturedTypes.Length == 0)
510 var instField = tb.DefineField(
"inst", tb, FieldAttributes.Private | FieldAttributes.Static);
513 var cctor =
ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.ClassLoader);
514 var ilgenCCtor = context.Context.CodeEmitterFactory.Create(cctor);
515 ilgenCCtor.Emit(OpCodes.Newobj, ctor);
516 ilgenCCtor.Emit(OpCodes.Stsfld, instField);
517 ilgenCCtor.Emit(OpCodes.Ret);
521 ilgenGet.Emit(OpCodes.Ldsfld, instField);
526 for (
int i = 0; i < capturedTypes.Length; i++)
527 ilgenGet.EmitLdarg(i);
529 ilgenGet.Emit(OpCodes.Newobj, ctor);
533 ilgenGet.Emit(OpCodes.Castclass, cpi.GetRetType().TypeAsBaseType);
534 ilgenGet.Emit(OpCodes.Ret);
538 foreach (var mw
in methods)
539 EmitDispatch(context, args, tb, mw, implParameters, implMethod, instantiatedMethodType, capturedFields);
544 var writeReplace = tb.DefineMethod(
"writeReplace", MethodAttributes.Private, context.Context.Types.Object,
Type.EmptyTypes);
546 context.TypeWrapper.EmitClassLiteral(ilgen);
547 ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace(
'.',
'/'));
548 ilgen.Emit(OpCodes.Ldstr, cpi.Name);
549 ilgen.Emit(OpCodes.Ldstr, samMethodType.Signature.Replace(
'.',
'/'));
550 ilgen.EmitLdc_I4((
int)implMethod.Kind);
551 ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace(
'.',
'/'));
552 ilgen.Emit(OpCodes.Ldstr, implMethod.Name);
553 ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace(
'.',
'/'));
554 ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace(
'.',
'/'));
555 ilgen.EmitLdc_I4(capturedFields.Length);
556 ilgen.Emit(OpCodes.Newarr, context.Context.Types.Object);
557 for (
int i = 0; i < capturedFields.Length; i++)
559 ilgen.Emit(OpCodes.Dup);
562 ilgen.Emit(OpCodes.Ldfld, capturedFields[i]);
563 if (args[i].IsPrimitive)
565 context.Context.Boxer.EmitBox(ilgen, args[i]);
567 else if (args[i].IsGhost)
569 args[i].EmitConvSignatureTypeToStackType(ilgen);
571 ilgen.Emit(OpCodes.Stelem, context.Context.Types.Object);
573 RuntimeJavaMethod ctorSerializedLambda = context.Context.ClassLoaderFactory.LoadClassCritical(
"java.lang.invoke.SerializedLambda").GetMethod(
StringConstants.INIT,
574 "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V",
false);
575 ctorSerializedLambda.Link();
576 ctorSerializedLambda.EmitNewobj(ilgen);
577 ilgen.Emit(OpCodes.Ret);
580 if (!context.TypeWrapper.ClassLoader.NoAutomagicSerialization)
583 context.Context.Serialization.MarkSerializable(tb);
584 context.Context.Serialization.AddGetObjectData(tb);
605 var mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
606 if (interfaceMethod.Name != interfaceMethod.RealName)
607 tb.DefineMethodOverride(mb, (
MethodInfo)interfaceMethod.GetMethod());
609 context.Context.AttributeHelper.HideFromJava(mb);
612 for (
int i = 0; i < capturedFields.Length; i++)
615 var opc = OpCodes.Ldfld;
616 if (i == 0 && args[0].IsGhost)
618 switch (implMethod.Kind)
620 case MethodHandleKind.InvokeInterface:
621 case MethodHandleKind.InvokeVirtual:
622 case MethodHandleKind.InvokeSpecial:
623 opc = OpCodes.Ldflda;
628 ilgen.Emit(opc, capturedFields[i]);
635 for (
int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++)
637 ilgen.EmitLdarg(i + 1);
638 var Ui = interfaceMethod.GetParameters()[i];
639 var Ti = instantiatedMethodType.GetArgTypes()[i];
640 var Aj = implParameters[i + k];
643 if (Ui == context.Context.PrimitiveJavaTypeFactory.BYTE)
644 ilgen.Emit(OpCodes.Conv_I1);
651 Ti.EmitConvStackTypeToSignatureType(ilgen, Ui);
655 Ui.EmitConvSignatureTypeToStackType(ilgen);
659 Ti.EmitCheckcast(ilgen);
666 if (Ti.IsPrimitive && !Aj.IsPrimitive)
669 context.Context.Boxer.EmitBox(ilgen, Ti);
671 else if (!Ti.IsPrimitive && Aj.IsPrimitive)
674 var primitive = GetUnboxedPrimitiveType(Ti);
675 context.Context.Boxer.EmitUnbox(ilgen, primitive,
false);
676 if (primitive == context.Context.PrimitiveJavaTypeFactory.BYTE)
677 ilgen.Emit(OpCodes.Conv_I1);
679 else if (Aj == context.Context.PrimitiveJavaTypeFactory.LONG)
682 ilgen.Emit(OpCodes.Conv_I8);
684 else if (Aj == context.Context.PrimitiveJavaTypeFactory.FLOAT)
687 ilgen.Emit(OpCodes.Conv_R4);
689 else if (Aj == context.Context.PrimitiveJavaTypeFactory.DOUBLE)
692 ilgen.Emit(OpCodes.Conv_R8);
697 Aj.EmitConvStackTypeToSignatureType(ilgen, Ti);
702 switch (implMethod.Kind)
704 case MethodHandleKind.InvokeVirtual:
705 case MethodHandleKind.InvokeInterface:
708 case MethodHandleKind.NewInvokeSpecial:
711 case MethodHandleKind.InvokeStatic:
712 case MethodHandleKind.InvokeSpecial:
716 throw new InvalidOperationException();
719 var Ru = interfaceMethod.ReturnType;
720 var Ra = GetImplReturnType(implMethod);
721 var Rt = instantiatedMethodType.GetRetType();
723 if (Ra == context.Context.PrimitiveJavaTypeFactory.BYTE)
725 ilgen.Emit(OpCodes.Conv_I1);
730 if (Ru == context.Context.PrimitiveJavaTypeFactory.VOID)
732 ilgen.Emit(OpCodes.Pop);
736 Ra.EmitConvSignatureTypeToStackType(ilgen);
740 Ru.EmitConvStackTypeToSignatureType(ilgen, Ra);
748 if (Rt == context.Context.PrimitiveJavaTypeFactory.VOID)
752 else if (!Ra.IsPrimitive)
754 var primitive = GetUnboxedPrimitiveType(Ra);
755 if (primitive !=
null)
757 context.Context.Boxer.EmitUnbox(ilgen, primitive,
false);
762 EmitConvertingUnbox(ilgen, Rt);
765 else if (Rt == context.Context.PrimitiveJavaTypeFactory.LONG)
767 ilgen.Emit(OpCodes.Conv_I8);
769 else if (Rt == context.Context.PrimitiveJavaTypeFactory.FLOAT)
771 ilgen.Emit(OpCodes.Conv_R4);
773 else if (Rt == context.Context.PrimitiveJavaTypeFactory.DOUBLE)
775 ilgen.Emit(OpCodes.Conv_R8);
778 else if (Ra.IsPrimitive)
780 var tw = GetUnboxedPrimitiveType(Rt);
784 context.Context.Boxer.EmitBox(ilgen, tw);
788 Rt.EmitCheckcast(ilgen);
791 ilgen.EmitTailCallPrevention();
792 ilgen.Emit(OpCodes.Ret);
796 static void EmitConvertingUnbox(
CodeEmitter ilgen, RuntimeJavaType tw)
798 switch (tw.SigName[0])
802 tw.Context.
Boxer.EmitUnbox(ilgen, tw,
true);
805 EmitUnboxNumber(tw.Context, ilgen,
"byteValue",
"()B");
808 EmitUnboxNumber(tw.Context, ilgen,
"shortValue",
"()S");
811 EmitUnboxNumber(tw.Context, ilgen,
"intValue",
"()I");
814 EmitUnboxNumber(tw.Context, ilgen,
"longValue",
"()J");
817 EmitUnboxNumber(tw.Context, ilgen,
"floatValue",
"()F");
820 EmitUnboxNumber(tw.Context, ilgen,
"doubleValue",
"()D");
823 throw new InvalidOperationException();
830 tw.EmitCheckcast(ilgen);
831 var mw = tw.GetMethod(methodName, methodSig,
false);
833 mw.EmitCallvirt(ilgen);
839 const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName;
841 var factory = context.TypeWrapper.ClassLoader.GetTypeWrapperFactory();
842 foreach (var mw
in methodList)
846 var mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr);
847 if (mw.Name != mw.RealName)
848 tb.DefineMethodOverride(mb, (
MethodInfo)mw.GetMethod());
850 context.EmitCallDefaultInterfaceMethod(mb, mw);
852 else if (IsObjectMethod(mw))
854 var mb = mw.GetDefineMethodHelper().DefineMethod(factory, tb, mw.Name, attr);
855 if (mw.Name != mw.RealName)
856 tb.DefineMethodOverride(mb, (
MethodInfo)mw.GetMethod());
859 for (
int i = 0, count = mw.GetParameters().Length; i <= count; i++)
862 context.Context.
JavaBase.TypeOfJavaLangObject.GetMethod(mw.Name, mw.Signature,
false).EmitCallvirt(ilgen);
863 ilgen.Emit(OpCodes.Ret);
871 switch (implMethod.Kind)
873 case MethodHandleKind.InvokeVirtual:
874 case MethodHandleKind.InvokeInterface:
875 case MethodHandleKind.NewInvokeSpecial:
876 case MethodHandleKind.InvokeStatic:
877 case MethodHandleKind.InvokeSpecial:
884 if (mw ==
null || mw.HasCallerID ||
RuntimeByteCodeJavaType.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature))
887 RuntimeJavaType instance;
888 if (mw.IsConstructor)
890 instance = mw.DeclaringType;
892 else if (mw.IsStatic)
899 instance = captured.Length == 0 ? instantiatedMethodType.GetArgTypes()[0] : captured[0];
900 if (!instance.IsAssignableTo(mw.DeclaringType))
904 if (!mw.IsAccessibleFrom(mw.DeclaringType, caller, instance))
911 static bool IsSupportedInterface(RuntimeJavaType tw, RuntimeJavaType caller)
913 return tw.IsInterface && !tw.IsGhost && tw.IsAccessibleFrom(caller) && !tw.Context.
Serialization.IsISerializable(tw);
919 if (!IsSupportedInterface(tw, caller))
925 Dictionary<MethodKey, RuntimeJavaMethod> methods =
new Dictionary<MethodKey, RuntimeJavaMethod>();
926 int abstractMethodCount = 0;
927 int bridgeMethodCount = 0;
928 if (GatherAllInterfaceMethods(tw, bridges, methods,
ref abstractMethodCount,
ref bridgeMethodCount) && abstractMethodCount == 1)
930 foreach (var marker
in markers)
932 if (!IsSupportedInterface(marker, caller))
938 if (!GatherAllInterfaceMethods(marker,
null, methods,
ref abstractMethodCount,
ref bridgeMethodCount) || abstractMethodCount != 1)
945 if (bridges !=
null && bridgeMethodCount != bridges.Length)
952 methods.Values.CopyTo(methodList, 0);
960 static bool GatherAllInterfaceMethods(RuntimeJavaType tw,
ClassFile.
ConstantPoolItemMethodType[] bridges, Dictionary<MethodKey, RuntimeJavaMethod> methods,
ref int abstractMethodCount,
ref int bridgeMethodCount)
962 foreach (var mw
in tw.GetMethods())
968 if (mmw.Error !=
null)
974 var key =
new MethodKey(
"", mw.Name, mw.Signature);
975 if (methods.TryGetValue(key, out var current))
977 if (!MatchSignatures(mw, current))
985 methods.Add(key, mw);
987 if (mw.IsAbstract && !IsObjectMethod(mw))
989 if (bridges !=
null && IsBridge(mw, bridges))
992 abstractMethodCount++;
997 if (mw.GetMethod() ==
null)
1000 if (current !=
null && mw.RealName != current.RealName)
1005 foreach (var tw1
in tw.Interfaces)
1006 if (!GatherAllInterfaceMethods(tw1, bridges, methods,
ref abstractMethodCount,
ref bridgeMethodCount))
1015 if (bridge.Signature == mw.Signature)
1024 return (objectMethod = mw.DeclaringType.Context.
JavaBase.TypeOfJavaLangObject.GetMethod(mw.Name, mw.Signature,
false)) !=
null && objectMethod.IsPublic;
1029 return interfaceMethod.ReturnType == samMethodType.GetRetType() && MatchTypes(interfaceMethod.GetParameters(), samMethodType.GetArgTypes());
1036 return mw1.ReturnType == mw2.ReturnType && MatchTypes(mw1.GetParameters(), mw2.GetParameters());
1039 static bool MatchTypes(RuntimeJavaType[] ar1, RuntimeJavaType[] ar2)
1041 if (ar1.Length != ar2.Length)
1044 for (
int i = 0; i < ar1.Length; i++)
1045 if (ar1[i] != ar2[i])
1059 return bsm.ArgumentCount == 3 &&
1060 classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType &&
1061 classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle &&
1062 classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType &&
1063 classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex) is { Kind: MethodHandleKind.InvokeStatic, Member: not
null } mh &&
1064 IsLambdaMetafactory(mh.Member);
1074 return mw.Name ==
"metafactory"
1075 && mw.Signature ==
"(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodType;Ljava.lang.invoke.MethodHandle;Ljava.lang.invoke.MethodType;)Ljava.lang.invoke.CallSite;"
1076 && mw.DeclaringType.Name ==
"java.lang.invoke.LambdaMetafactory";
1085 Mask = Serializable | Markers | Bridges
1090 ClassFile.ConstantPoolItemMethodHandle mh;
1093 return bsm.ArgumentCount >= 4
1094 && (mh = classFile.GetConstantPoolConstantMethodHandle(bsm.BootstrapMethodIndex)).Kind == MethodHandleKind.InvokeStatic
1095 && mh.Member !=
null
1096 && IsLambdaAltMetafactory(mh.Member)
1097 && classFile.GetConstantPoolConstantType(bsm.GetArgument(0)) == ClassFile.ConstantType.MethodType
1098 && classFile.GetConstantPoolConstantType(bsm.GetArgument(1)) == ClassFile.ConstantType.MethodHandle
1099 && classFile.GetConstantPoolConstantType(bsm.GetArgument(2)) == ClassFile.ConstantType.MethodType
1100 && classFile.GetConstantPoolConstantType(bsm.GetArgument(3)) == ClassFile.ConstantType.Integer
1101 && ((flags = (AltFlags)classFile.GetConstantPoolConstantInteger((IntegerConstantHandle)bsm.GetArgument(3))) & ~AltFlags.Mask) == 0
1102 && ((flags & AltFlags.Markers) == 0 || CheckOptionalArgs(classFile, bsm,
ClassFile.ConstantType.Class,
ref argpos))
1103 && ((flags & AltFlags.Bridges) == 0 || CheckOptionalArgs(classFile, bsm,
ClassFile.ConstantType.MethodType,
ref argpos))
1104 && argpos == bsm.ArgumentCount;
1109 return mw.Name ==
"altMetafactory"
1110 && mw.Signature ==
"(Ljava.lang.invoke.MethodHandles$Lookup;Ljava.lang.String;Ljava.lang.invoke.MethodType;[Ljava.lang.Object;)Ljava.lang.invoke.CallSite;"
1111 && mw.DeclaringType.Name ==
"java.lang.invoke.LambdaMetafactory";
1116 if (bsm.ArgumentCount - argpos < 1)
1119 if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos)) !=
ClassFile.ConstantType.Integer)
1122 int count = classFile.GetConstantPoolConstantInteger((IntegerConstantHandle)bsm.GetArgument(argpos++));
1123 if (count < 0 || bsm.ArgumentCount - argpos < count)
1126 for (
int i = 0; i < count; i++)
1127 if (classFile.GetConstantPoolConstantType(bsm.GetArgument(argpos++)) != type)
1135 return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable;
1140 return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable;
1145 return HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable;
1148 private static bool HasUnloadable(RuntimeJavaType[] wrappers)
1150 foreach (RuntimeJavaType tw
in wrappers)
1152 if (tw.IsUnloadable)