/// <summary>
        /// Gets the marshaler methods for a marshaler which has to be instantiated be used (the collection marshalers)
        /// </summary>
        private bool GetInstancedMarshalerMethods(ManagedUnrealPropertyInfo propertyInfo, ManagedUnrealMarshalerType marshalerType,
                                                  out System.Reflection.ConstructorInfo ctor,
                                                  out System.Reflection.MethodInfo fromNativeMethod,
                                                  out System.Reflection.MethodInfo toNativeMethod)
        {
            Type collectionMarshalerType = ManagedUnrealTypeInfo.GetMarshalerType(marshalerType, propertyInfo);

            // Find the constructor for the marshaler
            ctor = null;
            foreach (System.Reflection.ConstructorInfo ctorInfo in collectionMarshalerType.GetConstructors())
            {
                System.Reflection.ParameterInfo[] ctorParams = ctorInfo.GetParameters();
                if (ctorParams.Length > 2 && ctorParams[0].ParameterType == typeof(int) && ctorParams[1].ParameterType == typeof(UFieldAddress))
                {
                    ctor = ctorInfo;
                    break;
                }
            }

            fromNativeMethod = GetInstancedMarshalerMethod(collectionMarshalerType, true);
            toNativeMethod   = GetInstancedMarshalerMethod(collectionMarshalerType, false);

            bool success = ctor != null && fromNativeMethod != null && toNativeMethod != null;

            if (!success)
            {
                throw new RewriteException(propertyInfo.Path, "Failed to get marshaler methods");
            }
            return(success);
        }
示例#2
0
 private void WriteNativeFunctionInvoker(TypeDefinition type, ManagedUnrealTypeInfo typeInfo, ManagedUnrealFunctionInfo functionInfo,
                                         MethodDefinition method, InjectedMembers injectedMembers, bool perInstanceFunctionAddress)
 {
     method.Body = new MethodBody(method);
     WriteNativeFunctionInvokerBody(type, typeInfo, functionInfo, method, injectedMembers, GetParamsFromMethod(type, functionInfo, method),
                                    method.Body.GetILProcessor(), false, perInstanceFunctionAddress);
 }
        private VariableDefinition EmitCreateMarshaler(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField, ManagedUnrealPropertyInfo propertyInfo)
        {
            VariableDefinition marshalerVar = null;

            if (ManagedUnrealTypeInfo.PropertyRequiresMarshalerInstance(propertyInfo))
            {
                TypeReference marshalerType = assembly.MainModule.ImportEx(ManagedUnrealTypeInfo.GetMarshalerType(ManagedUnrealMarshalerType.Copy, propertyInfo));
                marshalerVar = new VariableDefinition(marshalerType);
            }

            if (marshalerVar != null)
            {
                processor.Emit(OpCodes.Ldc_I4_1);
                processor.Emit(OpCodes.Ldsfld, nativePropertyField);

                // New delegate marshaling code, this will use a cached delegate
                EmitCachedMarshalingDelegates(processor, propertyInfo, ManagedUnrealMarshalerType.Copy);

                System.Reflection.ConstructorInfo ctor;
                System.Reflection.MethodInfo      fromNativeMethod;
                System.Reflection.MethodInfo      toNativeMethod;
                GetInstancedMarshalerMethods(propertyInfo, ManagedUnrealMarshalerType.Copy, out ctor, out fromNativeMethod, out toNativeMethod);

                processor.Emit(OpCodes.Newobj, assembly.MainModule.ImportEx(ctor));

                processor.Emit(OpCodes.Stloc, marshalerVar);
            }

            return(marshalerVar);
        }
        private Instruction[] CreateFunctionOutDefaults(ILProcessor processor, ManagedUnrealFunctionInfo functionInfo, MethodDefinition method)
        {
            List <Instruction> instructions = new List <Instruction>();

            // Set out params to the equivalent of default(XXXX)
            for (int i = 0; i < functionInfo.Params.Count; ++i)
            {
                ManagedUnrealPropertyInfo param = functionInfo.Params[i];

                if (param.IsOut)
                {
                    instructions.AddRange(CreateSetDefaultValue(processor, param.Type.TypeCode, method.Parameters[i]));
                }
            }

            // Add a return var and set it to the equivalent of default(XXXX)
            if (functionInfo.ReturnProp != null)
            {
                TypeReference      returnType = assembly.MainModule.ImportEx(ManagedUnrealTypeInfo.GetTypeFromPropertyInfo(functionInfo.ReturnProp));
                VariableDefinition returnVar  = new VariableDefinition(returnType);
                method.Body.Variables.Add(returnVar);

                instructions.AddRange(CreateSetDefaultValue(processor, functionInfo.ReturnProp.Type.TypeCode, returnVar));
                instructions.Add(processor.Create(OpCodes.Ldloc, returnVar));
            }

            return(instructions.ToArray());
        }
示例#5
0
        private void RewriteInterface(TypeDefinition type, ManagedUnrealTypeInfo interfaceInfo)
        {
            InjectedMembers injectedMembers = new InjectedMembers(interfaceInfo);

            Dictionary <string, List <MethodDefinition> > methodsByName = new Dictionary <string, List <MethodDefinition> >();

            foreach (MethodDefinition method in type.Methods)
            {
                List <MethodDefinition> methods;
                if (!methodsByName.TryGetValue(method.Name, out methods))
                {
                    methodsByName.Add(method.Name, methods = new List <MethodDefinition>());
                }
                methods.Add(method);
            }

            foreach (ManagedUnrealFunctionInfo functionInfo in interfaceInfo.Functions)
            {
                List <MethodDefinition> methods;
                methodsByName.TryGetValue(functionInfo.Name, out methods);
                VerifySingleResult(methods, type, "Function " + functionInfo.Name + " (the reflection system doesn't support overloads");

                AddPathAttribute(methods[0], functionInfo);
            }

            TypeDefinition interfaceImplType = CreateDefaultInterfaceImpl(type, interfaceInfo, methodsByName);

            AddPathAttribute(type, interfaceInfo, interfaceImplType);
        }
        private void EmitLoad(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField,
                              ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, VariableDefinition marshalerVar, ParameterDefinition param)
        {
            // This is moving the native buffer into the parameter

            // If the param is "out" or "ref" load the arg and store it afterwards
            // NOTE: Is this a redundant check? Why would we be loading the native buffer into a param if it isn't ref / out?
            //       - Collections were treated as a special case. Look into if it is still required. If not; remove this ref/out check
            //         (or just change it to an assert) and only take the ref/out path.
            bool outOrRef = propertyInfo.IsByRef || propertyInfo.IsOut;

            if (outOrRef)
            {
                System.Diagnostics.Debug.Assert(param.IsOut || param.ParameterType.IsByReference);
                processor.Emit(OpCodes.Ldarg, param);
            }

            EmitLoad(processor, loadBuffer, offsetField, nativePropertyField, typeInfo, propertyInfo, marshalerVar);

            if (outOrRef)
            {
                processor.Append(CreateStRefOutParam(processor, param, propertyInfo.Type.TypeCode));
            }
            else
            {
                // Is this useful for anything? Old code used it when not handling ref/out properly.
                processor.Emit(OpCodes.Starg, param);
            }
        }
示例#7
0
 private void EndSetter(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition setter,
                        FieldDefinition isValidField, ILProcessor processor)
 {
     processor.Emit(OpCodes.Ret);
     InsertPropertyIsValidSafeguard(propertyInfo, setter, false, isValidField, processor);
     InsertObjectDestroyedCheck(typeInfo, processor);
     setter.Body.OptimizeMacros();
 }
示例#8
0
        private void WriteGetterCollection(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition getter,
                                           FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition nativePropertyField, FieldDefinition collectionWrapperField)
        {
            ILProcessor processor = BeginGetter(getter);

            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldfld, collectionWrapperField);

            // Save the position of the branch instruction for later, when we have a reference to its target.
            // (will insert Brtrue_S before this instruction as a null check on the wrapper field)
            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchPosition = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            processor.Emit(OpCodes.Ldc_I4_1);
            processor.Emit(OpCodes.Ldsfld, nativePropertyField);

            // New delegate marshaling code, this will use a cached delegate
            EmitCachedMarshalingDelegates(processor, propertyInfo, ManagedUnrealMarshalerType.Default);

            System.Reflection.ConstructorInfo collectionCtor;
            System.Reflection.MethodInfo      fromNativeMethod;
            System.Reflection.MethodInfo      toNativeMethod;
            GetInstancedMarshalerMethods(propertyInfo, ManagedUnrealMarshalerType.Default, out collectionCtor, out fromNativeMethod, out toNativeMethod);

            int numFromNativeParams = fromNativeMethod.GetParameters().Length;

            // Create an instance of the collection marshaler and store in the member field
            processor.Emit(OpCodes.Newobj, assembly.MainModule.ImportEx(collectionCtor));
            processor.Emit(OpCodes.Stfld, collectionWrapperField);

            // Store the branch destination
            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchTarget = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            processor.Emit(OpCodes.Ldfld, collectionWrapperField);
            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Call, uobjectAddressGetter);
            processor.Emit(OpCodes.Ldsfld, offsetField);
            processor.Emit(OpCodes.Call, intPtrAddMethod);
            if (numFromNativeParams == marshalerFromNativeParamCount)
            {
                // arrayIndex, prop (IntPtr.Zero as prop is already known by the collection marshaler), this
                processor.Emit(OpCodes.Ldc_I4_0);
                processor.Emit(OpCodes.Ldnull);
                processor.Emit(OpCodes.Ldarg_0);
            }
            else
            {
                System.Diagnostics.Debug.Assert(numFromNativeParams == marshalerFromNativeParamCountMin);
            }
            processor.Emit(OpCodes.Callvirt, assembly.MainModule.ImportEx(fromNativeMethod));
            // Now insert the branch
            Instruction branchInstruction = processor.Create(OpCodes.Brtrue_S, branchTarget);

            processor.InsertBefore(branchPosition, branchInstruction);

            EndGetter(typeInfo, propertyInfo, getter, isValidField, processor);
        }
示例#9
0
 public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
 {
     typeInfo.AdditionalFlags |= ManagedUnrealTypeInfoFlags.UClass;
     typeInfo.ClassFlags      |= (EClassFlags)Flags;
     if (!string.IsNullOrEmpty(Config))
     {
         typeInfo.ClassConfigName = Config;
     }
 }
示例#10
0
        private void WriteGetterFixedSizeArray(TypeDefinition type, ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo,
                                               MethodDefinition getter, FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition nativePropertyField,
                                               FieldDefinition fixedSizeArrayField)
        {
            ILProcessor processor = BeginGetter(getter);

            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldfld, fixedSizeArrayField);

            // Save the position of the branch instruction for later, when we have a reference to its target.
            // (will insert Brtrue_S before this instruction as a null check on the wrapper field)
            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchPosition = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            MethodReference constructor = null;

            foreach (MethodDefinition ctor in fixedSizeArrayField.FieldType.Resolve().GetConstructors())
            {
                if (ctor.Parameters.Count == 3)
                {
                    constructor = ctor;
                    break;
                }
            }
            VerifyNonNull(constructor, type, "constructor for " + fixedSizeArrayField.FieldType.FullName);
            constructor = GetConstrainedGenericTypeCtor(fixedSizeArrayField.FieldType, constructor);

            // new TFixedSizeArray<XXXX>(IntPtr.Add(Address, XXXX_Offset), XXXX_PropertyAddress, this);
            // IntPtr.Add(this.Address, XXXX_Offset)
            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Call, uobjectAddressGetter);
            processor.Emit(OpCodes.Ldsfld, offsetField);
            processor.Emit(OpCodes.Call, intPtrAddMethod);
            // XXXX_PropertyAddress
            processor.Emit(OpCodes.Ldsfld, nativePropertyField);
            // this
            processor.Emit(OpCodes.Ldarg_0);

            // Create an instance of the array and store in the member field
            processor.Emit(OpCodes.Newobj, constructor);
            processor.Emit(OpCodes.Stfld, fixedSizeArrayField);

            // return XXXX;
            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchTarget = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            processor.Emit(OpCodes.Ldfld, fixedSizeArrayField);

            // Insert the branch (before the return statement)
            Instruction branchInstruction = processor.Create(OpCodes.Brtrue_S, branchTarget);

            processor.InsertBefore(branchPosition, branchInstruction);

            EndGetter(typeInfo, propertyInfo, getter, isValidField, processor);
        }
示例#11
0
 public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
 {
     if (Enabled)
     {
         typeInfo.ClassFlags |= EClassFlags.EditInlineNew;
     }
     else
     {
         typeInfo.ClassFlags &= ~EClassFlags.EditInlineNew;
     }
 }
示例#12
0
 public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
 {
     if (IsTransient)
     {
         typeInfo.ClassFlags |= EClassFlags.Transient;
     }
     else
     {
         typeInfo.ClassFlags &= ~EClassFlags.Transient;
     }
 }
示例#13
0
 public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
 {
     if (Collapse)
     {
         typeInfo.ClassFlags |= EClassFlags.CollapseCategories;
     }
     else
     {
         typeInfo.ClassFlags &= ~EClassFlags.CollapseCategories;
     }
 }
示例#14
0
        private void WriteGetter(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition getter,
                                 FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition nativePropertyField)
        {
            ILProcessor processor = BeginGetter(getter);

            Instruction[]   loadBufferInstructions = GetLoadNativeBufferInstructions(typeInfo, processor, null, offsetField);
            MethodReference marshaler = GetFromNativeMarshaler(ManagedUnrealMarshalerType.Default, propertyInfo);

            WriteMarshalFromNative(processor, nativePropertyField, loadBufferInstructions, null, marshaler);
            EndGetter(typeInfo, propertyInfo, getter, isValidField, processor);
        }
        private void EmitLoad(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField,
                              ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, VariableDefinition marshalerVar, FieldDefinition field)
        {
            // Assuming we are targeting "this"
            processor.Emit(OpCodes.Ldarg_0);

            EmitLoad(processor, loadBuffer, offsetField, nativePropertyField, typeInfo, propertyInfo, marshalerVar);

            // Assuming we are storing into a non-static field
            processor.Emit(OpCodes.Stfld, field);
        }
示例#16
0
        private void WriteSetter(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition setter,
                                 FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition nativePropertyField)
        {
            ILProcessor processor = BeginSetter(setter);
            Instruction loadValue = processor.Create(OpCodes.Ldarg_1);

            Instruction[]   loadBufferInstructions = GetLoadNativeBufferInstructions(typeInfo, processor, null, offsetField);
            MethodReference marshaler = GetToNativeMarshaler(ManagedUnrealMarshalerType.Default, propertyInfo);

            WriteMarshalToNative(processor, nativePropertyField, loadBufferInstructions, null, loadValue, marshaler);
            EndSetter(typeInfo, propertyInfo, setter, isValidField, processor);
        }
示例#17
0
        private void WriteCachedFTextGetter(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition getter,
                                            FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition cachedFTextField)
        {
            ILProcessor processor = BeginGetter(getter);

            WriteCachedFTextGetterSetter(offsetField, cachedFTextField, processor,
                                         new Instruction[]
            {
                processor.Create(OpCodes.Ldfld, cachedFTextField)
            });
            EndGetter(typeInfo, propertyInfo, getter, isValidField, processor);
        }
        private FieldDefinition AddNativePropertyField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo, ManagedUnrealPropertyInfo paramInfo)
        {
            if (!ManagedUnrealTypeInfo.RequiresNativePropertyField(paramInfo, codeSettings.LazyFunctionParamInitDestroy))
            {
                return(null);
            }
            FieldDefinition field = new FieldDefinition(functionInfo.Name + "_" + paramInfo.Name + codeSettings.VarNames.PropertyAddress,
                                                        FieldAttributes.Static | FieldAttributes.Private, ufieldAddressTypeRef);

            type.Fields.Add(field);
            return(field);
        }
示例#19
0
 public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
 {
     if (IsPlacable && typeInfo.ClassFlags.HasFlag(EClassFlags.NotPlaceable))
     {
         InvalidTarget       = true;
         InvalidTargetReason = "The 'placeable' specifier is only allowed on classes which have " +
                               "a base class that's marked as not placeable. Classes are assumed to be placeable by default.";
     }
     else if (!IsPlacable)
     {
         typeInfo.ClassFlags |= EClassFlags.NotPlaceable;
     }
 }
示例#20
0
 public override void ProcessStruct(ManagedUnrealTypeInfo typeInfo)
 {
     typeInfo.StructFlags |= (EStructFlags)Flags;
     if (ForceBlittable)
     {
         typeInfo.BlittableKind = ManagedUnrealBlittableKind.ForceBlittable;
     }
     if (Atomic)
     {
         typeInfo.StructFlags |= EStructFlags.Atomic;
     }
     typeInfo.AdditionalFlags |= ManagedUnrealTypeInfoFlags.UStruct;
 }
示例#21
0
        private void EmitFunctionParamDestroy(ILProcessor processor, ManagedUnrealFunctionInfo functionInfo, ManagedUnrealPropertyInfo paramInfo,
                                              VariableDefinition paramsBuffer, FieldDefinition nativePropertyField)
        {
            if (!codeSettings.LazyFunctionParamInitDestroy && ManagedUnrealTypeInfo.PropertyRequiresDestroy(paramInfo))
            {
                // Ensure the checks to include the native field prop are in sync with this function
                Debug.Assert(nativePropertyField != null);

                // NativeReflection.DestroyValue_InContainer(XXXX_YYYY_PropertyAddress.Address, ParamsBuffer)
                EmitLdNativePropertyFieldAddress(processor, nativePropertyField);
                processor.Emit(OpCodes.Ldloc, paramsBuffer);
                processor.Emit(OpCodes.Call, reflectionDestroyValue_InContainer);
            }
        }
        /// <summary>
        /// Loads the static delegates FromNative / ToNative from CachedMarshalingDelegates<,>
        /// e.g. CachedMarshalingDelegates<int, BlittableTypeMarshaler<int>>.FromNative / .ToNative
        /// </summary>
        private void EmitCachedMarshalingDelegates(ILProcessor processor, ManagedUnrealPropertyInfo propertyInfo, ManagedUnrealMarshalerType marshalerType)
        {
            foreach (ManagedUnrealTypeInfoReference genericArg in propertyInfo.GenericArgs)
            {
                Type cachedMarshalingDelegatesType = ManagedUnrealTypeInfo.GetCachedMarshalingDelegatesType(marshalerType, genericArg);

                FieldReference fromNative = assembly.MainModule.ImportEx(
                    ManagedUnrealTypeInfo.GetCachedMarshalingDelegatesDelegate(cachedMarshalingDelegatesType, true));
                FieldReference toNative = assembly.MainModule.ImportEx(
                    ManagedUnrealTypeInfo.GetCachedMarshalingDelegatesDelegate(cachedMarshalingDelegatesType, false));
                processor.Emit(OpCodes.Ldsfld, fromNative);
                processor.Emit(OpCodes.Ldsfld, toNative);
            }
        }
        private void EmitStore(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField,
                               ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, Instruction[] loadValue, VariableDefinition marshalerVar)
        {
            if (marshalerVar != null)
            {
                processor.Emit(ManagedUnrealTypeInfo.IsPropertyMarshalerStruct(propertyInfo) ? OpCodes.Ldloca : OpCodes.Ldloc, marshalerVar);
            }

            Instruction[] loadBufferInstructions = GetLoadNativeBufferInstructions(typeInfo, processor, loadBuffer, offsetField);

            MethodReference toNativeMethod = GetToNativeMarshaler(ManagedUnrealMarshalerType.Copy, propertyInfo);

            WriteMarshalToNative(processor, nativePropertyField, loadBufferInstructions, null, loadValue, toNativeMethod);
        }
示例#24
0
        private void WriteCachedFTextSetter(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition setter,
                                            FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition cachedFTextField)
        {
            ILProcessor processor = BeginSetter(setter);

            WriteCachedFTextGetterSetter(offsetField, cachedFTextField, processor,
                                         new Instruction[]
            {
                processor.Create(OpCodes.Ldfld, cachedFTextField),
                processor.Create(OpCodes.Ldarg_1),
                processor.Create(OpCodes.Callvirt, ftextCopyFrom)
            });
            EndSetter(typeInfo, propertyInfo, setter, isValidField, processor);
        }
示例#25
0
        public override void ProcessClass(ManagedUnrealTypeInfo typeInfo)
        {
            if (ClassWithinType != null)
            {
                if (!ClassWithinType.IsSameOrSubclassOf(typeof(UObject)))
                {
                    throw new ManagedUnrealTypeInfoException("The base type for ClassWithin is not a UObject type '" + typeInfo.FullName + "'");
                }
            }
            else if (string.IsNullOrEmpty(Path))
            {
                throw new ManagedUnrealTypeInfoException("Type / path not specified for ClassWithin on '" + typeInfo.FullName + "'");
            }

            throw new NotImplementedException("TODO: Create some way of linking this to UClass " +
                                              " if the target is a managed unreal type it wont have a path specified yet - use the fully qualified name?");
        }
示例#26
0
        private Dictionary <ManagedUnrealPropertyInfo, ParameterDefinition> GetParamsFromMethod(TypeDefinition type,
                                                                                                ManagedUnrealFunctionInfo functionInfo, MethodDefinition method, InjectedMembers injectedMembers, bool addFields)
        {
            Dictionary <ManagedUnrealPropertyInfo, ParameterDefinition> parameters = new Dictionary <ManagedUnrealPropertyInfo, ParameterDefinition>();

            foreach (ManagedUnrealPropertyInfo param in functionInfo.Params)
            {
                Type paramType = ManagedUnrealTypeInfo.GetTypeFromPropertyInfo(param);

                List <ParameterDefinition> foundParams = new List <ParameterDefinition>();
                foreach (ParameterDefinition paramDef in method.Parameters)
                {
                    if (paramDef.Name == param.Name)
                    {
                        foundParams.Add(paramDef);
                        break;
                    }
                }
                VerifySingleResult(foundParams, type, "Param count mismatch " + param.Name + " in delegate");

                if (addFields)
                {
                    FieldDefinition isValidField        = AddIsValidField(type, functionInfo, param);
                    FieldDefinition offsetField         = AddOffsetField(type, functionInfo, param);
                    FieldDefinition nativePropertyField = AddNativePropertyField(type, functionInfo, param);
                    injectedMembers.SetFunctionParamIsValid(functionInfo, param, isValidField);
                    injectedMembers.SetFunctionParamOffset(functionInfo, param, offsetField);
                    injectedMembers.SetFunctionParamPropertyAddress(functionInfo, param, nativePropertyField);
                }

                parameters.Add(param, foundParams[0]);
            }

            if (addFields && functionInfo.ReturnProp != null)
            {
                FieldDefinition isValidField        = AddIsValidField(type, functionInfo, functionInfo.ReturnProp);
                FieldDefinition offsetField         = AddOffsetField(type, functionInfo, functionInfo.ReturnProp);
                FieldDefinition nativePropertyField = AddNativePropertyField(type, functionInfo, functionInfo.ReturnProp);
                injectedMembers.SetFunctionParamIsValid(functionInfo, functionInfo.ReturnProp, isValidField);
                injectedMembers.SetFunctionParamOffset(functionInfo, functionInfo.ReturnProp, offsetField);
                injectedMembers.SetFunctionParamPropertyAddress(functionInfo, functionInfo.ReturnProp, nativePropertyField);
            }

            return(parameters);
        }
示例#27
0
        /// <summary>
        /// Inserts an IsValid safeguard on the given non-blittable struct marshaling method (ctor (FromNative) / ToNative)
        /// </summary>
        private void InsertStructMarshalerIsValidSafeguard(TypeDefinition type, ManagedUnrealTypeInfo structInfo,
                                                           MethodDefinition method, InjectedMembers injectedMembers, ILProcessor processor, bool isCtor)
        {
            if (!codeSettings.GenerateIsValidSafeguards)
            {
                return;
            }

            FieldDefinition structIsValidField = injectedMembers.StructIsValid;

            if (structIsValidField == null)
            {
                return;
            }

            // If the struct isn't valid create a log and set any out params to default values
            // if (!structName_IsValid)
            // {
            //     NativeReflection.LogInvalidStructAccessed("XXXX");
            //     PropXXX = default(XXXX); (constructor only)
            //     return;
            // }

            List <Instruction> instructions = new List <Instruction>();

            Instruction branchTarget = processor.Body.Instructions[0];

            instructions.Add(processor.Create(OpCodes.Ldsfld, structIsValidField));
            instructions.Add(processor.Create(OpCodes.Brtrue, branchTarget));
            instructions.Add(processor.Create(OpCodes.Ldstr, structInfo.Path));
            instructions.Add(processor.Create(OpCodes.Call, reflectionLogInvalidStructAccessedMethod));

            if (isCtor)
            {
                // Set struct members to default(XXXX)
                instructions.AddRange(CreateStructPropertyDefaults(processor, structInfo, type));
            }

            instructions.Add(processor.Create(OpCodes.Ret));

            // Insert the instructions at the start
            InsertInstructionsAt(processor, 0, instructions.ToArray());
        }
示例#28
0
        private void WriteGetterDelegate(ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, MethodDefinition getter,
                                         FieldDefinition isValidField, FieldDefinition offsetField, FieldDefinition delegateWrapperField)
        {
            ILProcessor processor = BeginGetter(getter);

            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldfld, delegateWrapperField);

            // Save the position of the branch instruction for later, when we have a reference to its target.
            // (will insert Brtrue_S before this instruction as a null check on the wrapper field)
            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchPosition = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            Type delegateType = ManagedUnrealTypeInfo.GetTypeFromPropertyInfo(propertyInfo);

            // Find the default constructor / SetAddress method for the delegate
            System.Reflection.ConstructorInfo delegateCtor     = delegateType.GetConstructor(Type.EmptyTypes);
            System.Reflection.MethodInfo      setAddressMethod = delegateType.GetMethod("SetAddress");

            // Create an instance of the delegate and store in the member field
            processor.Emit(OpCodes.Newobj, assembly.MainModule.ImportEx(delegateCtor));
            processor.Emit(OpCodes.Stfld, delegateWrapperField);

            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Ldfld, delegateWrapperField);
            processor.Emit(OpCodes.Ldarg_0);
            processor.Emit(OpCodes.Call, uobjectAddressGetter);
            processor.Emit(OpCodes.Ldsfld, offsetField);
            processor.Emit(OpCodes.Call, intPtrAddMethod);
            processor.Emit(OpCodes.Callvirt, assembly.MainModule.ImportEx(setAddressMethod));

            processor.Emit(OpCodes.Ldarg_0);
            Instruction branchTarget = processor.Body.Instructions[processor.Body.Instructions.Count - 1];

            processor.Emit(OpCodes.Ldfld, delegateWrapperField);

            // Insert the branch
            Instruction branchInstruction = processor.Create(OpCodes.Brtrue_S, branchTarget);

            processor.InsertBefore(branchPosition, branchInstruction);

            EndGetter(typeInfo, propertyInfo, getter, isValidField, processor);
        }
        private Instruction[] CreateStructPropertyDefaults(ILProcessor processor, ManagedUnrealTypeInfo structInfo, TypeDefinition structType)
        {
            List <Instruction> instructions = new List <Instruction>();

            Dictionary <string, FieldDefinition> fieldsByName = new Dictionary <string, FieldDefinition>();

            foreach (FieldDefinition fieldDef in structType.Fields)
            {
                fieldsByName.Add(fieldDef.Name, fieldDef);
            }

            foreach (ManagedUnrealPropertyInfo propertyInfo in structInfo.Properties)
            {
                FieldDefinition field = null;
                fieldsByName.TryGetValue(propertyInfo.Name, out field);
                VerifyNonNull(field, structType, "field " + propertyInfo.Name);

                instructions.Add(processor.Create(OpCodes.Ldarg_0));
                instructions.AddRange(CreateSetDefaultValue(processor, propertyInfo.Type.TypeCode, field));
            }

            return(instructions.ToArray());
        }
        private void EmitStore(ILProcessor processor, Instruction loadBuffer, FieldDefinition offsetField, FieldDefinition nativePropertyField,
                               ManagedUnrealTypeInfo typeInfo, ManagedUnrealPropertyInfo propertyInfo, VariableDefinition marshalerVar, ParameterDefinition param)
        {
            // This is moving the parameter into the native buffer

            Instruction[] loadValue = null;
            if (propertyInfo.IsByRef)
            {
                // If this is a "ref" param we need to pass the arg without the ref as no marshalers use by ref args.
                // (if they did support ref we would need to do the opposite on all args which didn't match the ref arg)
                System.Diagnostics.Debug.Assert(param.ParameterType.IsByReference);
                loadValue = new Instruction[]
                {
                    processor.Create(OpCodes.Ldarg, param),
                    CreateLdRefOutParam(processor, param, propertyInfo.Type.TypeCode)
                };
            }
            else
            {
                loadValue = new Instruction[] { processor.Create(OpCodes.Ldarg, param) };
            }
            EmitStore(processor, loadBuffer, offsetField, nativePropertyField, typeInfo, propertyInfo, loadValue, marshalerVar);
        }