public static void MakeSetter(FieldDefinition field, FieldRewriteContext fieldContext, PropertyDefinition property) { var imports = AssemblyKnownImports.For(property); var setter = new MethodDefinition("set_" + property.Name, Field2MethodAttrs(field.Attributes) | MethodAttributes.SpecialName | MethodAttributes.HideBySig, imports.Void); setter.Parameters.Add(new ParameterDefinition(property.PropertyType)); property.DeclaringType.Methods.Add(setter); var setterBody = setter.Body.GetILProcessor(); if (field.IsStatic) { setterBody.Emit(OpCodes.Ldsfld, fieldContext.PointerField); setterBody.EmitObjectToPointer(field.FieldType, property.PropertyType, fieldContext.DeclaringType, 0, false, true, true, out _); setterBody.Emit(OpCodes.Call, imports.FieldStaticSet); } else { setterBody.EmitObjectToPointer(fieldContext.DeclaringType.OriginalType, fieldContext.DeclaringType.NewType, fieldContext.DeclaringType, 0, false, false, false, out _); setterBody.Emit(OpCodes.Ldsfld, fieldContext.PointerField); setterBody.Emit(OpCodes.Call, imports.FieldGetOffset); setterBody.Emit(OpCodes.Add); setterBody.EmitObjectStore(field.FieldType, property.PropertyType, fieldContext.DeclaringType, 1); } setterBody.Emit(OpCodes.Ret); property.SetMethod = setter; }
public static MethodDefinition MakeGetter(FieldDefinition field, FieldReference fieldInfoPointer, PropertyDefinition property) { var imports = AssemblyKnownImports.For(property); var getter = new MethodDefinition("get_" + property.Name, Field2MethodAttrs(field.Attributes) | MethodAttributes.SpecialName | MethodAttributes.HideBySig, property.PropertyType); var propertyTypeIsValueType = field.FieldType.IsValueType || field.FieldType.IsPrimitive; var local0 = new VariableDefinition(propertyTypeIsValueType ? property.PropertyType : imports.IntPtr); getter.Body.Variables.Add(local0); var getterBody = getter.Body.GetILProcessor(); if (field.IsStatic) { getterBody.Emit(OpCodes.Ldsfld, fieldInfoPointer); getterBody.Emit(OpCodes.Ldloca_S, local0); getterBody.Emit(OpCodes.Conv_U); getterBody.Emit(OpCodes.Call, imports.FieldStaticGet); } else { getterBody.Emit(OpCodes.Ldarg_0); getterBody.Emit(OpCodes.Call, imports.Il2CppObjectBaseToPointerNotNull); getterBody.Emit(OpCodes.Ldsfld, fieldInfoPointer); getterBody.Emit(OpCodes.Call, imports.FieldGetOffset); getterBody.Emit(OpCodes.Add); getterBody.Emit(OpCodes.Ldobj, local0.VariableType); getterBody.Emit(OpCodes.Stloc_0); } getterBody.Emit(OpCodes.Ldloc_0); if (field.FieldType.FullName == "System.String") { getterBody.Emit(OpCodes.Call, imports.StringFromNative); } else if (!propertyTypeIsValueType) { var createRealObject = getterBody.Create(OpCodes.Newobj, new MethodReference(".ctor", imports.Void, property.PropertyType) { Parameters = { new ParameterDefinition(imports.IntPtr) }, HasThis = true }); getterBody.Emit(OpCodes.Dup); getterBody.Emit(OpCodes.Brtrue_S, createRealObject); getterBody.Emit(OpCodes.Pop); getterBody.Emit(OpCodes.Ldnull); getterBody.Emit(OpCodes.Ret); getterBody.Append(createRealObject); } getterBody.Emit(OpCodes.Ret); property.GetMethod = getter; return(getter); }
public static void EmitUpdateRef(this ILProcessor body, ParameterDefinition newMethodParameter, int argIndex, VariableDefinition paramVariable, AssemblyKnownImports imports) { body.Emit(OpCodes.Ldarg, argIndex); body.Emit(OpCodes.Ldloc, paramVariable); if (newMethodParameter.ParameterType.GetElementType().FullName == "System.String") { body.Emit(OpCodes.Call, imports.StringFromNative); } else { body.Emit(OpCodes.Newobj, new MethodReference(".ctor", imports.Void, newMethodParameter.ParameterType.GetElementType()) { HasThis = true, Parameters = { new ParameterDefinition(imports.IntPtr) } }); } body.Emit(OpCodes.Stind_Ref); }
public static void MakeGetter(FieldDefinition field, FieldRewriteContext fieldContext, PropertyDefinition property, AssemblyKnownImports imports) { var getter = new MethodDefinition("get_" + property.Name, Field2MethodAttrs(field.Attributes) | MethodAttributes.SpecialName | MethodAttributes.HideBySig, property.PropertyType); var getterBody = getter.Body.GetILProcessor(); property.DeclaringType.Methods.Add(getter); if (field.IsStatic) { var local0 = new VariableDefinition(property.PropertyType.IsValueType ? property.PropertyType : imports.IntPtr); getter.Body.Variables.Add(local0); bool localIsPointer = false; if (field.FieldType.IsValueType && !property.PropertyType.IsValueType) { var pointerStore = new GenericInstanceType(imports.Il2CppClassPointerStore); pointerStore.GenericArguments.Add(property.PropertyType); var pointerStoreType = property.DeclaringType.Module.ImportReference(pointerStore); getterBody.Emit(OpCodes.Ldsfld, new FieldReference(nameof(Il2CppClassPointerStore <int> .NativeClassPtr), imports.IntPtr, pointerStoreType)); getterBody.Emit(OpCodes.Ldc_I4, 0); getterBody.Emit(OpCodes.Conv_U); getterBody.Emit(OpCodes.Call, imports.ValueSizeGet); getterBody.Emit(OpCodes.Conv_U); getterBody.Emit(OpCodes.Localloc); getterBody.Emit(OpCodes.Stloc, local0); localIsPointer = true; } getterBody.Emit(OpCodes.Ldsfld, fieldContext.PointerField); if (localIsPointer) { getterBody.Emit(OpCodes.Ldloc, local0); } else { getterBody.Emit(OpCodes.Ldloca_S, local0); } getterBody.Emit(OpCodes.Conv_U); getterBody.Emit(OpCodes.Call, imports.FieldStaticGet); if (property.PropertyType.IsValueType) { getterBody.Emit(OpCodes.Ldloc, local0); getterBody.Emit(OpCodes.Ret); property.GetMethod = getter; return; } } else { var local0 = new VariableDefinition(imports.IntPtr); getter.Body.Variables.Add(local0); getterBody.EmitObjectToPointer(fieldContext.DeclaringType.OriginalType, fieldContext.DeclaringType.NewType, fieldContext.DeclaringType, 0, false, false, false, out _); getterBody.Emit(OpCodes.Ldsfld, fieldContext.PointerField); getterBody.Emit(OpCodes.Call, imports.FieldGetOffset); getterBody.Emit(OpCodes.Add); getterBody.Emit(OpCodes.Stloc_0); } getterBody.EmitPointerToObject(fieldContext.OriginalField.FieldType, property.PropertyType, fieldContext.DeclaringType, getterBody.Create(OpCodes.Ldloc_0), !field.IsStatic, false); getterBody.Emit(OpCodes.Ret); property.GetMethod = getter; }
public static MethodDefinition MakeSetter(FieldDefinition field, FieldReference fieldDefinition, PropertyDefinition property) { var imports = AssemblyKnownImports.For(property); var propertyTypeIsValueType = field.FieldType.IsValueType || field.FieldType.IsPrimitive; var actualFieldType = propertyTypeIsValueType ? property.PropertyType : imports.IntPtr; var setter = new MethodDefinition("set_" + property.Name, Field2MethodAttrs(field.Attributes) | MethodAttributes.SpecialName | MethodAttributes.HideBySig, imports.Void); setter.Parameters.Add(new ParameterDefinition(property.PropertyType)); var setterBody = setter.Body.GetILProcessor(); if (field.IsStatic) { setterBody.Emit(OpCodes.Ldsfld, fieldDefinition); if (field.FieldType.FullName == "System.String") { setterBody.Emit(OpCodes.Ldarg_0); setterBody.Emit(OpCodes.Call, imports.StringToNative); } else if (!propertyTypeIsValueType) { setterBody.Emit(OpCodes.Ldarg_0); setterBody.Emit(OpCodes.Call, imports.Il2CppObjectBaseToPointer); } else { setterBody.Emit(OpCodes.Ldarga_S, (byte)0); setterBody.Emit(OpCodes.Conv_U); } setterBody.Emit(OpCodes.Call, imports.FieldStaticSet); } else { setterBody.Emit(OpCodes.Ldarg_0); setterBody.Emit(OpCodes.Call, imports.Il2CppObjectBaseToPointerNotNull); setterBody.Emit(OpCodes.Ldsfld, fieldDefinition); setterBody.Emit(OpCodes.Call, imports.FieldGetOffset); setterBody.Emit(OpCodes.Add); if (field.FieldType.FullName == "System.String") { setterBody.Emit(OpCodes.Ldarg_1); setterBody.Emit(OpCodes.Call, imports.StringToNative); } else if (!propertyTypeIsValueType) { setterBody.Emit(OpCodes.Ldarg_1); setterBody.Emit(OpCodes.Call, imports.Il2CppObjectBaseToPointer); } else { setterBody.Emit(OpCodes.Ldarg_1); } setterBody.Emit(OpCodes.Stobj, actualFieldType); } setterBody.Emit(OpCodes.Ret); property.SetMethod = setter; return(setter); }