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;
        }
コード例 #2
0
        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);
        }
コード例 #3
0
 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);
 }
コード例 #4
0
        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;
        }
コード例 #5
0
        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);
        }