private static void AddReadResolve(DynamicTypeWrapper wrapper, TypeBuilder tb)
{
MethodWrapper mw = wrapper.GetMethodWrapper("readResolve", "()Ljava.lang.Object;", false);
if (mw != null && !wrapper.IsSubTypeOf(iobjectreference))
{
tb.AddInterfaceImplementation(JVM.Import(typeof(IObjectReference)));
MethodBuilder getRealObject = tb.DefineMethod("IObjectReference.GetRealObject", MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final,
Types.Object, new Type[] { JVM.Import(typeof(StreamingContext)) });
getRealObject.SetCustomAttribute(securityCriticalAttribute);
AttributeHelper.HideFromJava(getRealObject);
tb.DefineMethodOverride(getRealObject, JVM.Import(typeof(IObjectReference)).GetMethod("GetRealObject"));
CodeEmitter ilgen = CodeEmitter.Create(getRealObject);
mw.Link();
if (!wrapper.IsFinal)
{
// readResolve is only applicable if it exists on the actual type of the object, so if we're a subclass don't call it
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod);
ilgen.Emit(OpCodes.Ldtoken, wrapper.TypeAsBaseType);
ilgen.Emit(OpCodes.Call, Compiler.getTypeFromHandleMethod);
CodeEmitterLabel label = ilgen.DefineLabel();
ilgen.Emit(OpCodes.Beq_S, label);
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Ret);
ilgen.MarkLabel(label);
}
ilgen.Emit(OpCodes.Ldarg_0);
mw.EmitCall(ilgen);
ilgen.Emit(OpCodes.Ret);
ilgen.DoEmit();
}
}