46 FieldInfo ghostRefField;
47 MethodBuilder ghostIsInstanceMethod;
48 MethodBuilder ghostIsInstanceArrayMethod;
49 MethodBuilder ghostCastMethod;
50 MethodBuilder ghostCastArrayMethod;
51 TypeBuilder typeBuilderGhostInterface;
62 base(
null, f, loader,
null)
67 internal override void Finish()
76 readonly TypeBuilder typeBuilder;
78 MethodBuilder constructorBuilder;
87 base(ctor.DeclaringType, ctor.Name, ctor.Signature,
null,
null,
null, ctor.Modifiers,
MemberFlags.None)
89 this.context = context;
90 this.typeBuilder = typeBuilder;
94 protected override void DoLinkMethod()
98 constructorBuilder = dmh.DefineConstructor(context, typeBuilder, MethodAttributes.PrivateScope);
99 ctor.DeclaringType.Context.AttributeHelper.HideFromJava(constructorBuilder);
101 ilgen.Emit(OpCodes.Ldarg_0);
102 for (
int i = 1; i <= dmh.ParameterCount; i++)
106 ctor.EmitCall(ilgen);
107 ilgen.Emit(OpCodes.Ret);
113 ilgen.Emit(OpCodes.Call, constructorBuilder);
117 internal override bool IsGhost =>
classLoader.IsGhost(
this);
119 internal override bool IsMapUnsafeException =>
classLoader.IsMapUnsafeException(
this);
121 internal override Type TypeAsBaseType => typeBuilderGhostInterface !=
null ? typeBuilderGhostInterface : base.TypeAsBaseType;
123 internal void GetParameterNamesFromXml(
string methodName,
string methodSig,
string[] parameterNames)
125 var parameters =
classLoader.GetXmlMapParameters(
Name, methodName, methodSig);
126 if (parameters !=
null)
127 for (
int i = 0; i < parameters.Length; i++)
128 if (parameters[i].
Name !=
null)
129 parameterNames[i] = parameters[i].Name;
132 internal void AddXmlMapParameterAttributes(MethodBuilder method,
string className,
string methodName,
string methodSig,
ref ParameterBuilder[] parameterBuilders)
134 var parameters =
classLoader.GetXmlMapParameters(className, methodName, methodSig);
135 if (parameters !=
null)
138 if (parameters.Length > parameterBuilders.Length)
139 throw new InvalidOperationException($
"Number of parameters in map XML exceeds the number of parameters being built for '{className}:{methodName}' ({parameters.Length} > {parameterBuilders.Length}).");
141 for (
int i = 0; i < parameters.Length; i++)
142 if (parameters[i].Attributes !=
null)
143 foreach (var attr
in parameters[i].Attributes)
150 ParameterBuilder[] pbs;
151 if ((mw.DeclaringType.IsPublic && (mw.IsPublic || mw.IsProtected)) ||
classLoader.EmitSymbols)
153 string[] parameterNames =
new string[mw.GetParameters().Length];
154 GetParameterNamesFromXml(mw.Name, mw.Signature, parameterNames);
163 if ((mw.Modifiers &
Modifiers.VarArgs) != 0 && pbs.Length > 0)
166 AddXmlMapParameterAttributes(method,
Name, mw.Name, mw.Signature,
ref pbs);
176 if (mapxml !=
null && mapxml.TryGetValue(
Name, out var clazz) && clazz.Fields !=
null)
178 foreach (var field
in clazz.Fields)
182 foreach (var fw
in fields)
184 if (fw.Name == field.Name && fw.Signature == field.Sig)
200 if (prologue !=
null)
204 if (mapxml !=
null && mapxml.TryGetValue(
new MethodKey(f.Name, m.Name, m.Signature), out var opcodes))
213 void PublishAttributes(TypeBuilder typeBuilder, Class clazz)
215 foreach (var attr
in clazz.Attributes)
225 static bool CheckPropertyArgs(Type[] args1, Type[] args2)
227 if (args1.Length == args2.Length)
229 for (
int i = 0; i < args1.Length; i++)
230 if (args1[i] != args2[i])
239 static MethodAttributes GetPropertyMethodAttributes(
RuntimeJavaMethod mw,
bool final)
241 var attribs = MethodAttributes.HideBySig;
244 attribs |= MethodAttributes.Static;
252 attribs |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride;
254 attribs |= MethodAttributes.Final;
259 attribs |= MethodAttributes.Public;
260 else if (mw.IsProtected)
261 attribs |= MethodAttributes.FamORAssem;
262 else if (mw.IsPrivate)
263 attribs |= MethodAttributes.Private;
265 attribs |= MethodAttributes.Assembly;
270 private void PublishProperties(TypeBuilder typeBuilder, Class clazz)
272 foreach (var prop
in clazz.Properties)
274 var typeWrapper = ClassLoader.RetTypeWrapperFromSig(prop.Sig,
LoadMode.Link);
275 var propargs = ClassLoader.ArgJavaTypeListFromSig(prop.Sig,
LoadMode.Link);
276 Type[] indexer =
new Type[propargs.Length];
277 for (
int i = 0; i < propargs.Length; i++)
279 indexer[i] = propargs[i].TypeAsSignatureType;
281 PropertyBuilder propbuilder = typeBuilder.DefineProperty(prop.Name, PropertyAttributes.None, typeWrapper.TypeAsSignatureType, indexer);
283 if (prop.Attributes !=
null)
293 if (prop.Getter !=
null)
295 getter = GetMethod(prop.Getter.Name, prop.Getter.Sig,
true);
298 Console.Error.WriteLine(
"Warning: getter not found for {0}::{1}", clazz.Name, prop.Name);
302 if (prop.Setter !=
null)
304 setter = GetMethod(prop.Setter.Name, prop.Setter.Sig,
true);
306 Console.Error.WriteLine(
"Warning: setter not found for {0}::{1}", clazz.Name, prop.Name);
309 var
final = (getter !=
null && getter.IsFinal) || (setter !=
null && setter.IsFinal);
314 if (!CheckPropertyArgs(mw.GetParametersForDefineMethod(), indexer) || mw.ReturnType != typeWrapper)
316 Console.Error.WriteLine(
"Warning: ignoring invalid property getter for {0}::{1}", clazz.Name, prop.Name);
320 var mb = mw.GetMethod() as MethodBuilder;
321 if (mb ==
null || mb.DeclaringType != typeBuilder || (!mb.IsFinal &&
final))
323 mb = typeBuilder.DefineMethod(
"get_" + prop.Name, GetPropertyMethodAttributes(mw,
final), typeWrapper.TypeAsSignatureType, indexer);
328 for (
int i = 0; i < indexer.Length; i++)
336 ilgen.Emit(OpCodes.Ldarg_0);
337 for (
int i = 0; i < indexer.Length; i++)
338 ilgen.EmitLdarg(i + 1);
339 mw.EmitCallvirt(ilgen);
341 ilgen.Emit(OpCodes.Ret);
344 propbuilder.SetGetMethod(mb);
350 var args =
ArrayUtil.Concat(indexer, typeWrapper.TypeAsSignatureType);
351 if (!CheckPropertyArgs(args, mw.GetParametersForDefineMethod()))
353 Console.Error.WriteLine(
"Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name);
357 var mb = mw.GetMethod() as MethodBuilder;
358 if (mb ==
null || mb.DeclaringType != typeBuilder || (!mb.IsFinal &&
final))
360 mb = typeBuilder.DefineMethod(
"set_" + prop.Name, GetPropertyMethodAttributes(mw,
final), mw.ReturnTypeForDefineMethod, args);
365 for (
int i = 0; i <= indexer.Length; i++)
371 ilgen.Emit(OpCodes.Ldarg_0);
372 for (
int i = 0; i <= indexer.Length; i++)
373 ilgen.EmitLdarg(i + 1);
374 mw.EmitCallvirt(ilgen);
376 ilgen.Emit(OpCodes.Ret);
380 propbuilder.SetSetMethod(mb);
386 private static void MapModifiers(
MapModifiers mapmods,
bool isConstructor, out
bool setmodifiers,
ref MethodAttributes attribs,
bool isNewSlot)
388 setmodifiers =
false;
392 attribs |= MethodAttributes.Public;
394 else if ((modifiers &
Modifiers.Protected) != 0)
396 attribs |= MethodAttributes.FamORAssem;
398 else if ((modifiers &
Modifiers.Private) != 0)
400 attribs |= MethodAttributes.Private;
404 attribs |= MethodAttributes.Assembly;
409 attribs |= MethodAttributes.Static;
415 else if (!isConstructor)
418 if ((modifiers &
Modifiers.Final) != 0 && (attribs & MethodAttributes.NewSlot) != 0 && (attribs & MethodAttributes.Virtual) == 0)
421 attribs &= ~MethodAttributes.NewSlot;
423 else if (((modifiers & (
Modifiers.Public |
Modifiers.Final)) ==
Modifiers.Final && isNewSlot && (attribs & MethodAttributes.Virtual) == 0))
429 if ((modifiers &
Modifiers.Private) == 0)
431 attribs |= MethodAttributes.Virtual;
435 attribs |= MethodAttributes.Final;
437 else if ((modifiers &
Modifiers.Abstract) != 0)
439 attribs |= MethodAttributes.Abstract;
444 if ((modifiers &
Modifiers.Synchronized) != 0)
446 throw new NotImplementedException();
450 private void MapSignature(
string sig, out Type returnType, out Type[] parameterTypes)
452 returnType = ClassLoader.RetTypeWrapperFromSig(sig,
LoadMode.Link).TypeAsSignatureType;
453 var parameterTypeWrappers = ClassLoader.ArgJavaTypeListFromSig(sig,
LoadMode.Link);
454 parameterTypes =
new Type[parameterTypeWrappers.Length];
455 for (
int i = 0; i < parameterTypeWrappers.Length; i++)
457 parameterTypes[i] = parameterTypeWrappers[i].TypeAsSignatureType;
466 if (mapxml.TryGetValue(classFile.Name, out var clazz))
468 if (clazz.Attributes !=
null)
469 PublishAttributes(typeBuilder, clazz);
471 if (clazz.Properties !=
null)
472 PublishProperties(typeBuilder, clazz);
474 if (clazz.Fields !=
null)
476 foreach (var field
in clazz.Fields)
478 if (field.Attributes !=
null)
480 foreach (var fw
in fields)
482 if (fw.Name == field.Name && fw.Signature == field.Sig)
484 var fb = fw.GetField() as FieldBuilder;
486 foreach (var attr
in field.Attributes)
493 if (clazz.Constructors !=
null)
496 foreach (var constructor
in clazz.Constructors)
501 if (constructor.Body ==
null)
503 Console.Error.WriteLine(
"Error: Constructor {0}.<init>{1} in xml remap file doesn't have a body.", clazz.Name, constructor.Sig);
507 MethodAttributes attribs = 0;
508 MapModifiers(constructor.Modifiers,
true, out var setmodifiers,
ref attribs,
false);
509 MapSignature(constructor.Sig, out var returnType, out var parameterTypes);
510 var cb =
ReflectUtil.DefineConstructor(typeBuilder, attribs, parameterTypes);
518 if (constructor.Attributes !=
null)
519 foreach (var attr
in constructor.Attributes)
524 foreach (var constructor
in clazz.Constructors)
526 if (constructor.Attributes !=
null)
528 foreach (var mw
in methods)
530 if (mw.Name ==
"<init>" && mw.Signature == constructor.Sig)
532 var mb = mw.GetMethod() as MethodBuilder;
534 foreach (var attr
in constructor.Attributes)
541 if (clazz.Methods !=
null)
544 foreach (var method
in clazz.Methods)
547 if (GetMethod(method.Name, method.Sig,
false) ==
null)
549 var attribs = method.MethodAttributes;
550 MapModifiers(method.Modifiers,
false, out var setmodifiers,
ref attribs, BaseTypeWrapper ==
null || BaseTypeWrapper.GetMethod(method.Name, method.Sig,
true) ==
null);
551 if (method.Body ==
null && (attribs & MethodAttributes.Abstract) == 0)
553 Console.Error.WriteLine(
"Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig);
557 MapSignature(method.Sig, out var returnType, out var parameterTypes);
558 var mb = typeBuilder.DefineMethod(method.Name, attribs, returnType, parameterTypes);
564 if (method.Override !=
null)
566 var mw = ClassLoader.LoadClassByName(method.Override.Class).GetMethod(method.Override.Name, method.Sig,
true);
568 typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
572 if (method.Body !=
null)
579 if (method.Attributes !=
null)
580 foreach (var attr
in method.Attributes)
587 if (method.Attributes !=
null)
589 foreach (var mw
in methods)
591 if (mw.Name == method.Name && mw.Signature == method.Sig)
593 MethodBuilder mb = mw.GetMethod() as MethodBuilder;
606 if (clazz.Interfaces !=
null)
608 foreach (Implements iface
in clazz.Interfaces)
610 var tw = ClassLoader.LoadClassByName(iface.Class);
613 typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType);
614 if (iface.Methods !=
null)
616 foreach (Method m
in iface.Methods)
618 var mw = tw.GetMethod(m.Name, m.Sig,
false);
620 throw new InvalidOperationException(
"Method " + m.Name + m.Sig +
" not found in interface " + tw.Name);
623 MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(
this, typeBuilder, tw.Name +
"/" + m.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.CheckAccessOnOverride);
625 typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
639 if (typeBuilderGhostInterface !=
null && mw.IsVirtual)
641 var helper = mw.GetDefineMethodHelper();
642 var stub = helper.DefineMethod(
this, typeBuilder, name, MethodAttributes.Public);
644 return helper.DefineMethod(
this, typeBuilderGhostInterface, name, attribs);
652 if (typeBuilderGhostInterface !=
null)
655 for (
int i = 0; i < methods.Length; i++)
660 var args = methods[i].GetParameters();
661 var stub = gmw.GetGhostMethod();
662 AddParameterMetadata(stub, methods[i]);
665 var end = ilgen.DefineLabel();
666 var implementers =
classLoader.GetGhostImplementers(
this);
667 ilgen.Emit(OpCodes.Ldarg_0);
668 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
669 ilgen.Emit(OpCodes.Dup);
670 ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface);
671 var label = ilgen.DefineLabel();
672 ilgen.EmitBrfalse(label);
673 ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface);
674 for (
int k = 0; k < args.Length; k++)
676 ilgen.EmitLdarg(k + 1);
678 ilgen.Emit(OpCodes.Callvirt, (MethodInfo)methods[i].GetMethod());
680 ilgen.MarkLabel(label);
681 for (
int j = 0; j < implementers.Length; j++)
683 ilgen.Emit(OpCodes.Dup);
684 ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD);
685 label = ilgen.DefineLabel();
686 ilgen.EmitBrfalse(label);
687 var mw = implementers[j].GetMethod(methods[i].
Name, methods[i].
Signature,
true);
690 if (methods[i].IsAbstract)
696 ilgen.Emit(OpCodes.Pop);
697 ilgen.Emit(OpCodes.Ldarg_0);
698 for (
int k = 0; k < args.Length; k++)
700 ilgen.EmitLdarg(k + 1);
706 ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD);
707 for (
int k = 0; k < args.Length; k++)
709 ilgen.EmitLdarg(k + 1);
711 mw.EmitCallvirt(ilgen);
714 ilgen.MarkLabel(label);
717 ilgen.EmitNullCheck();
718 ilgen.EmitThrow(
"java.lang.IncompatibleClassChangeError",
Name);
719 ilgen.MarkLabel(end);
720 ilgen.Emit(OpCodes.Ret);
732 var implementers =
classLoader.GetGhostImplementers(
this);
733 for (
int i = 0; i < implementers.Length; i++)
735 mb = typeBuilder.DefineMethod(
"op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, TypeAsSignatureType,
new Type[] { implementers[i].TypeAsSignatureType });
738 local = ilgen.DeclareLocal(TypeAsSignatureType);
739 ilgen.Emit(OpCodes.Ldloca, local);
740 ilgen.Emit(OpCodes.Ldarg_0);
741 ilgen.Emit(OpCodes.Stfld, ghostRefField);
742 ilgen.Emit(OpCodes.Ldloca, local);
743 ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
744 ilgen.Emit(OpCodes.Ret);
748 mb = ghostIsInstanceMethod;
752 for (
int i = 0; i < implementers.Length; i++)
754 ilgen.Emit(OpCodes.Ldarg_0);
755 ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD);
757 ilgen.EmitBrfalse(label);
758 ilgen.Emit(OpCodes.Ldc_I4_1);
760 ilgen.MarkLabel(label);
762 ilgen.Emit(OpCodes.Ldarg_0);
763 ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface);
764 ilgen.Emit(OpCodes.Ldnull);
765 ilgen.Emit(OpCodes.Cgt_Un);
766 ilgen.MarkLabel(end);
767 ilgen.Emit(OpCodes.Ret);
770 mb = ghostIsInstanceArrayMethod;
773 var localType = ilgen.DeclareLocal(Context.
Types.
Type);
774 var localRank = ilgen.DeclareLocal(Context.
Types.
Int32);
775 ilgen.Emit(OpCodes.Ldarg_0);
776 var skip = ilgen.DefineLabel();
777 ilgen.EmitBrtrue(skip);
778 ilgen.Emit(OpCodes.Ldc_I4_0);
779 ilgen.Emit(OpCodes.Ret);
780 ilgen.MarkLabel(skip);
781 ilgen.Emit(OpCodes.Ldarg_0);
783 ilgen.Emit(OpCodes.Stloc, localType);
784 ilgen.Emit(OpCodes.Ldarg_1);
785 ilgen.Emit(OpCodes.Stloc, localRank);
786 skip = ilgen.DefineLabel();
788 var iter = ilgen.DefineLabel();
789 ilgen.MarkLabel(iter);
790 ilgen.Emit(OpCodes.Ldloc, localType);
791 ilgen.Emit(OpCodes.Callvirt, Context.
Types.
Type.GetMethod(
"GetElementType"));
792 ilgen.Emit(OpCodes.Stloc, localType);
793 ilgen.Emit(OpCodes.Ldloc, localRank);
794 ilgen.Emit(OpCodes.Ldc_I4_1);
795 ilgen.Emit(OpCodes.Sub);
796 ilgen.Emit(OpCodes.Stloc, localRank);
797 ilgen.Emit(OpCodes.Ldloc, localRank);
798 var typecheck = ilgen.DefineLabel();
799 ilgen.EmitBrfalse(typecheck);
800 ilgen.MarkLabel(skip);
801 ilgen.Emit(OpCodes.Ldloc, localType);
802 ilgen.Emit(OpCodes.Callvirt, Context.
Types.
Type.GetMethod(
"get_IsArray"));
803 ilgen.EmitBrtrue(iter);
804 ilgen.Emit(OpCodes.Ldc_I4_0);
805 ilgen.Emit(OpCodes.Ret);
806 ilgen.MarkLabel(typecheck);
807 for (
int i = 0; i < implementers.Length; i++)
809 ilgen.Emit(OpCodes.Ldtoken, implementers[i].TypeAsTBD);
810 ilgen.Emit(OpCodes.Call, Context.
Types.
Type.GetMethod(
"GetTypeFromHandle"));
811 ilgen.Emit(OpCodes.Ldloc, localType);
812 ilgen.Emit(OpCodes.Callvirt, Context.
Types.
Type.GetMethod(
"IsAssignableFrom"));
813 var label = ilgen.DefineLabel();
814 ilgen.EmitBrfalse(label);
815 ilgen.Emit(OpCodes.Ldc_I4_1);
816 ilgen.Emit(OpCodes.Ret);
817 ilgen.MarkLabel(label);
819 ilgen.Emit(OpCodes.Ldtoken, typeBuilderGhostInterface);
820 ilgen.Emit(OpCodes.Call, Context.
Types.
Type.GetMethod(
"GetTypeFromHandle"));
821 ilgen.Emit(OpCodes.Ldloc, localType);
822 ilgen.Emit(OpCodes.Callvirt, Context.
Types.
Type.GetMethod(
"IsAssignableFrom"));
823 skip = ilgen.DefineLabel();
824 ilgen.EmitBrfalse(skip);
825 ilgen.Emit(OpCodes.Ldc_I4_1);
826 ilgen.Emit(OpCodes.Ret);
827 ilgen.MarkLabel(skip);
828 ilgen.Emit(OpCodes.Ldarg_0);
829 ilgen.Emit(OpCodes.Ldtoken, typeBuilder);
830 ilgen.Emit(OpCodes.Ldarg_1);
831 ilgen.Emit(OpCodes.Call, Context.
Resolver.ResolveRuntimeType(typeof(
IKVM.
Runtime.
GhostTag).FullName).AsReflection().GetMethod(
"IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static));
832 ilgen.Emit(OpCodes.Ret);
836 mb = ghostCastMethod;
839 end = ilgen.DefineLabel();
840 for (
int i = 0; i < implementers.Length; i++)
842 ilgen.Emit(OpCodes.Ldarg_0);
843 ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD);
844 ilgen.EmitBrtrue(end);
846 ilgen.Emit(OpCodes.Ldarg_0);
847 ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface);
848 ilgen.Emit(OpCodes.Pop);
849 ilgen.MarkLabel(end);
850 local = ilgen.DeclareLocal(TypeAsSignatureType);
851 ilgen.Emit(OpCodes.Ldloca, local);
852 ilgen.Emit(OpCodes.Ldarg_0);
853 ilgen.Emit(OpCodes.Stfld, ghostRefField);
854 ilgen.Emit(OpCodes.Ldloca, local);
855 ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
856 ilgen.Emit(OpCodes.Ret);
859 mb = typeBuilder.DefineMethod(
"ToObject", MethodAttributes.HideBySig | MethodAttributes.Public, Context.
Types.
Object, Type.EmptyTypes);
862 ilgen.Emit(OpCodes.Ldarg_0);
863 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
864 ilgen.Emit(OpCodes.Ret);
871 mb = ghostCastArrayMethod;
874 end = ilgen.DefineLabel();
875 ilgen.Emit(OpCodes.Ldarg_0);
876 ilgen.EmitBrfalse(end);
877 ilgen.Emit(OpCodes.Ldarg_0);
878 ilgen.Emit(OpCodes.Ldarg_1);
879 ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod);
880 ilgen.EmitBrtrue(end);
881 ilgen.Emit(OpCodes.Ldarg_0);
882 ilgen.Emit(OpCodes.Ldtoken, typeBuilder);
883 ilgen.Emit(OpCodes.Ldarg_1);
884 ilgen.Emit(OpCodes.Call, Context.
Resolver.ResolveRuntimeType(typeof(
IKVM.
Runtime.
GhostTag).FullName).AsReflection().GetMethod(
"ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static));
885 ilgen.MarkLabel(end);
886 ilgen.Emit(OpCodes.Ret);
890 mb = typeBuilder.DefineMethod(
"Equals", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.
Types.
Boolean,
new Type[] { Context.Types.Object });
893 ilgen.Emit(OpCodes.Ldarg_0);
894 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
895 ilgen.Emit(OpCodes.Ldarg_1);
896 ilgen.Emit(OpCodes.Ceq);
897 ilgen.Emit(OpCodes.Ret);
901 mb = typeBuilder.DefineMethod(
"GetHashCode", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Context.
Types.
Int32, Type.EmptyTypes);
904 ilgen.Emit(OpCodes.Ldarg_0);
905 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
906 ilgen.Emit(OpCodes.Callvirt, Context.
Types.
Object.GetMethod(
"GetHashCode"));
907 ilgen.Emit(OpCodes.Ret);
911 mb = typeBuilder.DefineMethod(
"op_Equality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.
Types.
Boolean,
new Type[] { typeBuilder, typeBuilder });
915 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
917 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
918 ilgen.Emit(OpCodes.Ceq);
919 ilgen.Emit(OpCodes.Ret);
923 mb = typeBuilder.DefineMethod(
"op_Inequality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Context.
Types.
Boolean,
new Type[] { typeBuilder, typeBuilder });
927 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
929 ilgen.Emit(OpCodes.Ldfld, ghostRefField);
930 ilgen.Emit(OpCodes.Ceq);
931 ilgen.Emit(OpCodes.Ldc_I4_0);
932 ilgen.Emit(OpCodes.Ceq);
933 ilgen.Emit(OpCodes.Ret);
941 typeBuilderGhostInterface?.CreateType();
944 protected override TypeBuilder
DefineGhostType(
string mangledTypeName, TypeAttributes typeAttribs)
946 typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract);
947 typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed;
948 TypeBuilder typeBuilder =
classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, Context.
Types.
ValueType);
951 ghostRefField = typeBuilder.DefineField(
"__<ref>", Context.
Types.
Object, FieldAttributes.Public | FieldAttributes.SpecialName);
952 typeBuilderGhostInterface = typeBuilder.DefineNestedType(
"__Interface", TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.NestedPublic);
954 ghostIsInstanceMethod = typeBuilder.DefineMethod(
"IsInstance", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.
Types.
Boolean,
new Type[] { Context.Types.Object });
955 ghostIsInstanceMethod.DefineParameter(1, ParameterAttributes.None,
"obj");
956 ghostIsInstanceArrayMethod = typeBuilder.DefineMethod(
"IsInstanceArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.
Types.
Boolean,
new Type[] { Context.Types.Object, Context.Types.Int32 });
957 ghostIsInstanceArrayMethod.DefineParameter(1, ParameterAttributes.None,
"obj");
958 ghostIsInstanceArrayMethod.DefineParameter(2, ParameterAttributes.None,
"rank");
959 ghostCastMethod = typeBuilder.DefineMethod(
"Cast", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeBuilder,
new Type[] { Context.Types.Object });
960 ghostCastMethod.DefineParameter(1, ParameterAttributes.None,
"obj");
961 ghostCastArrayMethod = typeBuilder.DefineMethod(
"CastArray", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, Context.
Types.
Void,
new Type[] { Context.Types.Object, Context.Types.Int32 });
962 ghostCastArrayMethod.DefineParameter(1, ParameterAttributes.None,
"obj");
963 ghostCastArrayMethod.DefineParameter(2, ParameterAttributes.None,
"rank");
967 internal override FieldInfo GhostRefField => ghostRefField;
969 internal override void EmitCheckcast(
CodeEmitter ilgen)
973 ilgen.Emit(OpCodes.Dup);
974 ilgen.Emit(OpCodes.Call, ghostCastMethod);
975 ilgen.Emit(OpCodes.Pop);
977 else if (IsGhostArray)
979 ilgen.Emit(OpCodes.Dup);
980 RuntimeJavaType tw =
this;
985 tw = tw.ElementTypeWrapper;
987 ilgen.EmitLdc_I4(rank);
988 ilgen.Emit(OpCodes.Call, ghostCastArrayMethod);
993 base.EmitCheckcast(ilgen);
997 internal override void EmitInstanceOf(
CodeEmitter ilgen)
1001 ilgen.Emit(OpCodes.Call, ghostIsInstanceMethod);
1003 else if (IsGhostArray)
1005 ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod);
1009 base.EmitInstanceOf(ilgen);
1013 internal void SetAnnotation(
Annotation annotation)
1015 this.annotation = annotation;
1020 internal void SetEnumType(Type enumType)
1022 this.enumType = enumType;
1025 internal override Type EnumType => enumType;
1056 protected override void DoLinkMethod()
1065 for (
int i = 0; i < code.Instructions.Length; i++)
1066 code.Instructions[i].Generate(context, ilgen);
1069 internal override void EmitCall(
CodeEmitter ilgen)
1074 internal override void EmitCallvirt(
CodeEmitter ilgen)
1079 internal override void EmitNewobj(
CodeEmitter ilgen)
1088 var replacedMethods = ((
ImportClassLoader)ClassLoader).GetReplacedMethodsFor(mw);
1089 var baseReplacedMethodWrappers = base.GetReplacedMethodsFor(mw);
1090 if (replacedMethods !=
null || baseReplacedMethodWrappers !=
null || this.replacedMethods !=
null)
1092 var list =
new List<RuntimeJavaMethod>();
1094 if (replacedMethods !=
null)
1095 for (
int i = 0; i < replacedMethods.Length; i++)
1096 list.Add(
new ReplacedMethodWrapper(ClassLoader.LoadClassByName(replacedMethods[i].Class), replacedMethods[i].Name, replacedMethods[i].Sig, replacedMethods[i].Code));
1098 if (baseReplacedMethodWrappers !=
null)
1099 list.AddRange(baseReplacedMethodWrappers);
1101 if (this.replacedMethods !=
null)
1102 list.AddRange(this.replacedMethods);
1104 return list.ToArray();
1110 internal override bool IsFastClassLiteralSafe
1112 get {
return true; }
1117 if (replacedMethods !=
null)
1118 foreach (var r
in replacedMethods)
1119 if (mw.DeclaringType == r.DeclaringType && mw.Name == r.Name && mw.Signature == r.Signature)