Beispiel #1
0
        public override void Populate(IDefinitionManager definitionManager, IPlanet planet, IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11)
        {
            // Tree Definitions initialisieren
            if (treeDefinitions == null)
            {
                treeDefinitions = definitionManager.GetDefinitions<ITreeDefinition>().OrderBy(d => d.Order).ToArray();
                foreach (var treeDefinition in treeDefinitions)
                    treeDefinition.Init(definitionManager);
            }

            int salt = (column00.Index.X & 0xffff) + ((column00.Index.Y & 0xffff) << 16);
            Random random = new Random(planet.Seed + salt);

            Index3 sample = new Index3(column00.Index.X * Chunk.CHUNKSIZE_X, column00.Index.Y * Chunk.CHUNKSIZE_Y, column00.Heights[0, 0]);
            foreach (var treeDefinition in treeDefinitions)
            {
                int density = treeDefinition.GetDensity(planet, sample);
                if (density <= 0) continue;

                for (int i = 0; i < density; i++)
                {
                    int x = random.Next(Chunk.CHUNKSIZE_X / 2, Chunk.CHUNKSIZE_X * 3 / 2);
                    int y = random.Next(Chunk.CHUNKSIZE_Y / 2, Chunk.CHUNKSIZE_Y * 3 / 2);
                    int z = LocalBuilder.GetSurfaceHeight(column00, column10, column01, column11, x, y);

                    LocalBuilder builder = new LocalBuilder(x, y, z + 1, column00, column10, column01, column11);
                    treeDefinition.PlantTree(definitionManager, planet, new Index3(x, y, z), builder, random.Next(int.MaxValue));
                }
            }
        }
        public override void PlantTree(IDefinitionManager definitionManager, IPlanet planet, Index3 index, LocalBuilder builder, int seed)
        {
            ushort ground = builder.GetBlock(0, 0, -1);
            if (ground == water) return;

            Random rand = new Random(seed);
            int height = rand.Next(2, 4);

            for (int i = 0; i < height; i++)
                builder.SetBlock(0, 0, i, cactus);
        }
        public override void PlantTree(IDefinitionManager definitionManager, IPlanet planet, Index3 index, LocalBuilder builder, int seed)
        {
            ushort ground = builder.GetBlock(0, 0, -1);
            if (ground == water) return;

            Random rand = new Random(seed);
            int height = rand.Next(3, 5);
            int radius = rand.Next(3, height);

            builder.FillSphere(0, 0, height, radius, leave);

            for (int i = 0; i < height + 2; i++)
            {
                builder.SetBlock(0, 0, 0 + i, wood);
            }
        }
Beispiel #4
0
        public bool TryEmitSerialiseCode(ILGenerator ilg, ThrowBlockGatherer throwBlocks, ICollection <string> errors, LocalBuilder value, LocalBuilder packer, LocalBuilder contextLocal, DasherContext context)
        {
            // write the string form of the value
            ilg.Emit(OpCodes.Ldloc, packer);
            ilg.Emit(OpCodes.Ldloca, value);
            ilg.Emit(OpCodes.Call, Methods.Decimal_ToString);
            ilg.Emit(OpCodes.Call, Methods.Packer_Pack_String);

            return(true);
        }
        private static Type CreateInterfaceType()
        {
            Type type = typeof(I);
            // Get the current application domain for the current thread.
            AppDomain    myCurrentDomain = AppDomain.CurrentDomain;
            AssemblyName myAssemblyName  = new AssemblyName()
            {
                Name = "TempAssembly"
            };

            // Define a dynamic assembly in the current application domain.
            AssemblyBuilder myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run);

            // Define a dynamic module in this assembly.
            ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("TempModule");

            // Define a runtime class with specified name and attributes.
            TypeBuilder typeBuilder = myModuleBuilder.DefineType("ImplOf" + type.Name, TypeAttributes.Class | TypeAttributes.Public);

            typeBuilder.AddInterfaceImplementation(type);

            // Create Constructor
            ConstructorInfo    baseConstructorInfo = typeof(object).GetConstructor(new Type[0]);
            ConstructorBuilder constructorBuilder  = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
            ILGenerator        ilGenerator         = constructorBuilder.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_0);                   // Load "this"
            ilGenerator.Emit(OpCodes.Call, baseConstructorInfo); // Call the base constructor
            ilGenerator.Emit(OpCodes.Ret);                       // return

            // actor field
            var actorField = typeBuilder.DefineField("actorRef", typeof(IActor), FieldAttributes.Public);

            // what methods ?
            List <MethodInfo> methods = new List <MethodInfo>();

            AddMethodsToList(methods, type);

            // properties ?
            List <PropertyInfo> properties = new List <PropertyInfo>();

            AddPropertiesToList(properties, type);

            // add properties
            foreach (PropertyInfo pi in properties)
            {
                string piName       = pi.Name;
                Type   propertyType = pi.PropertyType;

                // Create underlying field; all properties have a field of the same type
                FieldBuilder field =
                    typeBuilder.DefineField("_" + piName, propertyType, FieldAttributes.Private);

                // If there is a getter in the interface, create a getter in the new type
                MethodInfo getMethod = pi.GetGetMethod();
                if (null != getMethod)
                {
                    // This will prevent us from creating a default method for the property's getter
                    methods.Remove(getMethod);

                    // Now we will generate the getter method
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(getMethod.Name,
                                                                           MethodAttributes.Public | MethodAttributes.Virtual, propertyType,
                                                                           Type.EmptyTypes);

                    // The ILGenerator class is used to put op-codes (similar to assembly)
                    // into the method
                    ilGenerator = methodBuilder.GetILGenerator();

                    // These are the op-codes, (similar to assembly)
                    ilGenerator.Emit(OpCodes.Ldarg_0);  // Load "this"
                                                        // Load the property's underlying field onto the stack
                    ilGenerator.Emit(OpCodes.Ldfld, field);
                    ilGenerator.Emit(OpCodes.Ret);      // Return the value on the stack

                    // We need to associate our new type's method with the
                    // getter method in the interface
                    typeBuilder.DefineMethodOverride(methodBuilder, getMethod);
                }

                // If there is a setter in the interface, create a setter in the new type
                MethodInfo setMethod = pi.GetSetMethod();
                if (null != setMethod)
                {
                    // This will prevent us from creating a default method for the property's setter
                    methods.Remove(setMethod);

                    // Now we will generate the setter method
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod
                                                      (setMethod.Name, MethodAttributes.Public |
                                                      MethodAttributes.Virtual, typeof(void), new Type[] { pi.PropertyType });

                    // The ILGenerator class is used to put op-codes (similar to assembly)
                    // into the method
                    ilGenerator = methodBuilder.GetILGenerator();

                    // These are the op-codes, (similar to assembly)
                    ilGenerator.Emit(OpCodes.Ldarg_0);  // Load "this"
                    ilGenerator.Emit(OpCodes.Ldarg_1);  // Load "value" onto the stack
                                                        // Set the field equal to the "value" on the stack
                    ilGenerator.Emit(OpCodes.Stfld, field);
                    ilGenerator.Emit(OpCodes.Ret);      // Return nothing

                    // We need to associate our new type's method with the
                    // setter method in the interface
                    typeBuilder.DefineMethodOverride(methodBuilder, setMethod);
                }
            }

            // add method
            foreach (MethodInfo methodInfo in methods)
            {
                // Get the return type and argument types

                Type returnType = methodInfo.ReturnType;

                List <Type> argumentTypes = new List <Type>();
                foreach (ParameterInfo parameterInfo in methodInfo.GetParameters())
                {
                    argumentTypes.Add(parameterInfo.ParameterType);
                }

                // Define the method
                MethodBuilder methodBuilder = typeBuilder.DefineMethod
                                                  (methodInfo.Name, MethodAttributes.Public |
                                                  MethodAttributes.Virtual, returnType, argumentTypes.ToArray());

                // The ILGenerator class is used to put op-codes
                // (similar to assembly) into the method
                ilGenerator = methodBuilder.GetILGenerator();

                // If there's a return type, create a default value or null to return
                if (returnType != typeof(void))
                {
                    // send message with a future param
                    // this declares the local object, int, long, float, etc.
                    LocalBuilder localBuilder    = ilGenerator.DeclareLocal(returnType);
                    var          constructorInfo = returnType.GetConstructor(Type.EmptyTypes);
                    var          localMethodinfo = typeof(ActorProxyModel <T>).GetMethod("SendMethodAndParam");
                    // build local future
                    ilGenerator.Emit(OpCodes.Newobj, constructorInfo);
                    ilGenerator.Emit(OpCodes.Stloc_0);

                    ilGenerator.Emit(OpCodes.Ldarg_0);           // this
                    ilGenerator.Emit(OpCodes.Ldfld, actorField); // actor ref
                    ilGenerator.Emit(OpCodes.Ldstr, methodInfo.Name);
                    ilGenerator.Emit(OpCodes.Ldloc_0);           // future
                    ilGenerator.Emit(OpCodes.Callvirt, localMethodinfo);

                    // load the value on the stack to return
                    ilGenerator.Emit(OpCodes.Ldloc, localBuilder);
                    ilGenerator.Emit(OpCodes.Ret);                   // return
                }
                else
                {
                    var localMethodinfo = typeof(ActorProxyModel <T>).GetMethod("SendMethodAndParam");
                    ilGenerator.Emit(OpCodes.Ldarg_0);           // this
                    ilGenerator.Emit(OpCodes.Ldfld, actorField); // actor ref
                    ilGenerator.Emit(OpCodes.Ldstr, methodInfo.Name);
                    ilGenerator.Emit(OpCodes.Ldarg_1);           // message
                    ilGenerator.Emit(OpCodes.Callvirt, localMethodinfo);
                    ilGenerator.Emit(OpCodes.Ret);
                }
                // We need to associate our new type's method with the method in the interface
                typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
            }

            Type createdType = typeBuilder.CreateType();

            // InterfaceImplementations[type] = createdType;
            return(createdType);
        }
Beispiel #6
0
 public _Local(CodeGen owner, LocalBuilder var)
 {
     _owner = owner;
     _var   = var;
     _t     = var.LocalType;
 }
Beispiel #7
0
        private void BuildIsNull(
            MemberInfo mi,
            TypeBuilderHelper nestedType,
            Type memberType)
        {
            var methodType  = mi.DeclaringType;
            var getMethod   = null as MethodInfo;
            var isNullable  = TypeHelper.IsNullable(memberType);
            var isValueType = (!isNullable && memberType.IsValueType);

            if (!isValueType && mi is PropertyInfo)
            {
                getMethod = ((PropertyInfo)mi).GetGetMethod();

                if (getMethod == null)
                {
                    if (_type != _originalType)
                    {
                        getMethod  = _type.GetMethod("get_" + mi.Name);
                        methodType = _type;
                    }

                    if (getMethod == null)
                    {
                        return;
                    }
                }
            }

            var methodInfo = _memberAccessor.GetMethod("IsNull");

            if (methodInfo == null)
            {
                return;
            }

            var method = nestedType.DefineMethod(methodInfo);
            var emit   = method.Emitter;

            if (isValueType)
            {
                emit
                .ldc_i4_0
                .end()
                ;
            }
            else
            {
                LocalBuilder locObj = null;

                if (isNullable)
                {
                    locObj = method.Emitter.DeclareLocal(memberType);
                }

                emit
                .ldarg_1
                .castType(methodType)
                .end();

                if (mi is FieldInfo)
                {
                    emit.ldfld((FieldInfo)mi);
                }
                else
                {
                    emit.callvirt(getMethod);
                }

                if (isNullable)
                {
                    emit
                    .stloc(locObj)
                    .ldloca(locObj)
                    .call(memberType, "get_HasValue")
                    .ldc_i4_0
                    .ceq
                    .end();
                }
                else
                {
                    emit
                    .ldnull
                    .ceq
                    .end();
                }
            }

            emit
            .ret()
            ;
        }
Beispiel #8
0
    static void EmitPtrAndFlagsStore(ILGenerator ilg, LocalBuilder bufLocal,
                                     int argnum, IntPtr ptr, sbyte flags)
    {
        //= bufLocal[argnum].ptr = ptr;
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, ptr.ToInt32());
        ilg.Emit(OpCodes.Stind_I4);

        //= bufLocal[argnum].flags = flags;
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, (Int32)flags);
        ilg.Emit(OpCodes.Stind_I1);
    }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="Name">Local object name</param>
 /// <param name="LocalType">Local type</param>
 public DefineLocal(string Name, Type LocalType)
     : base()
 {
     Result = new LocalBuilder(Utilities.Reflection.Emit.BaseClasses.MethodBase.CurrentMethod, Name, LocalType);
 }
Beispiel #10
0
        private void EmitLiftedBinaryArithmetic(ExpressionType op, Type leftType, Type rightType, Type resultType)
        {
            bool leftIsNullable  = leftType.IsNullable();
            bool rightIsNullable = rightType.IsNullable();

            Debug.Assert(leftIsNullable || rightIsNullable);

            Label        labIfNull = _ilg.DefineLabel();
            Label        labEnd    = _ilg.DefineLabel();
            LocalBuilder locLeft   = GetLocal(leftType);
            LocalBuilder locRight  = GetLocal(rightType);
            LocalBuilder locResult = GetLocal(resultType);

            // store values (reverse order since they are already on the stack)
            _ilg.Emit(OpCodes.Stloc, locRight);
            _ilg.Emit(OpCodes.Stloc, locLeft);

            // test for null
            // don't use short circuiting
            if (leftIsNullable)
            {
                _ilg.Emit(OpCodes.Ldloca, locLeft);
                _ilg.EmitHasValue(leftType);
            }

            if (rightIsNullable)
            {
                _ilg.Emit(OpCodes.Ldloca, locRight);
                _ilg.EmitHasValue(rightType);
                if (leftIsNullable)
                {
                    _ilg.Emit(OpCodes.And);
                }
            }

            _ilg.Emit(OpCodes.Brfalse_S, labIfNull);

            // do op on values
            if (leftIsNullable)
            {
                _ilg.Emit(OpCodes.Ldloca, locLeft);
                _ilg.EmitGetValueOrDefault(leftType);
            }
            else
            {
                _ilg.Emit(OpCodes.Ldloc, locLeft);
            }

            if (rightIsNullable)
            {
                _ilg.Emit(OpCodes.Ldloca, locRight);
                _ilg.EmitGetValueOrDefault(rightType);
            }
            else
            {
                _ilg.Emit(OpCodes.Ldloc, locRight);
            }

            //RELEASING locLeft locRight
            FreeLocal(locLeft);
            FreeLocal(locRight);

            EmitBinaryOperator(op, leftType.GetNonNullable(), rightType.GetNonNullable(), resultType.GetNonNullable(), liftedToNull: false);

            // construct result type
            ConstructorInfo ci = resultType.GetConstructor(new[] { resultType.GetNonNullable() });

            // ReSharper disable once AssignNullToNotNullAttribute
            _ilg.Emit(OpCodes.Newobj, ci);
            _ilg.Emit(OpCodes.Stloc, locResult);
            _ilg.Emit(OpCodes.Br_S, labEnd);

            // if null then create a default one
            _ilg.MarkLabel(labIfNull);
            _ilg.Emit(OpCodes.Ldloca, locResult);
            _ilg.Emit(OpCodes.Initobj, resultType);

            _ilg.MarkLabel(labEnd);

            _ilg.Emit(OpCodes.Ldloc, locResult);

            //RELEASING locResult
            FreeLocal(locResult);
        }
Beispiel #11
0
 public static Instruction Create(Specials specials, LocalBuilder lvar)
 {
     Instruction i = new Instruction();
     i.type = InstructionType.Special;
     i.operand = lvar;
     i.operandType = typeof(LocalBuilder);
     i.special = specials;
     return i;
 }
    //Examples of generated code
    //     public static XWeak constructor1(XComponentContext ctx)
    //     {
    //         XMultiComponentFactory factory = ctx.getServiceManager();
    //         if (factory == null)
    //             throw new com.sun.star.uno.DeploymentException("bla", null);
    //         return (XWeak) factory.createInstanceWithContext("service_specifier", ctx);
    //     }
    //     public static XWeak constructor2(XComponentContext ctx, int a, int b)
    //     {
    //         XMultiComponentFactory factory = ctx.getServiceManager();
    //         if (factory == null)
    //             throw new com.sun.star.uno.DeploymentException("bla", null);
    //         Any a1;
    //         a1 = new Any( typeof(int), a);
    //         Any a2;
    //         a2 = new Any( typeof(int), b);
    //         Any[] arAny = new Any[2];
    //         arAny[0] = a1;
    //         arAny[1] = a2;
    //         return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx);
    //     }
    //     public static XWeak constructor3(XComponentContext ctx, params Any[] c)
    //     {
    //         XMultiComponentFactory factory = ctx.getServiceManager();
    //         if (factory == null)
    //             throw new com.sun.star.uno.DeploymentException("bla", null);
    //         return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx);
    //     }
    Type complete_service_type(service_entry entry)
    {
        TypeBuilder type_builder = entry.m_type_builder;
        XServiceTypeDescription2 xServiceType = entry.m_xType;

        // Create the private default constructor
        ConstructorBuilder ctor_builder =
            type_builder.DefineConstructor(
                (MethodAttributes.Private |
                 MethodAttributes.HideBySig |
                 MethodAttributes.SpecialName |
                 MethodAttributes.RTSpecialName),
                CallingConventions.Standard, null);

        ILGenerator code = ctor_builder.GetILGenerator();
        code.Emit(OpCodes.Ldarg_0); // push this
        code.Emit(OpCodes.Call,
                  type_builder.BaseType.GetConstructor(new Type[0]));
        code.Emit(OpCodes.Ret);

        // Create the service constructors.
        // optain the interface which makes up this service, it is the
        // return type of the constructor functions
        XInterfaceTypeDescription2 xIfaceType =
            xServiceType.getInterface() as XInterfaceTypeDescription2;
        if (xIfaceType == null)
            xIfaceType = resolveInterfaceTypedef(xServiceType.getInterface());
        Type retType = get_type(xIfaceType);

        // Create the ConstructorInfo for a DeploymentException
        Type typeDeploymentExc =
            get_type("unoidl.com.sun.star.uno.DeploymentException", true);

        Type[] typeCtor = new Type[] { typeof(System.String),
                                       typeof(System.Object) };
        ConstructorInfo ctorDeploymentException =
            typeDeploymentExc.GetConstructor(typeCtor);

        XServiceConstructorDescription[] ctors =
            xServiceType.getConstructors();

        Type type_uno_exception =
            get_type("unoidl.com.sun.star.uno.Exception", true);

        for (int i = ctors.Length - 1; i >= 0; --i)
        {
            bool bParameterArray = false;
            Type typeAny = typeof(uno.Any);
            XServiceConstructorDescription ctorDes = ctors[i];
            // obtain the parameter types
            XParameter[] xParams = ctorDes.getParameters();
            Type[] typeParameters = new Type[xParams.Length + 1];
            typeParameters[0] =
                get_type("unoidl.com.sun.star.uno.XComponentContext", true);
            for (int iparam = 0; iparam != xParams.Length; ++iparam)
            {
                if (xParams[iparam].isRestParameter())
                    typeParameters[iparam + 1] = typeof(uno.Any[]);
                else
                    typeParameters[iparam + 1] =
                        get_type(xParams[iparam].getType());
            }

            // define method
            string ctorName;
            if (ctorDes.isDefaultConstructor())
                ctorName = "create";
            else
                ctorName = ctorDes.getName();
            MethodBuilder method_builder = type_builder.DefineMethod(
                ctorName,
                (MethodAttributes.Public |
                 MethodAttributes.HideBySig |
                 MethodAttributes.Static),
                retType,
                typeParameters);

            // define UNO exception attribute (exceptions)
            CustomAttributeBuilder attrBuilder =
                get_service_exception_attribute(ctorDes);
            if (attrBuilder != null)
                method_builder.SetCustomAttribute(attrBuilder);

            // define parameter attributes (paramarray), names etc.
            // The first parameter is the XComponentContext, which cannot be
            // obtained from reflection.
            // The context is not part of the idl description
            /* ParameterBuilder param_builder = */
            method_builder.DefineParameter(
                1, ParameterAttributes.In, "the_context");

            ParameterBuilder[] parameterBuilders =
                new ParameterBuilder[xParams.Length];
            for (int iparam = 0; iparam != xParams.Length + 1; ++iparam)
            {
                parameterBuilders[iparam] = method_builder.DefineParameter(
                    iparam + 2, ParameterAttributes.In,
                    xParams[iparam].getName());

                if (xParams[iparam].isRestParameter())
                {
                    bParameterArray = true;
                    // set the ParameterArrayAttribute
                    ConstructorInfo ctor_info =
                        typeof(System.ParamArrayAttribute).GetConstructor(
                            new Type[0]);
                    CustomAttributeBuilder attr_builder =
                        new CustomAttributeBuilder(ctor_info, new object[0]);
                    parameterBuilders[iparam].SetCustomAttribute(attr_builder);
                    break;
                }
            }

            ILGenerator ilGen = method_builder.GetILGenerator();

            // Define locals
            // XMultiComponentFactory
            LocalBuilder local_factory = ilGen.DeclareLocal(
                get_type("unoidl.com.sun.star.lang.XMultiComponentFactory",
                         true));

            // The return type
            LocalBuilder local_return_val = ilGen.DeclareLocal(retType);

            // Obtain the XMultiComponentFactory and throw an exception if we
            // do not get one
            ilGen.Emit(OpCodes.Ldarg_0);

            MethodInfo methodGetServiceManager = get_type(
                "unoidl.com.sun.star.uno.XComponentContext", true)
                .GetMethod("getServiceManager");
            ilGen.Emit(OpCodes.Callvirt, methodGetServiceManager);
            ilGen.Emit(OpCodes.Stloc, local_factory);
            ilGen.Emit(OpCodes.Ldloc, local_factory);
            Label label1 = ilGen.DefineLabel();
            ilGen.Emit(OpCodes.Brtrue, label1);
            ilGen.Emit(OpCodes.Ldstr,
                       String.Format("The service unoidl.{0} could not be created. The context failed to supply the service manager.",
                                     xServiceType.getName()));
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Newobj, ctorDeploymentException);
            ilGen.Emit(OpCodes.Throw);
            ilGen.MarkLabel(label1);

            // We create a try/catch around the createInstanceWithContext,
            // etc. functions

            // There are 3 cases

            // 1. function do not specify exceptions. Then
            //    RuntimeExceptions are retrhown and other exceptions
            //    produce a DeploymentException.

            // 2. function specify Exception. Then all exceptions fly
            //    through

            // 3. function specifies exceptions but no Exception. Then
            //    these are rethrown and other exceptions, except
            //    RuntimeException, produce a deployment exception.

            // In case there are no parameters we call
            // XMultiComponentFactory.createInstanceWithContext

            ArrayList exceptionTypes =
                get_service_ctor_method_exceptions_reduced(
                    ctorDes.getExceptions());
            if (! exceptionTypes.Contains(type_uno_exception))
            {
                ilGen.BeginExceptionBlock();
            }
            if (xParams.Length == 0)
            {
                ilGen.Emit(OpCodes.Ldloc, local_factory);
                ilGen.Emit(OpCodes.Ldstr, to_cts_name(xServiceType.getName()));
                ilGen.Emit(OpCodes.Ldarg_0);

                MethodInfo methodCIWAAC =
                    local_factory.LocalType.GetMethod(
                        "createInstanceWithArgumentsAndContext");
                ilGen.Emit(OpCodes.Callvirt, methodCIWAAC);
            }
            else if (bParameterArray)
            {
                // Service constructor with parameter array
                ilGen.Emit(OpCodes.Ldloc, local_factory);
                ilGen.Emit(OpCodes.Ldstr, to_cts_name(xServiceType.getName()));
                ilGen.Emit(OpCodes.Ldarg_1);
                ilGen.Emit(OpCodes.Ldarg_0);
                MethodInfo methodCIWAAC =
                    local_factory.LocalType.GetMethod(
                        "createInstanceWithArgumentsAndContext");
                ilGen.Emit(OpCodes.Callvirt, methodCIWAAC);
            }
            else
            {
                // Any param1, Any param2, etc.
                // For each parameter, except the component context, and
                // the parameter array an Any is created.
                LocalBuilder[] localAnys = new LocalBuilder[xParams.Length];

                for (int iparam = 0; iparam < xParams.Length; ++iparam)
                {
                    localAnys[iparam] = ilGen.DeclareLocal(typeAny);
                }

                // Any[]. This array is filled with the created Anys
                // which contain the parameters and the values
                // contained in the parameter array
                LocalBuilder local_anyParams =
                    ilGen.DeclareLocal(typeof(uno.Any[]));

                // Create the Any for every argument, except for the
                // parameter array. localAnys contains the LocalBuilder for
                // all these parameters. We call the ctor Any(Type, Object)
                Type[] typesCtorAny = { typeof(System.Type),
                                        typeof(System.Object) };
                ConstructorInfo ctorAny =
                    typeAny.GetConstructor(typesCtorAny);
                for (int j = 0; j < localAnys.Length; ++j)
                {
                    ilGen.Emit(OpCodes.Ldloca, localAnys[j]);
                    ilGen.Emit(OpCodes.Ldtoken, typeParameters[j+1]);

                    Type[] typeParams = { typeof(System.RuntimeTypeHandle) };

                    ilGen.Emit(OpCodes.Call,
                               typeof(System.Type).GetMethod(
                                   "GetTypeFromHandle", typeParams));
                    ilGen.Emit(OpCodes.Ldarg, j + 1);
                    // if the parameter is a value type then we need
                    // to box it, because the Any ctor takes an Object
                    if (typeParameters[j+1].IsValueType)
                        ilGen.Emit(OpCodes.Box, typeParameters[j+1]);
                    ilGen.Emit(OpCodes.Call, ctorAny);
                }

                // Create the Any[] that is passed to the
                // createInstanceWithContext[AndArguments] function
                ilGen.Emit(OpCodes.Ldc_I4, localAnys.Length);
                ilGen.Emit(OpCodes.Newarr, typeAny);
                ilGen.Emit(OpCodes.Stloc, local_anyParams);

                // Assign all anys created from the parameters array
                // to the Any[]
                for (int j = 0; j < localAnys.Length; ++j)
                {
                    ilGen.Emit(OpCodes.Ldloc, local_anyParams);
                    ilGen.Emit(OpCodes.Ldc_I4, j);
                    ilGen.Emit(OpCodes.Ldelema, typeAny);
                    ilGen.Emit(OpCodes.Ldloc, localAnys[j]);
                    ilGen.Emit(OpCodes.Stobj, typeAny);
                }

                // call createInstanceWithContextAndArguments
                ilGen.Emit(OpCodes.Ldloc, local_factory);
                ilGen.Emit(OpCodes.Ldstr, to_cts_name(xServiceType.getName()));
                ilGen.Emit(OpCodes.Ldloc, local_anyParams);
                ilGen.Emit(OpCodes.Ldarg_0);
                MethodInfo methodCIWAAC =
                    local_factory.LocalType.GetMethod(
                        "createInstanceWithArgumentsAndContext");
                ilGen.Emit(OpCodes.Callvirt, methodCIWAAC);
            }

            // cast the object returned by the functions
            // createInstanceWithContext or
            // createInstanceWithArgumentsAndContext to the interface type
            ilGen.Emit(OpCodes.Castclass, retType);
            ilGen.Emit(OpCodes.Stloc, local_return_val);

            // catch exceptions thrown by createInstanceWithArgumentsAndContext
            // and createInstanceWithContext
            if (!exceptionTypes.Contains(type_uno_exception))
            {
                // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;}
                ilGen.BeginCatchBlock(
                    get_type(
                        "unoidl.com.sun.star.uno.RuntimeException", true));
                ilGen.Emit(OpCodes.Pop);
                ilGen.Emit(OpCodes.Rethrow);

                // catch and rethrow all other defined Exceptions
                foreach (Type excType in exceptionTypes)
                {
                    if (excType.IsInstanceOfType(
                            get_type(
                                "unoidl.com.sun.star.uno.RuntimeException",
                                true)))
                    {
                        // we have a catch for RuntimeException already defined
                        continue;
                    }

                    // catch Exception and rethrow
                    ilGen.BeginCatchBlock(excType);
                    ilGen.Emit(OpCodes.Pop);
                    ilGen.Emit(OpCodes.Rethrow);
                }

                // catch (unoidl.com.sun.star.uno.Exception)
                // { throw DeploymentException... }
                ilGen.BeginCatchBlock(type_uno_exception);

                // define the local variable that keeps the exception
                LocalBuilder local_exception = ilGen.DeclareLocal(
                    type_uno_exception);

                // Store the exception
                ilGen.Emit(OpCodes.Stloc, local_exception);

                // prepare the construction of the exception
                ilGen.Emit(OpCodes.Ldstr,
                           "The context (com.sun.star.uno.XComponentContext)" +
                           "failed to supply the service " +
                           to_cts_name(xServiceType.getName()) +
                           ": ");

                // add to the string the Exception.Message
                ilGen.Emit(OpCodes.Ldloc, local_exception);
                ilGen.Emit(OpCodes.Callvirt,
                           type_uno_exception.GetProperty("Message")
                           .GetGetMethod());
                Type[] concatParams = new Type[] { typeof(System.String),
                                                   typeof(System.String) };
                ilGen.Emit(OpCodes.Call,
                           typeof(System.String).GetMethod("Concat",
                                                           concatParams));
                // load context argument
                ilGen.Emit(OpCodes.Ldarg_0);
                ilGen.Emit(OpCodes.Newobj, ctorDeploymentException);
                ilGen.Emit(OpCodes.Throw); // Exception(typeDeploymentExc);

                ilGen.EndExceptionBlock();
            }

            // Check if the service instance was create and throw an
            // exception if not.
            Label label_service_created = ilGen.DefineLabel();
            ilGen.Emit(OpCodes.Ldloc, local_return_val);
            ilGen.Emit(OpCodes.Brtrue_S, label_service_created);

            ilGen.Emit(OpCodes.Ldstr,
                       "The context (com.sun.star.uno.XComponentContext)" +
                       "failed to supply the service unoidl." +
                       to_cts_name(xServiceType.getName()) +
                       ".");
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Newobj, ctorDeploymentException);
            ilGen.Emit(OpCodes.Throw); // Exception(typeDeploymentExc);

            ilGen.MarkLabel(label_service_created);
            ilGen.Emit(OpCodes.Ldloc, local_return_val);
            ilGen.Emit(OpCodes.Ret);
        }

        // remove from incomplete types map
        m_incomplete_services.Remove(type_builder.FullName);

        if (Climaker.g_verbose)
        {
            Console.WriteLine("> emitting service type {0}",
                              type_builder.FullName);
        }

        return type_builder.CreateType();
    }
Beispiel #13
0
        void EmitProtoFull(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label onLabel   = ilg.DefineLabel();
            Label callLabel = ilg.DefineLabel();
            Label endLabel  = ilg.DefineLabel();

            Var v = ((VarExpr)_fexpr).Var;

            Expr e = (Expr)_args.nth(0);

            e.Emit(RHC.Expression, objx, ilg);               // target
            ilg.Emit(OpCodes.Dup);                           // target, target

            LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object));

            GenContext.SetLocalName(targetTemp, "target");
            ilg.Emit(OpCodes.Stloc, targetTemp);                  // target

            ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class
            ilg.EmitLoadArg(0);                                   // class, this
            ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex));   // class, cached-class
            ilg.Emit(OpCodes.Beq, callLabel);                     //
            if (_protocolOn != null)
            {
                ilg.Emit(OpCodes.Ldloc, targetTemp);             // target
                ilg.Emit(OpCodes.Isinst, _protocolOn);           // null or target
                ilg.Emit(OpCodes.Ldnull);                        // (null or target), null
                ilg.Emit(OpCodes.Cgt_Un);                        // (0 or 1)
                ilg.Emit(OpCodes.Brtrue, onLabel);
            }
            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // target
            ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class

            LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type));

            GenContext.SetLocalName(typeTemp, "type");
            ilg.Emit(OpCodes.Stloc, typeTemp);                   //    (typeType <= class)

            ilg.EmitLoadArg(0);                                  // this

            ilg.Emit(OpCodes.Ldloc, typeTemp);                   // this, class
            ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex));  //

            ilg.MarkLabel(callLabel);

            objx.EmitVar(ilg, v);                                   // var
            ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot); // proto-fn
            ilg.Emit(OpCodes.Castclass, typeof(AFunction));

            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // proto-fn, target

            EmitArgsAndCall(1, rhc, objx, ilg);
            ilg.Emit(OpCodes.Br, endLabel);

            ilg.MarkLabel(onLabel);
            ilg.Emit(OpCodes.Ldloc, targetTemp);                  // target
            if (_protocolOn != null)
            {
                ilg.Emit(OpCodes.Castclass, _protocolOn);
                MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count()));
                //if (rhc == RHC.Return)
                //{
                //    ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref();
                //    method.EmitClearLocals(context);
                //}
                ilg.Emit(OpCodes.Callvirt, _onMethod);
                HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType);
            }
            ilg.MarkLabel(endLabel);
        }
Beispiel #14
0
 public abstract void PlantTree(IDefinitionManager definitionManager, IPlanet planet, Index3 index, LocalBuilder builder, int seed);
Beispiel #15
0
    static void EmitOutParamPrep(ILGenerator ilg, LocalBuilder bufLocal,
                                 TypeInfo.TypeDescriptor type, int argnum)
    {
        ilg.Emit(OpCodes.Nop);
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, 1); // PTR_IS_DATA
        ilg.Emit(OpCodes.Stind_I1);

        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8); // offsetof(ptr)
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 0); // offsetof(val)
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Stind_I4); /* XXX 64-bitness! */
    }
Beispiel #16
0
 static void EmitTypeStore(ILGenerator ilg, LocalBuilder bufLocal,
                           TypeInfo.TypeDescriptor t, int argnum)
 {
     ilg.Emit(OpCodes.Ldloc, bufLocal);
     ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 12);
     ilg.Emit(OpCodes.Add);
     ilg.Emit(OpCodes.Ldc_I4, (Int32)t.tag);
     ilg.Emit(OpCodes.Stind_I4);
 }
Beispiel #17
0
        internal void Emit(OpCode opcode, LocalBuilder local)
        {
            _ilg.Emit(opcode, local);
            int tempVal = local.LocalIndex;

            if (opcode.Equals(OpCodes.Ldloc))
            {
                switch (tempVal)
                {
                case 0:
                    opcode = OpCodes.Ldloc_0;
                    break;

                case 1:
                    opcode = OpCodes.Ldloc_1;
                    break;

                case 2:
                    opcode = OpCodes.Ldloc_2;
                    break;

                case 3:
                    opcode = OpCodes.Ldloc_3;
                    break;

                default:
                    if (tempVal <= 255)
                    {
                        opcode = OpCodes.Ldloc_S;
                    }
                    break;
                }
            }
            else if (opcode.Equals(OpCodes.Stloc))
            {
                switch (tempVal)
                {
                case 0:
                    opcode = OpCodes.Stloc_0;
                    break;

                case 1:
                    opcode = OpCodes.Stloc_1;
                    break;

                case 2:
                    opcode = OpCodes.Stloc_2;
                    break;

                case 3:
                    opcode = OpCodes.Stloc_3;
                    break;

                default:
                    if (tempVal <= 255)
                    {
                        opcode = OpCodes.Stloc_S;
                    }
                    break;
                }
            }
            else if (opcode.Equals(OpCodes.Ldloca))
            {
                if (tempVal <= 255)
                {
                    opcode = OpCodes.Ldloca_S;
                }
            }

            AdvanceOffset(opcode);

            if (opcode.OperandType == OperandType.InlineNone)
            {
                return;
            }
            else if (!OpCodes.TakesSingleByteArgument(opcode))
            {
                _offset += 2;
            }
            else
            {
                _offset++;
            }
            AssertOffsetMatches();
        }
Beispiel #18
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="name">Local object name</param>
 /// <param name="localType">Local type</param>
 public DefineLocal(string name, Type localType)
 {
     Result = new LocalBuilder(MethodBase.CurrentMethod, name, localType);
 }
Beispiel #19
0
 public VarInfo(LocalBuilder lb)
 {
     _lb   = lb;
     _kind = VarKind.vkLocal;
 }
 public virtual void EmitWriteLine(LocalBuilder localBuilder);
Beispiel #21
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            List <CodeInstruction> newInstructions = ListPool <CodeInstruction> .Shared.Rent(instructions);

            int offset = 0;
            int index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldarg_2) + offset;

            Label returnLabel   = generator.DefineLabel();
            Label setMaxHpLabel = generator.DefineLabel();
            Label rpcLabel      = generator.DefineLabel();

            newInstructions[newInstructions.Count - 1].labels.Add(returnLabel);

            LocalBuilder ev = generator.DeclareLocal(typeof(InteractingShootingTargetEventArgs));

            newInstructions.InsertRange(index, new[]
            {
                // Player.Get(ReferenceHub)
                new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]),
                new CodeInstruction(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),

                // this
                new CodeInstruction(OpCodes.Ldarg_0),

                // colliderId (ShootingTargetButton)
                new CodeInstruction(OpCodes.Ldarg_2),

                // GetNextValue(buttonPressed, ShootingTargetButton.DecreaseHp, BaseTarget._maxHp)
                new CodeInstruction(OpCodes.Ldarg_2),
                new CodeInstruction(OpCodes.Ldc_I4_1),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, Field(typeof(BaseTarget), nameof(BaseTarget._maxHp))),
                new CodeInstruction(OpCodes.Call, Method(typeof(InteractingShootingTarget), nameof(InteractingShootingTarget.GetNextValue))),

                // GetNextValue(buttonPressed, ShootingTargetButton.DecreaseResetTime, BaseTarget._autoDestroyTime)
                new CodeInstruction(OpCodes.Ldarg_2),
                new CodeInstruction(OpCodes.Ldc_I4_3),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, Field(typeof(BaseTarget), nameof(BaseTarget._autoDestroyTime))),
                new CodeInstruction(OpCodes.Call, Method(typeof(InteractingShootingTarget), nameof(InteractingShootingTarget.GetNextValue))),

                // true
                new CodeInstruction(OpCodes.Ldc_I4_1),

                // var ev = new InteractingShootingTargetEventArgs(Player, BaseTarget, ShootingTargetButton, MaxHp, ResetTime, true)
                new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingShootingTargetEventArgs))[0]),
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Dup),
                new CodeInstruction(OpCodes.Stloc_S, ev.LocalIndex),

                // OnInteractingShootingTarget(ev)
                new CodeInstruction(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingShootingTarget))),

                // if (!ev.IsAllowed)
                //   CheckMaxHp
                new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingShootingTargetEventArgs), nameof(InteractingShootingTargetEventArgs.IsAllowed))),
                new CodeInstruction(OpCodes.Brfalse, setMaxHpLabel),
            });

            offset = 1;
            index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Call && (MethodInfo)i.operand == Method(typeof(NetworkServer), nameof(NetworkServer.Destroy))) + offset;
            newInstructions[index] = new CodeInstruction(OpCodes.Br, setMaxHpLabel);

            offset = 1;
            index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Call && (MethodInfo)i.operand == Method(typeof(BaseTarget), "set_Network_syncMode")) + offset;
            newInstructions[index] = new CodeInstruction(OpCodes.Br, setMaxHpLabel);

            offset = -5;
            index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Call && (MethodInfo)i.operand == Method(typeof(BaseTarget), nameof(BaseTarget.RpcSendInfo))) + offset;

            newInstructions[index].labels.Add(rpcLabel);

            newInstructions.InsertRange(index, new[]
            {
                // BaseTarget.MaxHp = ev.NewMaxHp
                new CodeInstruction(OpCodes.Ldarg_0).WithLabels(setMaxHpLabel),
                new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex),
                new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingShootingTargetEventArgs), nameof(InteractingShootingTargetEventArgs.NewMaxHp))),
                new CodeInstruction(OpCodes.Stfld, Field(typeof(BaseTarget), nameof(BaseTarget._maxHp))),

                // BaseTarget._autoDestroyTime = ev.NewAutoResetTime
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex),
                new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingShootingTargetEventArgs), nameof(InteractingShootingTargetEventArgs.NewAutoResetTime))),
                new CodeInstruction(OpCodes.Stfld, Field(typeof(BaseTarget), nameof(BaseTarget._autoDestroyTime))),
            });

            for (int z = 0; z < newInstructions.Count; z++)
            {
                yield return(newInstructions[z]);
            }

            ListPool <CodeInstruction> .Shared.Return(newInstructions);
        }
Beispiel #22
0
 static void EmitPrepareArgStore(ILGenerator ilg, LocalBuilder bufLocal,
                                 int argnum)
 {
     EmitComputeBufferLoc(ilg, bufLocal, argnum);
     EmitLoadArg(ilg, argnum);
 }
Beispiel #23
0
		public virtual void EmitWriteLine (LocalBuilder localBuilder)
		{
			throw new PlatformNotSupportedException ();
		}
Beispiel #24
0
 internal FieldNullable(LocalBuilder stack, ILGenerator generator) : base(ToNullable(stack, generator), generator)
 {
     ValueInfo             = typeof(Nullable <T>).GetProperty("Value").GetGetMethod();
     HasValueInfo          = typeof(Nullable <T>).GetProperty("HasValue").GetGetMethod();
     GetValueOrDefaultInfo = typeof(Nullable <T>).GetMethod("GetValueOrDefault", Type.EmptyTypes);
 }
Beispiel #25
0
		internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen)
		{
			Debug.Assert(Name != null);
			if(Name == ".ctor")
			{
				Debug.Assert(Class == null && type != null);
				Type[] argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
				ConstructorInfo ci = StaticCompiler.GetType(context.ClassLoader, type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null);
				if(ci == null)
				{
					throw new InvalidOperationException("Missing .ctor: " + type + "..ctor" + Sig);
				}
				ilgen.Emit(opcode, ci);
			}
			else
			{
				Debug.Assert(Class == null ^ type == null);
				if(Class != null)
				{
					Debug.Assert(Sig != null);
					MethodWrapper method = context.ClassLoader.LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false);
					if(method == null)
					{
						throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
					}
					method.Link();
					// TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does,
					// it would be nice if we could avoid this duplication...
					TypeWrapper[] argTypeWrappers = method.GetParameters();
					for(int i = 0; i < argTypeWrappers.Length; i++)
					{
						if(argTypeWrappers[i].IsGhost)
						{
							LocalBuilder[] temps = new LocalBuilder[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)];
							for(int j = temps.Length - 1; j >= 0; j--)
							{
								TypeWrapper tw;
								if(method.IsStatic)
								{
									tw = argTypeWrappers[j];
								}
								else
								{
									if(j == 0)
									{
										tw = method.DeclaringType;
									}
									else
									{
										tw = argTypeWrappers[j - 1];
									}
								}
								if(tw.IsGhost)
								{
									tw.EmitConvStackTypeToSignatureType(ilgen, null);
								}
								temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType);
								ilgen.Emit(OpCodes.Stloc, temps[j]);
							}
							for(int j = 0; j < temps.Length; j++)
							{
								ilgen.Emit(OpCodes.Ldloc, temps[j]);
							}
							break;
						}
					}
					if(opcode.Value == OpCodes.Call.Value)
					{
						method.EmitCall(ilgen);
					}
					else if(opcode.Value == OpCodes.Callvirt.Value)
					{
						method.EmitCallvirt(ilgen);
					}
					else if(opcode.Value == OpCodes.Newobj.Value)
					{
						method.EmitNewobj(ilgen);
					}
					else
					{
						throw new InvalidOperationException();
					}
				}
				else
				{
					Type[] argTypes;
					if(Sig.StartsWith("("))
					{
						argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
					}
					else
					{
						string[] types = Sig.Split(';');
						argTypes = new Type[types.Length];
						for(int i = 0; i < types.Length; i++)
						{
							argTypes[i] = StaticCompiler.GetType(context.ClassLoader, types[i]);
						}
					}
					MethodInfo mi = StaticCompiler.GetType(context.ClassLoader, type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null);
					if(mi == null)
					{
						throw new InvalidOperationException("Missing method: " + type + "." + Name + Sig);
					}
					ilgen.Emit(opcode, mi);
				}
			}
		}
Beispiel #26
0
        private static DynamicMethod CreateClassDeserializerDynamicMethod(Type type, IDataReader reader, IRecordStructure structure, int startColumn, int columnCount, bool createNewObject, bool isRootObject, bool allowBindChild, bool checkForAllDbNull)
        {
            // if there are no columns detected for the class, then don't deserialize it
            // exception: a parentandchild object in the middle of a child hierarchy
            var genericType = type.GetTypeInfo().IsGenericType ? type.GetGenericTypeDefinition() : null;

            if (columnCount == 0 && !isRootObject && genericType != typeof(ParentAndChild <,>))
            {
                return(null);
            }

            var mappings = MapColumns(type, reader, startColumn, columnCount, structure, allowBindChild && isRootObject);

            // need to know the constructor for the object (except for structs)
            bool            isStruct    = type.GetTypeInfo().IsValueType;
            ConstructorInfo constructor = createNewObject ? SelectConstructor(type) : null;

            // if there is a constructor, determine which columns will be mapped to constructor parameters
            // constructorMappings will be indexes into the mappin array (or -1 if there is no mapping)
            var constructorParameters = (constructor != null) ? constructor.GetParameters() : null;
            var constructorMappings   = (constructor != null) ? constructorParameters.Select(p => mappings.FindIndex(m => m != null && p.Name.IsIEqualTo(m.Member.Name))).ToArray() : new int[0];

            // remove any mappings that are not settable and not used for constructor initialization
            // this will save on translating properties we can't set and prevent issue #459
            for (var m = 0; m < mappings.Count; m++)
            {
                if (mappings[m] != null && !mappings[m].Member.CanSetMember && !constructorMappings.Contains(m))
                {
                    mappings[m] = null;
                }
            }

            // the method can either be:
            // createNewObject => Func<IDataReader, T>
            // !createNewObject => Func<IDataReader, T, T>
            // create a new anonymous method that takes an IDataReader and returns the given type
            var dm = new DynamicMethod(
                String.Format(CultureInfo.InvariantCulture, "Deserialize-{0}-{1}", type.FullName, Guid.NewGuid()),
                type,
                createNewObject ? new[] { typeof(IDataReader) } : new[] { typeof(IDataReader), type },
                true);

            // get the il generator and put some local variables on the stack
            var il                  = dm.GetILGenerator();
            var localIndex          = il.DeclareLocal(typeof(int));
            var localResult         = il.DeclareLocal(type);
            var localValue          = il.DeclareLocal(typeof(object));
            var localIsNotAllDbNull = il.DeclareLocal(typeof(bool));

            // initialization
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Stloc, localIndex);

            /////////////////////////////////////////////////////////////////////
            // read all of the values into local variables
            /////////////////////////////////////////////////////////////////////
            il.BeginExceptionBlock();
            var hasAtLeastOneMapping = false;
            var localValues          = new LocalBuilder[mappings.Count];

            for (int index = 0; index < columnCount; index++)
            {
                var mapping = mappings[index];
                if (mapping == null)
                {
                    continue;
                }
                hasAtLeastOneMapping = true;

                var member = mapping.Member;

                localValues[index] = il.DeclareLocal(member.MemberType);

                // need to call IDataReader.GetItem to get the value of the field
                il.Emit(OpCodes.Ldarg_0);
                IlHelper.EmitLdInt32(il, index + startColumn);

                // before we call it, put the current index into the index local variable
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Stloc, localIndex);

                // now call it
                il.Emit(OpCodes.Callvirt, _iDataReaderGetItem);

                // if handling a subobject, we check to see if the value is null
                if (startColumn > 0)
                {
                    var afterNullCheck = il.DefineLabel();
                    il.Emit(OpCodes.Dup);
                    il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value"));
                    il.Emit(OpCodes.Ceq);
                    il.Emit(OpCodes.Brtrue, afterNullCheck);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.Emit(OpCodes.Stloc, localIsNotAllDbNull);
                    il.MarkLabel(afterNullCheck);
                }

                // store the value as a local variable in case type conversion fails
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Stloc, localValue);

                // convert the value and store it locally
                Type sourceType = reader.GetFieldType(index + startColumn);
                TypeConverterGenerator.EmitConvertValue(il, member.Name, sourceType, member.MemberType, mapping.Serializer);
                il.Emit(OpCodes.Stloc, localValues[index]);
            }

            /////////////////////////////////////////////////////////////////////
            // catch translation exceptions and rethrow
            /////////////////////////////////////////////////////////////////////
            il.BeginCatchBlock(typeof(Exception));                                              // stack => [Exception]
            il.Emit(OpCodes.Ldloc, localIndex);                                                 // push loc.0, stack => [Exception][index]
            il.Emit(OpCodes.Ldarg_0);                                                           // push arg.0, stack => [Exception][index][reader]
            il.Emit(OpCodes.Ldloc, localValue);                                                 // push loc.3, stack => [Exception][index][reader][value]
            il.Emit(OpCodes.Call, TypeConverterGenerator.CreateDataExceptionMethod);
            il.Emit(OpCodes.Throw);                                                             // stack => DataException
            il.EndExceptionBlock();

            /////////////////////////////////////////////////////////////////////
            // if this was a subobject and all of the values are null, then return the default for the object
            /////////////////////////////////////////////////////////////////////
            if (hasAtLeastOneMapping && checkForAllDbNull)
            {
                var afterNullExit = il.DefineLabel();
                il.Emit(OpCodes.Ldloc, localIsNotAllDbNull);
                il.Emit(OpCodes.Brtrue, afterNullExit);
                TypeHelper.EmitDefaultValue(il, type);
                il.Emit(OpCodes.Ret);
                il.MarkLabel(afterNullExit);
            }

            /////////////////////////////////////////////////////////////////////
            // call the constructor
            /////////////////////////////////////////////////////////////////////
            if (createNewObject)
            {
                if (isStruct)
                {
                    il.Emit(OpCodes.Ldloca_S, localResult);
                    il.Emit(OpCodes.Initobj, type);
                    if (constructor != null)
                    {
                        il.Emit(OpCodes.Ldloca_S, localResult);
                    }
                }

                // if there is a constructor, then populate the values from the pre-converted local values we created above
                if (constructor != null)
                {
                    for (var p = 0; p < constructorParameters.Length; p++)
                    {
                        if (constructorMappings[p] >= 0)
                        {
                            il.Emit(OpCodes.Ldloc, localValues[constructorMappings[p]]);
                        }
                        else
                        {
                            TypeHelper.EmitDefaultValue(il, constructorParameters[p].ParameterType);
                        }
                    }
                }

                if (isStruct)
                {
                    if (constructor != null)
                    {
                        il.Emit(OpCodes.Call, constructor);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Newobj, constructor);
                    il.Emit(OpCodes.Stloc, localResult);
                }
            }
            else
            {
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Stloc, localResult);
            }

            /////////////////////////////////////////////////////////////////////
            // for anything not passed to the constructor, copy the local values to the properties
            /////////////////////////////////////////////////////////////////////
            for (int index = 0; index < columnCount; index++)
            {
                var mapping = mappings[index];
                if (mapping == null)
                {
                    continue;
                }

                // don't attempt to set values that can't be set at all
                var member = mapping.Member;
                if (!member.CanSetMember)
                {
                    continue;
                }

                // don't set values that have already been set in the constructor
                if (constructorMappings.Contains(index))
                {
                    continue;
                }

                // load the address of the object we are working on
                if (isStruct)
                {
                    il.Emit(OpCodes.Ldloca_S, localResult);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, localResult);
                }

                // for deep mappings, go to the parent of the field that we are trying to set
                var nextLabel = il.DefineLabel();
                if (mapping.IsDeep)
                {
                    ClassPropInfo.EmitGetValue(type, mapping.Prefix, il);

                    // if the mapping parent is nullable, check to see if it is null.
                    // if so, pop the parent off the stack and move to the next field
                    if (!ClassPropInfo.FindMember(type, mapping.Prefix).MemberType.GetTypeInfo().IsValueType)
                    {
                        var notNullLabel = il.DefineLabel();
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brtrue, notNullLabel);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Br, nextLabel);
                        il.MarkLabel(notNullLabel);
                    }
                }

                // load the value from the local and set it on the object
                il.Emit(OpCodes.Ldloc, localValues[index]);
                member.EmitSetValue(il);
                il.MarkLabel(nextLabel);

                /////////////////////////////////////////////////////////////////////
                // stack should be [target] and ready for the next column
                /////////////////////////////////////////////////////////////////////
            }

            /////////////////////////////////////////////////////////////////////
            // load the return value from the local variable
            /////////////////////////////////////////////////////////////////////
            il.Emit(OpCodes.Ldloc, localResult);                                                        // ld loc.1 (target), stack => [target]
            il.Emit(OpCodes.Ret);

            // create the function
            return(dm);
        }
Beispiel #27
0
 static void EmitLoadReturnSlot_1(ILGenerator ilg, LocalBuilder bufLocal,
                                  int slotnum)
 {
     ilg.Emit(OpCodes.Ldloc, bufLocal);
     ilg.Emit(OpCodes.Ldc_I4, (slotnum - 1) * VARIANT_SIZE);
     ilg.Emit(OpCodes.Add);
     ilg.Emit(OpCodes.Ldind_I4);
 }
Beispiel #28
0
            /// <summary>
            /// 创建 TCP 客户端
            /// </summary>
            /// <param name="type"></param>
            /// <param name="attribute"></param>
            /// <param name="methods"></param>
            /// <param name="getCommandMethod"></param>
            /// <returns></returns>
            internal Type Build(Type type, ServerBaseAttribute attribute, Method <attributeType, methodAttributeType, serverSocketSenderType>[] methods, MethodInfo getCommandMethod)
            {
                TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ClientTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.MethodClientType, new Type[] { type });

                typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

                ConstructorBuilder staticConstructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null);
                ILGenerator        staticConstructorGenerator = staticConstructorBuilder.GetILGenerator();

                Commands = new CommandInfo[methods.Length];
                int parameterIndex;

                foreach (Method <attributeType, methodAttributeType, serverSocketSenderType> nextMethod in methods)
                {
                    if (nextMethod != null)
                    {
                        Method <attributeType, methodAttributeType, serverSocketSenderType> method = nextMethod;
METHOD:
                        FieldBuilder commandInfoFieldBuilder;
                        if (method.Attribute.IsExpired)
                        {
                            commandInfoFieldBuilder = null;
                        }
                        else
                        {
                            commandInfoFieldBuilder = typeBuilder.DefineField("_c" + method.Attribute.CommandIdentity.toString(), typeof(CommandInfo), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);
                            CommandInfo commandInfo = new CommandInfo {
                                Command = method.Attribute.CommandIdentity + TcpServer.Server.CommandStartIndex, TaskType = method.IsAsynchronousCallback ? method.Attribute.ClientTaskType : AutoCSer.Net.TcpServer.ClientTaskType.Synchronous, IsVerifyMethod = method.Attribute.IsVerifyMethod
                            };
                            Commands[method.Attribute.CommandIdentity] = commandInfo;
                            if (method.IsClientSendOnly)
                            {
                                commandInfo.IsSendOnly = 1;
                            }
                            if (method.IsJsonSerialize)
                            {
                                commandInfo.CommandFlags = CommandFlags.JsonSerialize;
                            }
                            if (method.ParameterType != null)
                            {
                                commandInfo.InputParameterIndex = method.ParameterType.Index;
                                if (attribute.IsSimpleSerialize)
                                {
                                    commandInfo.IsSimpleSerializeInputParamter = method.ParameterType.IsSimpleSerialize;
                                }
                            }
                            if (attribute.IsSimpleSerialize && method.OutputParameterType != null)
                            {
                                commandInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType);
                            }
                            #region private static readonly AutoCSer.Net.TcpServer.CommandInfo @MethodIdentityCommand = AutoCSer.Net.TcpInternalServer.Emit.Client<interfaceType>.commands[method.Attribute.CommandIdentity];
                            staticConstructorGenerator.int32(method.Attribute.CommandIdentity);
                            staticConstructorGenerator.call(getCommandMethod);
                            staticConstructorGenerator.Emit(OpCodes.Stsfld, commandInfoFieldBuilder);
                            #endregion
                        }
                        if (method.PropertyInfo == null)
                        {
                            ParameterInfo[] parameters    = method.MethodInfo.GetParameters();
                            MethodBuilder   methodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType));
                            typeBuilder.DefineMethodOverride(methodBuilder, method.MethodInfo);
                            ILGenerator methodGenerator = methodBuilder.GetILGenerator();
                            if (method.Attribute.IsExpired)
                            {
                                if (method.ReturnValueType == null)
                                {
                                    #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString());
                                    methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString());
                                    #endregion
                                }
                                else
                                {
                                    #region @ParameterName = default(@ParameterType.FullName);
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.IsOut)
                                        {
                                            methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj);
                                        }
                                    }
                                    #endregion
                                    #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.VersionExpired };
                                    LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                    if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj()))
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                    methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                    methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                    methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Ret);
                                    #endregion
                                }
                            }
                            else if (method.IsClientSendOnly)
                            {
                                LocalBuilder inputParameterLocalBuilder;
                                if (method.ParameterType == null)
                                {
                                    inputParameterLocalBuilder = null;
                                }
                                else
                                {
                                    #region TcpInternalServer.@InputParameterTypeName _inputParameter_ = new TcpInternalServer.@InputParameterTypeName { @ParameterName = @ParameterName };
                                    inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type);
                                    }
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (StreamParameterType.IsInputParameter(parameter))
                                        {
                                            methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name));
                                        }
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder);
                                    #endregion
                                }
                                #region _TcpClient_.Sender.CallOnly(@MethodIdentityCommand, ref _inputParameter_);
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.call(Metadata.MethodClientGetTcpClientMethod);
                                methodGenerator.call(Metadata.ClientGetSenderMethod);
                                methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder);
                                if (method.ParameterType == null)
                                {
                                    methodGenerator.call(Metadata.ClientSocketSenderCallOnlyMethod);
                                }
                                else
                                {
                                    methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder);
                                    methodGenerator.call(Metadata.ClientSocketSenderCallOnlyInputMethod.MakeGenericMethod(method.ParameterType.Type));
                                }
                                #endregion
                                methodGenerator.Emit(OpCodes.Ret);
                            }
                            else
                            {
                                Label        clientExceptionLabel = methodGenerator.DefineLabel(), returnLable = methodGenerator.DefineLabel(), returnReturnValueLable, returnValueLable;
                                LocalBuilder returnReturnValueLocalBuilder, returnValueLocalBuilder;
                                if (method.ReturnValueType == null)
                                {
                                    returnReturnValueLocalBuilder = null;
                                    returnReturnValueLable        = default(Label);
                                }
                                else
                                {
                                    returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType);
                                    returnReturnValueLable        = methodGenerator.DefineLabel();
                                }
                                if (method.ReturnValueType == null && method.ReturnType != typeof(void))
                                {
                                    returnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnType);
                                    returnValueLable        = methodGenerator.DefineLabel();
                                }
                                else
                                {
                                    returnValueLocalBuilder = null;
                                    returnValueLable        = default(Label);
                                }
                                #region AutoCSer.Net.TcpServer.AutoWaitReturnValue<TcpInternalServer.@OutputParameterTypeName> _wait_ = _TcpClient_.GetAutoWait<TcpInternalServer.@OutputParameterTypeName>();
                                Type         waitType         = method.OutputParameterType == null ? typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue) : typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue <>).MakeGenericType(method.OutputParameterType.Type);
                                LocalBuilder waitLocalBuilder = methodGenerator.DeclareLocal(waitType);
                                methodGenerator.call(method.OutputParameterType == null ? TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePopMethod : waitType.GetMethod("Pop", BindingFlags.Static | BindingFlags.Public));
                                methodGenerator.Emit(OpCodes.Stloc_S, waitLocalBuilder);
                                #endregion
                                #region try
                                methodGenerator.BeginExceptionBlock();
                                #endregion
                                Label        leaveTryLabel      = methodGenerator.DefineLabel();
                                LocalBuilder senderLocalBuilder = methodGenerator.DeclareLocal(Metadata.SenderType);
                                parameterIndex = 0;
                                if (method.Attribute.IsVerifyMethod)
                                {
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.ParameterType == Metadata.SenderType)
                                        {
                                            #region AutoCSer.Net.TcpInternalServer.ClientSocketSender _socket_ = _sender_;
                                            methodGenerator.ldarg(parameterIndex);
                                            methodGenerator.Emit(OpCodes.Stloc_S, senderLocalBuilder);
                                            #endregion
                                            parameterIndex = int.MinValue;
                                            break;
                                        }
                                    }
                                }
                                if (parameterIndex != int.MinValue)
                                {
                                    #region AutoCSer.Net.TcpInternalServer.ClientSocketSender _socket_ = _TcpClient_.Sender;
                                    methodGenerator.Emit(OpCodes.Ldarg_0);
                                    methodGenerator.call(Metadata.MethodClientGetTcpClientMethod);
                                    methodGenerator.call(Metadata.ClientGetSenderMethod);
                                    methodGenerator.Emit(OpCodes.Stloc_S, senderLocalBuilder);
                                    #endregion
                                }
                                #region if (_socket_ != null)
                                methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder);
                                methodGenerator.Emit(method.ParameterType == null ? OpCodes.Brfalse_S : OpCodes.Brfalse, leaveTryLabel);
                                #endregion
                                LocalBuilder inputParameterLocalBuilder;
                                if (method.ParameterType == null)
                                {
                                    inputParameterLocalBuilder = null;
                                }
                                else
                                {
                                    #region TcpInternalServer.@InputParameterTypeName _inputParameter_ = new TcpInternalServer.@InputParameterTypeName { @ParameterName = @ParameterName };
                                    inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type);
                                    }
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (StreamParameterType.IsInputParameter(parameter))
                                        {
                                            methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name));
                                        }
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder);
                                    #endregion
                                }
                                if (method.OutputParameterType == null)
                                {
                                    #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _socket_.WaitCall(@MethodIdentityCommand, ref _wait_, ref _inputParameter_);
                                    LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                                    methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder);
                                    methodGenerator.Emit(OpCodes.Ldloca_S, waitLocalBuilder);
                                    if (method.ParameterType == null)
                                    {
                                        methodGenerator.call(Metadata.ClientSocketSenderWaitCallMethod);
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder);
                                        methodGenerator.call(Metadata.ClientSocketSenderWaitCallInputMethod.MakeGenericMethod(method.ParameterType.Type));
                                    }
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                    #endregion
                                    if (method.ReturnValueType == null)
                                    {
                                        Label throwReturnTypeLabel = methodGenerator.DefineLabel();
                                        #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) return;
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un_S, throwReturnTypeLabel);
                                        methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                                        #endregion
                                        methodGenerator.MarkLabel(throwReturnTypeLabel);
                                        #region throw new Exception(AutoCSer.Net.TcpInternalServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]);
                                        methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldelem_Ref);
                                        methodGenerator.Emit(OpCodes.Newobj, AutoCSer.Extension.EmitGenerator.StringExceptionConstructor);
                                        methodGenerator.Emit(OpCodes.Throw);
                                        #endregion
                                    }
                                    else
                                    {
                                        #region return new AutoCSer.Net.TcpServer.ReturnValue { Type = _returnType_ };
                                        //methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        //methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField);
                                        methodGenerator.Emit(OpCodes.Leave, returnReturnValueLable);
                                        #endregion
                                    }
                                }
                                else
                                {
                                    #region TcpInternalServer.@OutputParameterTypeName _outputParameter_ = new TcpInternalServer.@OutputParameterTypeName { @ParameterName = @ParameterName };
                                    LocalBuilder outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type);
                                    }
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.ParameterType.IsByRef)
                                        {
                                            methodGenerator.parameterToStructField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                        }
                                    }
                                    //if (method.ReturnInputParameter != null)
                                    //{
                                    //}
                                    #endregion
                                    #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _socket_.WaitGet<TcpInternalServer.@InputParameterTypeName, TcpInternalServer.@OutputParameterTypeName>(@MethodIdentityCommand, ref _wait_, ref _inputParameter_, ref _outputParameter_);
                                    LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                                    methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder);
                                    methodGenerator.Emit(OpCodes.Ldloca_S, waitLocalBuilder);
                                    if (method.ParameterType == null)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.call(Metadata.ClientSocketSenderWaitGetMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.call(Metadata.ClientSocketSenderWaitGetInputMethod.MakeGenericMethod(method.ParameterType.Type, method.OutputParameterType.Type));
                                    }
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                    #endregion
                                    if (method.ReturnValueType == null)
                                    {
                                        Label throwReturnTypeLabel = methodGenerator.DefineLabel();
                                        #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success)
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un, throwReturnTypeLabel);
                                        #endregion
                                        #region @ParameterName = _outputParameter_.@ParameterName;
                                        parameterIndex = 0;
                                        foreach (ParameterInfo parameter in parameters)
                                        {
                                            ++parameterIndex;
                                            if (parameter.ParameterType.IsByRef)
                                            {
                                                methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                            }
                                        }
                                        #endregion
                                        if (method.ReturnType == typeof(void))
                                        {
                                            #region return;
                                            methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                                            #endregion
                                        }
                                        else
                                        {
                                            #region return _outputParameter_.Ret;
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                            methodGenerator.Emit(OpCodes.Stloc_S, returnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Leave_S, returnValueLable);
                                            #endregion
                                        }
                                        methodGenerator.MarkLabel(throwReturnTypeLabel);
                                        #region throw new Exception(AutoCSer.Net.TcpServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]);
                                        methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldelem_Ref);
                                        methodGenerator.Emit(OpCodes.Newobj, AutoCSer.Extension.EmitGenerator.StringExceptionConstructor);
                                        methodGenerator.Emit(OpCodes.Throw);
                                        #endregion
                                    }
                                    else
                                    {
                                        #region @ParameterName = _outputParameter_.@ParameterName;
                                        parameterIndex = 0;
                                        foreach (ParameterInfo parameter in parameters)
                                        {
                                            ++parameterIndex;
                                            if (parameter.ParameterType.IsByRef)
                                            {
                                                methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name));
                                            }
                                        }
                                        #endregion
                                        #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = _returnType_, Value = _outputParameter_.Return };
                                        if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj()))
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                        }
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                        if (method.ReturnType != typeof(void))
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(ReturnValue.RetParameterName));
                                            methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public));
                                        }
                                        methodGenerator.Emit(OpCodes.Leave, returnReturnValueLable);
                                        #endregion
                                    }
                                }
                                methodGenerator.MarkLabel(leaveTryLabel);
                                methodGenerator.Emit(OpCodes.Leave_S, clientExceptionLabel);
                                #region finally
                                methodGenerator.BeginFinallyBlock();
                                #endregion
                                Label endfinallyLabel = methodGenerator.DefineLabel();
                                #region if (_wait_ != null)
                                methodGenerator.Emit(OpCodes.Ldloc_S, waitLocalBuilder);
                                methodGenerator.Emit(OpCodes.Brfalse_S, endfinallyLabel);
                                #endregion
                                #region AutoCSer.Net.TcpServer.AutoWaitReturnValue<TcpInternalServer.@OutputParameterTypeName>.PushNotNull(_wait_);
                                methodGenerator.Emit(OpCodes.Ldloc_S, waitLocalBuilder);
                                if (method.OutputParameterType == null)
                                {
                                    methodGenerator.call(TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePushNotNullMethod);
                                }
                                else
                                {
                                    Type autoWaitReturnValueType = typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue <>).MakeGenericType(method.OutputParameterType.Type);
                                    methodGenerator.call(autoWaitReturnValueType.GetMethod(TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePushNotNullMethod.Name, BindingFlags.Static | BindingFlags.Public, null, new Type[] { autoWaitReturnValueType }, null));
                                }
                                #endregion
                                methodGenerator.MarkLabel(endfinallyLabel);
                                methodGenerator.Emit(OpCodes.Endfinally);
                                #region try end
                                methodGenerator.EndExceptionBlock();
                                #endregion
                                methodGenerator.MarkLabel(clientExceptionLabel);
                                if (method.ReturnValueType == null)
                                {
                                    #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString());
                                    methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString());
                                    #endregion
                                    methodGenerator.MarkLabel(returnLable);
                                    methodGenerator.Emit(OpCodes.Ret);
                                    if (method.ReturnType != typeof(void))
                                    {
                                        methodGenerator.MarkLabel(returnValueLable);
                                        #region @MethodReturnType.FullName
                                        methodGenerator.Emit(OpCodes.Ldloc_S, returnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ret);
                                        #endregion
                                    }
                                }
                                else
                                {
                                    #region @ParameterName = default(@ParameterType.FullName);
                                    parameterIndex = 0;
                                    foreach (ParameterInfo parameter in parameters)
                                    {
                                        ++parameterIndex;
                                        if (parameter.IsOut)
                                        {
                                            methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj);
                                        }
                                    }
                                    #endregion
                                    #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.ClientException };
                                    if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj()))
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType);
                                    }
                                    methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder);
                                    methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ClientException);
                                    methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                                    methodGenerator.MarkLabel(returnReturnValueLable);
                                    methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder);
                                    methodGenerator.MarkLabel(returnLable);
                                    methodGenerator.Emit(OpCodes.Ret);
                                    #endregion
                                }
                            }
                        }
                        else if (method.IsPropertySetMethod)
                        {
                            if (method.PropertyBuilder != null || method.PropertyGetMethod == null)
                            {
                                ParameterInfo[] parameters      = method.MethodInfo.GetParameters();
                                PropertyBuilder propertyBuilder = method.PropertyBuilder ?? typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, parameters[parameters.Length - 1].ParameterType, new LeftArray <ParameterInfo> {
                                    Array = parameters, Length = parameters.Length - 1
                                }.GetArray(parameter => parameter.ParameterType));
                                MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType));
                                ILGenerator   methodGenerator  = setMethodBuilder.GetILGenerator();
                                //XXX
                                propertyBuilder.SetSetMethod(setMethodBuilder);
                                method.PropertyBuilder = null;
                            }
                        }
                        else
                        {
                            Type[]          parameterTypes   = method.MethodInfo.GetParameters().getArray(parameter => parameter.ParameterType);
                            PropertyBuilder propertyBuilder  = typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, method.MethodInfo.ReturnType, parameterTypes);
                            MethodBuilder   getMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameterTypes);
                            ILGenerator     methodGenerator  = getMethodBuilder.GetILGenerator();
                            //XXX
                            propertyBuilder.SetGetMethod(getMethodBuilder);
                            if (method.PropertySetMethod != null)
                            {
                                method = method.PropertySetMethod;
                                method.PropertyBuilder = propertyBuilder;
                                goto METHOD;
                            }
                        }
                    }
                }
                staticConstructorGenerator.Emit(OpCodes.Ret);
                return(typeBuilder.CreateType());
            }
Beispiel #29
0
        private EmitHelper InitGeneralPropertyInfo(EmitHelper emiter, LocalBuilder local, IProperty property)
        {
            var propertyType = property.GetType();
            var mapType      = typeof(PropertyMapInfo);

            emiter = emiter
                     .ldtoken(EntityType).call(MethodCache.TypeGetTypeFromHandle)
                     .newobj(propertyType)
                     .stloc(local)
                     .ldloc(local)
                     .ldstr(property.Name)
                     .call(propertyType.GetProperty(nameof(GeneralProperty.Name)).GetSetMethod())
                     .nop
                     .ldloc(local)
                     .ldtoken(property.Type)
                     .call(MethodCache.TypeGetTypeFromHandle)
                     .call(propertyType.GetProperty(nameof(GeneralProperty.Type)).GetSetMethod())
                     .nop
                     .ldloc(local)
                     .newobj(typeof(PropertyMapInfo))
                     .dup
                     .ldstr(property.Info.FieldName)
                     .call(mapType.GetProperty(nameof(PropertyMapInfo.FieldName)).GetSetMethod())
                     .nop;

            if (property.Info.IsPrimaryKey)
            {
                emiter = emiter.dup.ldc_i4_1.call(mapType.GetProperty(nameof(PropertyMapInfo.IsPrimaryKey)).GetSetMethod()).nop;
            }

            if (property.Info.GenerateType != IdentityGenerateType.None)
            {
                emiter = emiter.dup.ldc_i4_((int)property.Info.GenerateType).call(mapType.GetProperty(nameof(PropertyMapInfo.GenerateType)).GetSetMethod()).nop;
            }

            if (property.Info.DataType != null)
            {
                emiter = emiter.dup.ldc_i4_((int)property.Info.DataType).newobj(typeof(DbType?), typeof(DbType)).call(mapType.GetProperty(nameof(PropertyMapInfo.DataType)).GetSetMethod()).nop;
            }

            if (!string.IsNullOrEmpty(property.Info.Description))
            {
                emiter = emiter.dup.ldstr(property.Info.Description).call(mapType.GetProperty(nameof(PropertyMapInfo.Description)).GetSetMethod()).nop;
            }

            if (property.Info.IsDeletedKey)
            {
                emiter = emiter.dup.ldc_i4_1.call(mapType.GetProperty(nameof(PropertyMapInfo.IsDeletedKey)).GetSetMethod()).nop;
            }

            if (property.Info.IsNullable)
            {
                emiter = emiter.dup.ldc_i4_1.call(mapType.GetProperty(nameof(PropertyMapInfo.IsNullable)).GetSetMethod()).nop;
            }

            if (property.Info.Precision != null)
            {
                emiter = emiter.dup.ldc_i4_((int)property.Info.Precision).newobj(typeof(int?), typeof(int)).call(mapType.GetProperty(nameof(PropertyMapInfo.Precision)).GetSetMethod()).nop;
            }

            if (property.Info.Scale != null)
            {
                emiter = emiter.dup.ldc_i4_((int)property.Info.Scale).newobj(typeof(int?), typeof(int)).call(mapType.GetProperty(nameof(PropertyMapInfo.Scale)).GetSetMethod()).nop;
            }

            if (property.Info.Length != null)
            {
                emiter = emiter.dup.ldc_i4_((int)property.Info.Length).newobj(typeof(int?), typeof(int)).call(mapType.GetProperty(nameof(PropertyMapInfo.Length)).GetSetMethod()).nop;
            }

            if (!PropertyValue.IsEmpty(property.Info.DefaultValue))
            {
                //emiter = emiter.dup.ldc_i4_((int)property.Info.Length).newobj(typeof(int?), typeof(int)).call(mapType.GetProperty(nameof(PropertyMapInfo.Length)).GetSetMethod()).nop;
            }

            return(emiter.call(propertyType.GetProperty(nameof(GeneralProperty.Info)).GetSetMethod())
                   .ldloc(local)
                   .call(MethodCache.RegisterProperty));
        }
        private void EmitSyncCall(List <ParameterInfo> parameters, EmitHelper emit)
        {
            Context.MethodBuilder.MethodBuilder.SetCustomAttribute(_soapDocumentAttributeBuilder);

            bool withOutParameters = EmitParameters(emit, parameters);
            bool callGeneric       = !withOutParameters && Context.CurrentMethod.ReturnType != typeof(void);

            // Use Invoke<T>() for methods with return value but
            // Invoke() for methods with no return value or with out/ref parameters.
            //
            MethodInfo invoke = TypeHelper.GetMethod(
                typeof(WebClientBase),
                callGeneric,
                "Invoke",
                BindingFlags.Public | BindingFlags.Instance);

            if (callGeneric)
            {
                emit
                .call(invoke.MakeGenericMethod(Context.CurrentMethod.ReturnType))
                .stloc(Context.ReturnValue)
                ;
            }
            else
            {
                if (withOutParameters)
                {
                    LocalBuilder ret  = emit.DeclareLocal(typeof(object[]));
                    Label        exit = emit.DefineLabel();

                    emit
                    .call(invoke)
                    .dup
                    .stloc(ret)
                    .brfalse_s(exit)
                    ;

                    int idx = 0;

                    if (Context.CurrentMethod.ReturnType != typeof(void))
                    {
                        emit
                        .ldloc(ret)
                        .ldc_i4_0
                        .ldelem_ref
                        .CastFromObject(Context.CurrentMethod.ReturnType)
                        .stloc(Context.ReturnValue)
                        ;

                        ++idx;
                    }

                    for (int i = 0; i < parameters.Count; ++i)
                    {
                        ParameterInfo pi   = parameters[i];
                        Type          type = pi.ParameterType;

                        if (!type.IsByRef)
                        {
                            continue;
                        }

                        // Get ride of ref
                        //
                        type = type.GetElementType();

                        emit
                        .ldarg(pi)
                        .ldloc(ret)
                        .ldc_i4_(idx)
                        .ldelem_ref
                        .CastFromObject(type)
                        .stind(type)
                        ;

                        ++idx;
                    }

                    emit.MarkLabel(exit);
                }
                else
                {
                    emit
                    .call(invoke)
                    .pop
                    .end()
                    ;
                }
            }
        }
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] args = method.GetParameters();

            Label argsOk = generator.DefineLabel();

            // throw an error if the number of argument values doesn't match method parameters
            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }

            int localVariableCount = 0;

            for (int i = 0; i < args.Length; i++)
            {
                ParameterInfo parameter     = args[i];
                Type          parameterType = parameter.ParameterType;

                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();

                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);

                    // don't need to set variable for 'out' parameter
                    if (!parameter.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);

                        if (parameterType.IsValueType())
                        {
                            Label skipSettingDefault          = generator.DefineLabel();
                            Label finishedProcessingParameter = generator.DefineLabel();

                            // check if parameter is not null
                            generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                            // parameter has no value, initialize to default
                            generator.Emit(OpCodes.Ldloca_S, localVariable);
                            generator.Emit(OpCodes.Initobj, parameterType);
                            generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                            // parameter has value, get value from array again and unbox and set to variable
                            generator.MarkLabel(skipSettingDefault);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);

                            // parameter finished, we out!
                            generator.MarkLabel(finishedProcessingParameter);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);
                        }
                    }

                    generator.Emit(OpCodes.Ldloca_S, localVariable);

                    localVariableCount++;
                }
                else if (parameterType.IsValueType())
                {
                    generator.PushArrayInstance(argsIndex, i);

                    // have to check that value type parameters aren't null
                    // otherwise they will error when unboxed
                    Label skipSettingDefault          = generator.DefineLabel();
                    Label finishedProcessingParameter = generator.DefineLabel();

                    // check if parameter is not null
                    generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                    // parameter has no value, initialize to default
                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc, localVariableCount);
                    generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                    // parameter has value, get value from array again and unbox
                    generator.MarkLabel(skipSettingDefault);
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);

                    // parameter finished, we out!
                    generator.MarkLabel(finishedProcessingParameter);
                    localVariableCount++;
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);

                    generator.UnboxIfNeeded(parameterType);
                }
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }

            Type returnType = method.IsConstructor
                ? method.DeclaringType
                : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Return();
        }
Beispiel #32
0
        private static DynamicMethod CreateIl2CppShim(DynamicMethod patch, MethodBase original)
        {
            var patchName = patch.Name + "_il2cpp";

            var parameters     = patch.GetParameters();
            var result         = parameters.Types().ToList();
            var origParamTypes = result.ToArray();
            var paramTypes     = new Type[origParamTypes.Length];

            for (int i = 0; i < paramTypes.Length; ++i)
            {
                paramTypes[i] = Il2CppTypeForPatchType(origParamTypes[i]);
            }

            var origReturnType = AccessTools.GetReturnedType(patch);
            var returnType     = Il2CppTypeForPatchType(origReturnType);

            DynamicMethod method = new DynamicMethod(
                patchName,
                MethodAttributes.Public | MethodAttributes.Static,
                CallingConventions.Standard,
                returnType,
                paramTypes,
                original.DeclaringType,
                true
                );

            for (var i = 0; i < parameters.Length; i++)
            {
                method.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);
            }

            var il = method.GetILGenerator();

            LocalBuilder[] byRefValues = new LocalBuilder[parameters.Length];
            LocalBuilder   returnLocal = null;

            if (origReturnType != typeof(void))
            {
                returnLocal = il.DeclareLocal(origReturnType);
                Emitter.LogLocalVariable(il, returnLocal);
            }
            LocalBuilder exceptionLocal = il.DeclareLocal(typeof(Exception));

            Emitter.LogLocalVariable(il, exceptionLocal);

            // Start a try-block for the call to the original patch
            Emitter.MarkBlockBefore(il, new ExceptionBlock(ExceptionBlockType.BeginExceptionBlock, null), out _);

            // Load arguments, invoking the IntPrt -> Il2CppObject constructor for IL2CPP types
            for (int i = 0; i < origParamTypes.Length; ++i)
            {
                Emitter.Emit(il, OpCodes.Ldarg, i);
                ConvertArgument(il, origParamTypes[i], ref byRefValues[i]);
                if (byRefValues[i] != null)
                {
                    Emitter.LogLocalVariable(il, byRefValues[i]);
                }
            }

            // Call the original patch with the now-correct types
            Emitter.Emit(il, OpCodes.Call, patch);

            // Store the result, if any
            if (returnLocal != null)
            {
                Emitter.Emit(il, OpCodes.Stloc, returnLocal);
            }

            // Catch any exceptions that may have been thrown
            Emitter.MarkBlockBefore(il, new ExceptionBlock(ExceptionBlockType.BeginCatchBlock, typeof(Exception)), out _);

            // CumLogger.LogError("Exception in ...\n" + exception.ToString());
            Emitter.Emit(il, OpCodes.Stloc, exceptionLocal);
            Emitter.Emit(il, OpCodes.Ldstr, $"Exception in Harmony patch of method {original.FullDescription()}:\n");
            Emitter.Emit(il, OpCodes.Ldloc, exceptionLocal);
            Emitter.Emit(il, OpCodes.Call, AccessTools.DeclaredMethod(typeof(Exception), "ToString", new Type[0]));
            Emitter.Emit(il, OpCodes.Call, AccessTools.DeclaredMethod(typeof(string), "Concat", new Type[] { typeof(string), typeof(string) }));
            Emitter.Emit(il, OpCodes.Call, AccessTools.DeclaredMethod(typeof(CumLogger), "LogError", new Type[] { typeof(string) }));

            // Close the exception block
            Emitter.MarkBlockAfter(il, new ExceptionBlock(ExceptionBlockType.EndExceptionBlock, null));

            // Write back the pointers of ref arguments
            for (int i = 0; i < parameters.Length; ++i)
            {
                if (byRefValues[i] == null)
                {
                    continue;
                }

                Emitter.Emit(il, OpCodes.Ldarg, i);                 // -> [intptr*]
                Emitter.Emit(il, OpCodes.Ldloc, byRefValues[i]);    // -> [intptr*, obj]
                if (origParamTypes[i].GetElementType() == typeof(string))
                {
                    Emitter.Emit(il, OpCodes.Call, UnhollowerSupport.ManagedStringToIl2CppMethod);                     // -> [intptr*, intptr]
                }
                else
                {
                    Emitter.Emit(il, OpCodes.Call, UnhollowerSupport.Il2CppObjectBaseToPtrMethod); // -> [intptr*, intptr]
                }
                Emitter.Emit(il, OpCodes.Stind_I);                                                 // -> []
            }

            // Load the return value, if any, and unwrap it if required
            if (returnLocal != null)
            {
                Emitter.Emit(il, OpCodes.Ldloc, returnLocal);
                ConvertReturnValue(il, origReturnType);
            }

            Emitter.Emit(il, OpCodes.Ret);

            DynamicTools.PrepareDynamicMethod(method);
            return(method);
        }
Beispiel #33
0
        public bool TryEmitDeserialiseCode(ILGenerator ilg, ThrowBlockGatherer throwBlocks, ICollection <string> errors, string name, Type targetType, LocalBuilder value, LocalBuilder unpacker, LocalBuilder contextLocal, DasherContext context, UnexpectedFieldBehaviour unexpectedFieldBehaviour)
        {
            ilg.Emit(OpCodes.Ldloc, unpacker);
            ilg.LoadType(targetType);
            ilg.Emit(OpCodes.Ldstr, name);
            ilg.Emit(OpCodes.Call, Methods.DecimalProvider_Parse);
            ilg.Emit(OpCodes.Stloc, value);

            return(true);
        }
Beispiel #34
0
        private static void ConvertArgument(ILGenerator il, Type paramType, ref LocalBuilder byRefLocal)
        {
            if (paramType.IsValueType)
            {
                return;
            }

            if (paramType.IsByRef)
            {
                Type elementType = paramType.GetElementType();

                if (paramType.GetElementType() == typeof(string))
                {
                    // byRefLocal = Il2CppStringToManaged(*ptr);
                    // return ref byRefLocal;

                    byRefLocal = il.DeclareLocal(elementType);
                    Emitter.Emit(il, OpCodes.Ldind_I);
                    Emitter.Emit(il, OpCodes.Call, UnhollowerSupport.Il2CppStringToManagedMethod);
                    Emitter.Emit(il, OpCodes.Stloc, byRefLocal);
                    Emitter.Emit(il, OpCodes.Ldloca, byRefLocal);
                }
                else if (UnhollowerSupport.IsGeneratedAssemblyType(elementType))
                {
                    // byRefLocal = *ptr == 0 ? null : new SomeType(*ptr);
                    // return ref byRefLocal;
                    Label ptrNonZero = il.DefineLabel();
                    Label done       = il.DefineLabel();

                    byRefLocal = il.DeclareLocal(elementType);
                    Emitter.Emit(il, OpCodes.Ldind_I);
                    Emitter.Emit(il, OpCodes.Dup);
                    Emitter.Emit(il, OpCodes.Brtrue_S, ptrNonZero);
                    Emitter.Emit(il, OpCodes.Pop);
                    Emitter.Emit(il, OpCodes.Br_S, done);
                    Emitter.MarkLabel(il, ptrNonZero);
                    Emitter.Emit(il, OpCodes.Newobj, Il2CppConstuctor(elementType));
                    Emitter.Emit(il, OpCodes.Stloc, byRefLocal);
                    Emitter.MarkLabel(il, done);
                    Emitter.Emit(il, OpCodes.Ldloca, byRefLocal);
                }
            }
            else if (paramType == typeof(string))
            {
                // return Il2CppStringToManaged(ptr);
                Emitter.Emit(il, OpCodes.Call, UnhollowerSupport.Il2CppStringToManagedMethod);
            }
            else if (UnhollowerSupport.IsGeneratedAssemblyType(paramType))
            {
                // return ptr == 0 ? null : new SomeType(ptr);
                Label ptrNonZero = il.DefineLabel();
                Label done       = il.DefineLabel();

                Emitter.Emit(il, OpCodes.Dup);
                Emitter.Emit(il, OpCodes.Brtrue_S, ptrNonZero);
                Emitter.Emit(il, OpCodes.Pop);
                Emitter.Emit(il, OpCodes.Ldnull);
                Emitter.Emit(il, OpCodes.Br_S, done);
                Emitter.MarkLabel(il, ptrNonZero);
                Emitter.Emit(il, OpCodes.Newobj, Il2CppConstuctor(paramType));
                Emitter.MarkLabel(il, done);
            }
        }
Beispiel #35
0
        static Converter()
        {
            _type = typeof(T);
            TypeInfo typeInfo = _type.GetTypeInfo();

            if (_type == typeof(string))
            {
                _writeAction = (Converter.WriteAction <T>)(Delegate) new Converter.WriteAction <string>(StringConverter.Write);
                _readAction  = (Converter.ReadAction <T>)(Delegate) new Converter.ReadAction <string>(StringConverter.Read);
            }
            else if (typeInfo.IsArray)
            {
                Type elementType = typeInfo.GetElementType();

                _writeAction = (Converter.WriteAction <T>) typeof(Converter <>).MakeGenericType(elementType).GetTypeInfo().GetDeclaredMethod(nameof(WriteArray)).CreateDelegate(typeof(Converter.WriteAction <T>));
                _readAction  = (Converter.ReadAction <T>) typeof(Converter <>).MakeGenericType(elementType).GetTypeInfo().GetDeclaredMethod(nameof(ReadArray)).CreateDelegate(typeof(Converter.ReadAction <T>));
            }
            else
            {
                try
                {
                    if (typeInfo.IsUnmanaged())
                    {
                        TypeInfo unmanagedType = typeof(UnmanagedConverter <>).MakeGenericType(_type).GetTypeInfo();

                        _writeAction = (Converter.WriteAction <T>)unmanagedType.GetDeclaredMethod(nameof(UnmanagedConverter <bool> .Write)).CreateDelegate(typeof(Converter.WriteAction <T>));
                        _readAction  = (Converter.ReadAction <T>)unmanagedType.GetDeclaredMethod(nameof(UnmanagedConverter <bool> .Read)).CreateDelegate(typeof(Converter.ReadAction <T>));
                    }
                    else
                    {
                        DynamicMethod writeMethod    = new DynamicMethod($"Write_{nameof(T)}", typeof(void), new[] { _type.MakeByRefType(), typeof(Stream), typeof(byte[]), typeof(byte *) }, typeof(Converter <T>), true);
                        ILGenerator   writeGenerator = writeMethod.GetILGenerator();

                        DynamicMethod readMethod    = new DynamicMethod($"Read_{nameof(T)}", _type, new[] { typeof(Stream), typeof(byte[]), typeof(byte *) }, typeof(Converter <T>), true);
                        ILGenerator   readGenerator = readMethod.GetILGenerator();
                        LocalBuilder  readValue     = readGenerator.DeclareLocal(_type);

                        if (typeInfo.IsClass)
                        {
                            readGenerator.Emit(OpCodes.Ldsfld, typeof(Converter <T>).GetTypeInfo().GetDeclaredField(nameof(_type)));
                            readGenerator.Emit(OpCodes.Call, typeof(ObjectInitializer).GetTypeInfo().GetDeclaredMethod(nameof(ObjectInitializer.Create)));
                            readGenerator.Emit(OpCodes.Stloc, readValue);
                        }
                        else
                        {
                            readGenerator.Emit(OpCodes.Ldloca_S, readValue);
                            readGenerator.Emit(OpCodes.Initobj, _type);
                        }

                        while (typeInfo != null)
                        {
                            foreach (FieldInfo fieldInfo in typeInfo.DeclaredFields.Where(f => !f.IsStatic))
                            {
                                writeGenerator.Emit(OpCodes.Ldarg_0);
                                if (typeInfo.IsClass)
                                {
                                    writeGenerator.Emit(OpCodes.Ldind_Ref);
                                }
                                writeGenerator.Emit(OpCodes.Ldflda, fieldInfo);
                                writeGenerator.Emit(OpCodes.Ldarg_1);
                                writeGenerator.Emit(OpCodes.Ldarg_2);
                                writeGenerator.Emit(OpCodes.Ldarg_3);
                                writeGenerator.Emit(OpCodes.Call, typeof(Converter <>).MakeGenericType(fieldInfo.FieldType).GetTypeInfo().GetDeclaredMethod(nameof(Converter <T> .Write)));

                                readGenerator.Emit(typeInfo.IsClass ? OpCodes.Ldloc : OpCodes.Ldloca_S, readValue);
                                readGenerator.Emit(OpCodes.Ldarg_0);
                                readGenerator.Emit(OpCodes.Ldarg_1);
                                readGenerator.Emit(OpCodes.Ldarg_2);
                                readGenerator.Emit(OpCodes.Call, typeof(Converter <>).MakeGenericType(fieldInfo.FieldType).GetTypeInfo().GetDeclaredMethod(nameof(Converter <T> .Read)));
                                readGenerator.Emit(OpCodes.Stfld, fieldInfo);
                            }

                            typeInfo = typeInfo.BaseType?.GetTypeInfo();
                        }

                        writeGenerator.Emit(OpCodes.Ret);
                        _writeAction = (Converter.WriteAction <T>)writeMethod.CreateDelegate(typeof(Converter.WriteAction <T>));

                        readGenerator.Emit(OpCodes.Ldloc, readValue);
                        readGenerator.Emit(OpCodes.Ret);
                        _readAction = (Converter.ReadAction <T>)readMethod.CreateDelegate(typeof(Converter.ReadAction <T>));
                    }
                }
                catch
                {
                    _writeAction = (in T _, Stream __, byte[] ___, byte *____) => throw new InvalidOperationException($"Unable to handle type {_type.FullName}");
                    _readAction  = (_, __, ___) => throw new InvalidOperationException($"Unable to handle type {_type.FullName}");
                }
            }
        }
        /// <summary>
        /// 直接转换整个DataTable
        /// </summary>
        /// <typeparam name="T">model</typeparam>
        /// <param name="map">列名称映射:Key列名称,Value属性名称</param>
        /// <param name="mapType">列类型映射:key列类型,value属性类型</param>
        /// <returns></returns>
        public static DynamicMethod EntityToDataTableEmit <T>(Dictionary <string, string> map = null, Dictionary <string, Type> mapType = null)
        {
            DynamicMethod method = new DynamicMethod(typeof(T).Name + "ToDataTable", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null,
                                                     new Type[] { typeof(DataTable), typeof(T) }, typeof(EntityContext).Module, true);
            ILGenerator generator = method.GetILGenerator();
            //创建行 实现DataRow row=dt.NewRow();
            LocalBuilder reslut = generator.DeclareLocal(typeof(DataRow));

            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Call, typeof(DataTable).GetMethod("NewRow"));
            generator.Emit(OpCodes.Stloc, reslut);//结果存储
            var properties = typeof(T).GetProperties();
            //
            Dictionary <string, Type>         dic             = new Dictionary <string, Type>();
            Dictionary <string, LocalBuilder> dicLocalBuilder = new Dictionary <string, LocalBuilder>();
            List <PropertyInfo> lstNull = new List <PropertyInfo>();

            //获取空类型属性
            foreach (var item in properties)
            {
                if (Nullable.GetUnderlyingType(item.PropertyType) != null)
                {
                    lstNull.Add(item);
                }
            }
            int cout = lstNull.Count;
            List <LocalBuilder> lstLocal = new List <LocalBuilder>(lstNull.Count);

            foreach (var item in lstNull)
            {
                //获取所有空类型属性的类型
                dic[item.Name] = item.PropertyType;
            }

            for (int i = 0; i < cout; i++)
            {
                //定义足够的bool
                lstLocal.Add(generator.DeclareLocal(typeof(bool)));
            }
            foreach (var kv in dic)
            {
                //定义包含的空类型
                if (!dicLocalBuilder.ContainsKey(kv.Value.FullName))
                {
                    dicLocalBuilder[kv.Value.FullName] = generator.DeclareLocal(kv.Value);
                }
            }
            //没有列名称映射
            int index = -1;//必须-1合适

            if (map == null)
            {
                //遍历属性
                foreach (var p in properties)
                {
                    if (dic.ContainsKey(p.Name))
                    {
                        var endIfLabel = generator.DefineLabel();
                        //判断
                        //
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod());//

                        generator.Emit(OpCodes.Stloc_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Ldloca_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Call, dic[p.Name].GetMethod("get_HasValue"));

                        generator.Emit(OpCodes.Stloc, lstLocal[++index]);
                        generator.Emit(OpCodes.Ldloc, lstLocal[index]);
                        generator.Emit(OpCodes.Brfalse_S, endIfLabel);
                        //赋值
                        generator.Emit(OpCodes.Ldloc, reslut);          //取出变量
                        generator.Emit(OpCodes.Ldstr, p.Name);          //row["Name"]
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod()); //
                                                                        //
                        generator.Emit(OpCodes.Stloc_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Ldloca_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Call, dic[p.Name].GetMethod("get_Value"));
                        //
                        generator.Emit(OpCodes.Box, Nullable.GetUnderlyingType(p.PropertyType)); //一直在折腾这个地方,哎
                                                                                                 //
                        generator.Emit(OpCodes.Call, typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
                        generator.MarkLabel(endIfLabel);
                    }
                    else
                    {
                        generator.Emit(OpCodes.Ldloc, reslut);
                        generator.Emit(OpCodes.Ldstr, p.Name);
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod());//获取属性
                        if (mapType == null || !mapType.ContainsKey(p.Name))
                        {
                            if (p.PropertyType.IsValueType)
                            {
                                generator.Emit(OpCodes.Box, p.PropertyType);//一直在折腾这个地方,哎
                            }
                            else
                            {
                                generator.Emit(OpCodes.Castclass, p.PropertyType);
                            }
                        }
                        else
                        {
                            generator.Emit(OpCodes.Ldtoken, mapType[p.Name]);
                            generator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
                            generator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }));
                        }
                        generator.Emit(OpCodes.Call, typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
                    }
                }
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Call, typeof(DataTable).GetMethod("get_Rows"));
                generator.Emit(OpCodes.Ldloc, reslut);
                generator.Emit(OpCodes.Call, typeof(DataRowCollection).GetMethod("Add", new Type[] { typeof(DataRow) }));
                generator.Emit(OpCodes.Ret);
            }
            else
            {
                List <PropertyInfo> lst = new List <PropertyInfo>(properties);
                foreach (var kv in map)
                {
                    var p = lst.Find(x => x.Name == kv.Value);//找到属性
                    if (dic.ContainsKey(p.Name))
                    {
                        var endIfLabel = generator.DefineLabel();
                        //判断
                        //
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod());//

                        generator.Emit(OpCodes.Stloc_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Ldloca_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Call, dic[p.Name].GetMethod("get_HasValue"));

                        generator.Emit(OpCodes.Stloc, lstLocal[++index]);
                        generator.Emit(OpCodes.Ldloc, lstLocal[index]);
                        generator.Emit(OpCodes.Brfalse_S, endIfLabel);
                        //赋值
                        generator.Emit(OpCodes.Ldloc, reslut);
                        generator.Emit(OpCodes.Ldstr, kv.Value);        //属性名称
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod()); //
                                                                        //
                        generator.Emit(OpCodes.Stloc_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Ldloca_S, dicLocalBuilder[p.PropertyType.FullName]);
                        generator.Emit(OpCodes.Call, dic[p.Name].GetMethod("get_Value"));
                        //
                        generator.Emit(OpCodes.Box, Nullable.GetUnderlyingType(p.PropertyType)); //一直在折腾这个地方,哎
                                                                                                 //
                        generator.Emit(OpCodes.Call, typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
                        generator.MarkLabel(endIfLabel);
                    }
                    else
                    {
                        generator.Emit(OpCodes.Ldloc, reslut);
                        generator.Emit(OpCodes.Ldstr, kv.Value);        //属性名称
                        generator.Emit(OpCodes.Ldarg_1);
                        generator.Emit(OpCodes.Call, p.GetGetMethod()); //获取属性值
                        if (mapType == null || !mapType.ContainsKey(kv.Key))
                        {
                            if (p.PropertyType.IsValueType)
                            {
                                generator.Emit(OpCodes.Box, p.PropertyType);//一直在折腾这个地方,哎
                            }
                            else
                            {
                                generator.Emit(OpCodes.Castclass, p.PropertyType);
                            }
                        }
                        else
                        {
                            generator.Emit(OpCodes.Ldtoken, mapType[kv.Key]);
                            generator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
                            generator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }));
                        }

                        generator.Emit(OpCodes.Call, typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
                    }
                }
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Call, typeof(DataTable).GetMethod("get_Rows"));
                generator.Emit(OpCodes.Ldloc, reslut);
                generator.Emit(OpCodes.Call, typeof(DataRowCollection).GetMethod("Add", new Type[] { typeof(DataRow) }));
                generator.Emit(OpCodes.Ret);
            }
            return(method);
        }
Beispiel #37
0
                /// <summary>
                /// Creates a method for calling with the specified signature.  The returned method has a signature
                /// of the form:
                ///
                /// (IntPtr funcAddress, arg0, arg1, ..., object[] constantPool)
                ///
                /// where IntPtr is the address of the function to be called.  The arguments types are based upon
                /// the types that the ArgumentMarshaller requires.
                /// </summary>
                private static MethodInfo /*!*/ CreateInteropInvoker(CallingConvention convention, ArgumentMarshaller /*!*/[] /*!*/ sig, INativeType nativeRetType, bool retVoid, List <object> constantPool)
                {
                    Type[] sigTypes = new Type[sig.Length + 2];
                    sigTypes[0] = typeof(IntPtr);
                    for (int i = 0; i < sig.Length; i++)
                    {
                        sigTypes[i + 1] = sig[i].ArgumentExpression.Type;
                    }
                    sigTypes[sigTypes.Length - 1] = typeof(object[]);

                    Type retType = retVoid ? typeof(void) :
                                   nativeRetType != null?nativeRetType.GetPythonType() : typeof(int);

                    Type calliRetType = retVoid ? typeof(void) :
                                        nativeRetType != null?nativeRetType.GetNativeType() : typeof(int);

#if !CTYPES_USE_SNIPPETS
                    DynamicMethod dm = new DynamicMethod("InteropInvoker", retType, sigTypes, DynamicModule);
#else
                    TypeGen       tg = Snippets.Shared.DefineType("InteropInvoker", typeof(object), false, false);
                    MethodBuilder dm = tg.TypeBuilder.DefineMethod("InteropInvoker", CompilerHelpers.PublicStatic, retType, sigTypes);
#endif

                    ILGenerator  method = dm.GetILGenerator();
                    LocalBuilder calliRetTmp = null, finalRetValue = null;
                    if (dm.ReturnType != typeof(void))
                    {
                        calliRetTmp   = method.DeclareLocal(calliRetType);
                        finalRetValue = method.DeclareLocal(dm.ReturnType);
                    }

                    // try {
                    // emit all of the arguments, save their cleanups

                    method.BeginExceptionBlock();

                    List <MarshalCleanup> cleanups = null;
                    for (int i = 0; i < sig.Length; i++)
                    {
#if DEBUG
                        method.Emit(OpCodes.Ldstr, String.Format("Argument #{0}, Marshaller: {1}, Native Type: {2}", i, sig[i], sig[i].NativeType));
                        method.Emit(OpCodes.Pop);
#endif
                        MarshalCleanup cleanup = sig[i].EmitCallStubArgument(method, i + 1, constantPool, sigTypes.Length - 1);
                        if (cleanup != null)
                        {
                            if (cleanups == null)
                            {
                                cleanups = new List <MarshalCleanup>();
                            }

                            cleanups.Add(cleanup);
                        }
                    }

                    // emit the target function pointer and the calli
#if DEBUG
                    method.Emit(OpCodes.Ldstr, "!!! CALLI !!!");
                    method.Emit(OpCodes.Pop);
#endif

                    method.Emit(OpCodes.Ldarg_0);
                    method.Emit(OpCodes.Calli, GetCalliSignature(convention, sig, calliRetType));

                    // if we have a return value we need to store it and marshal to Python
                    // before we run any cleanup code.
                    if (retType != typeof(void))
                    {
#if DEBUG
                        method.Emit(OpCodes.Ldstr, "!!! Return !!!");
                        method.Emit(OpCodes.Pop);
#endif

                        if (nativeRetType != null)
                        {
                            method.Emit(OpCodes.Stloc, calliRetTmp);
                            nativeRetType.EmitReverseMarshalling(method, new Local(calliRetTmp), constantPool, sig.Length + 1);
                            method.Emit(OpCodes.Stloc, finalRetValue);
                        }
                        else
                        {
                            Debug.Assert(retType == typeof(int));
                            // no marshalling necessary
                            method.Emit(OpCodes.Stloc, finalRetValue);
                        }
                    }

                    // } finally {
                    // emit the cleanup code

                    method.BeginFinallyBlock();

                    if (cleanups != null)
                    {
                        foreach (MarshalCleanup mc in cleanups)
                        {
                            mc.Cleanup(method);
                        }
                    }

                    method.EndExceptionBlock();

                    // }
                    // load the temporary value and return it.
                    if (retType != typeof(void))
                    {
                        method.Emit(OpCodes.Ldloc, finalRetValue);
                    }

                    method.Emit(OpCodes.Ret);

#if CTYPES_USE_SNIPPETS
                    return(tg.TypeBuilder.CreateType().GetMethod("InteropInvoker"));
#else
                    return(dm);
#endif
                }
        private static void EmitReadMethodContents(
            ILGenerator gen,
            Type formattedType,
            FieldInfo dictField,
            Dictionary <Type, FieldBuilder> serializerFields,
            Dictionary <MemberInfo, List <string> > memberNames,
            Dictionary <Type, MethodInfo> serializerReadMethods)
        {
            MethodInfo skipMethod        = typeof(IDataReader).GetMethod("SkipEntry", Flags.InstancePublic);
            MethodInfo tryGetValueMethod = typeof(Dictionary <string, int>).GetMethod("TryGetValue", Flags.InstancePublic);

            //methodBuilder.DefineParameter(5, ParameterAttributes.None, "switchLookup");

            LocalBuilder lookupResult = gen.DeclareLocal(typeof(int));

            Label defaultLabel = gen.DefineLabel();
            Label switchLabel  = gen.DefineLabel();
            Label endLabel     = gen.DefineLabel();

            Label[] switchLabels = memberNames.Select(n => gen.DefineLabel()).ToArray();

            gen.Emit(OpCodes.Ldarg_1);                                              // Load entryName string
            gen.Emit(OpCodes.Ldnull);                                               // Load null
            gen.Emit(OpCodes.Ceq);                                                  // Equality check
            gen.Emit(OpCodes.Brtrue, defaultLabel);                                 // If entryName is null, go to default case

            //gen.Emit(OpCodes.Ldarg, (short)4);                                      // Load lookup dictionary argument (OLD CODE)

            gen.Emit(OpCodes.Ldsfld, dictField);                                    // Load lookup dictionary from static field on helper type
            gen.Emit(OpCodes.Ldarg_1);                                              // Load entryName string
            gen.Emit(OpCodes.Ldloca, (short)lookupResult.LocalIndex);               // Load address of lookupResult
            gen.Emit(OpCodes.Callvirt, tryGetValueMethod);                          // Call TryGetValue on the dictionary

            gen.Emit(OpCodes.Brtrue, switchLabel);                                  // If TryGetValue returned true, go to the switch case
            gen.Emit(OpCodes.Br, defaultLabel);                                     // Else, go to the default case

            gen.MarkLabel(switchLabel);                                             // Switch starts here
            gen.Emit(OpCodes.Ldloc, lookupResult);                                  // Load lookupResult
            gen.Emit(OpCodes.Switch, switchLabels);                                 // Perform switch on switchLabels

            int count = 0;

            foreach (var member in memberNames.Keys)
            {
                var memberType = FormatterUtilities.GetContainedType(member);

                var propInfo  = member as PropertyInfo;
                var fieldInfo = member as FieldInfo;

                gen.MarkLabel(switchLabels[count]);                                 // Switch case for [count] starts here

                // Now we load the instance that we have to set the value on
                gen.Emit(OpCodes.Ldarg_0);                                          // Load value reference

                if (formattedType.IsValueType == false)
                {
                    gen.Emit(OpCodes.Ldind_Ref);                                    // Indirectly load value of reference
                }

                // Now we deserialize the value itself
                gen.Emit(OpCodes.Ldsfld, serializerFields[memberType]);             // Load serializer from serializer container type
                gen.Emit(OpCodes.Ldarg, (short)3);                                  // Load reader argument
                gen.Emit(OpCodes.Callvirt, serializerReadMethods[memberType]);      // Call Serializer.ReadValue(IDataReader reader)

                // The stack now contains the formatted instance and the deserialized value to set the member to
                // Now we set the value
                if (fieldInfo != null)
                {
                    gen.Emit(OpCodes.Stfld, fieldInfo.DeAliasField());                              // Set field
                }
                else if (propInfo != null)
                {
                    gen.Emit(OpCodes.Callvirt, propInfo.DeAliasProperty().GetSetMethod(true));      // Call property setter
                }
                else
                {
                    throw new NotImplementedException();
                }

                gen.Emit(OpCodes.Br, endLabel);                                     // Jump to end of method

                count++;
            }

            gen.MarkLabel(defaultLabel);                                            // Default case starts here
            gen.Emit(OpCodes.Ldarg, (short)3);                                      // Load reader argument
            gen.Emit(OpCodes.Callvirt, skipMethod);                                 // Call IDataReader.SkipEntry

            gen.MarkLabel(endLabel);                                                // Method end starts here
            gen.Emit(OpCodes.Ret);                                                  // Return method
        }
 internal override void GenStatementCode(CompileContext compileContext, bool bGenDebug)
 {
     LocalBuilder thrownException = compileContext.gen.DeclareLocal(typeof(JSRuntimeException));
     Label exTryCatchFinally = compileContext.gen.BeginExceptionBlock();
     this.FinallyFwdDest = compileContext.gen.DeclareLocal(typeof(int));
     compileContext.gen.Emit(OpCodes.Ldc_I4_M1);
     compileContext.gen.Emit(OpCodes.Stloc, this.FinallyFwdDest);
     this.FinEnd = compileContext.gen.DefineLabel();
     ((StatementNode) base.Children[0]).GenCode(compileContext);
     compileContext.gen.MarkLabel(this.FinEnd);
     if (this.CatchTree != null)
     {
         compileContext.gen.BeginCatchBlock(typeof(JSRuntimeException));
         compileContext.gen.Emit(OpCodes.Stloc, thrownException);
         compileContext.gen.Emit(OpCodes.Ldarg_0);
         compileContext.gen.Emit(OpCodes.Ldloc, thrownException);
         compileContext.gen.Emit(OpCodes.Ldstr, this.CatchId);
         compileContext.gen.EmitCallV( CompileContext.mi_JSScope_CreateCatchScope);
         compileContext.gen.Emit(OpCodes.Starg, 0);
         Label InternalTry = compileContext.gen.BeginExceptionBlock();
         this.FinEnd = compileContext.gen.DefineLabel();
         this.CatchTree.GenCode(compileContext);
         compileContext.gen.MarkLabel(this.FinEnd);
         compileContext.gen.BeginFinallyBlock();
         compileContext.gen.Emit(OpCodes.Ldarg_0);
         compileContext.gen.EmitCallV( CompileContext.mi_JSContext_Parent);
         compileContext.gen.Emit(OpCodes.Starg, 0);
         compileContext.gen.EndExceptionBlock();
     }
     else if (this.FinallyTree != null)
     {
         compileContext.gen.BeginCatchBlock(typeof(JSRuntimeException));
         compileContext.gen.Emit(OpCodes.Stloc, thrownException);
     }
     if (this.FinallyTree != null)
     {
         this.FinEnd = compileContext.gen.DefineLabel();
         compileContext.gen.BeginFinallyBlock();
         this.FinallyTree.GenCode(compileContext);
         compileContext.gen.MarkLabel(this.FinEnd);
     }
     compileContext.gen.EndExceptionBlock();
     bool bProcessRedirects = this.PostFinallyLabels.Count > 0;
     if (bProcessRedirects)
     {
         compileContext.gen.Emit(OpCodes.Ldloc, this.FinallyFwdDest);
         compileContext.gen.Emit(OpCodes.Switch, this.PostFinallyLabels.Select<PostFinallyLabel, Label>(delegate (PostFinallyLabel x) {
             return x.switchlabel;
         }).ToArray<Label>());
     }
     if ((this.CatchTree == null) && (this.FinallyTree != null))
     {
         compileContext.gen.Emit(OpCodes.Ldloc, thrownException);
         compileContext.gen.Emit(OpCodes.Brfalse, base.breakdest);
         compileContext.gen.Emit(OpCodes.Ldloc, thrownException);
         compileContext.gen.Emit(OpCodes.Throw);
     }
     else
     {
         compileContext.gen.Emit(OpCodes.Br, base.breakdest);
     }
     if (bProcessRedirects)
     {
         foreach (PostFinallyLabel pfl in this.PostFinallyLabels)
         {
             compileContext.gen.MarkLabel(pfl.switchlabel);
             base.GenInterStatementBreak(compileContext, pfl.lbl, pfl.destNode);
         }
     }
 }
Beispiel #40
0
        /// <summary>
        /// ***********************************************************************
        /// V1: Not nullable object. ex) Int32, DateTime, Point, DayOfWeek
        /// P1: Nullable object. ex) String, class, Nullable<T>
        /// -----------------------------------------------------------------------
        /// src.V1 --> tgt.V1;
        /// var converted = converter.ToXXX(src.V1);
        /// if (converted == null) return; // DoNothing...
        /// tgt.V1 = converted.Value;
        ///
        /// -----------------------------------------------------------------------
        /// src.V1 --> tgt.P1;
        /// var converted = converter.ToXXX(src.V1);
        /// if (converted == null) return; // DoNothing...
        /// tgt.P1 = converted;
        ///
        /// -----------------------------------------------------------------------
        /// src.P1 --> tgt.V1;
        /// if (src.P1 == null) return; // DoNothing...
        /// var converted = converter.ToXXX(src.P1);
        /// if (converted.HasValue == false) return; // DoNothing...
        /// tgt.V1 = converted;
        ///
        /// -----------------------------------------------------------------------
        /// src.P1 --> tgt.P1;
        /// if (src.P1 == null) tgt.P1 = null;
        /// var converted = converter.ToXXX(src.P1);
        /// if (converted.HasValue == false) return; // DoNothing...
        /// tgt.P1 = converted;
        ///
        /// *************************************************************************/
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="propertyMapInfo"></param>
        /// <returns></returns>
        private Action <ObjectMapConfig, TSource, TTarget, MappingContext> CreateSetPropertyMethod <TSource, TTarget>(IEnumerable <PropertyMap> propertyMapInfo)
        {
            var           sourceType = typeof(TSource);
            var           targetType = typeof(TTarget);
            DynamicMethod dm         = new DynamicMethod("SetProperty", null, new[] { typeof(ObjectMapConfig), sourceType, targetType, typeof(MappingContext) });
            ILGenerator   il         = dm.GetILGenerator();
            var           mapConfigTypeConverterGetMethod = typeof(ObjectMapConfig).GetProperty("TypeConverter", BindingFlags.Instance | BindingFlags.Public).GetGetMethod();

            il.DeclareLocal(typeof(TypeConverter));
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, mapConfigTypeConverterGetMethod);
            il.Emit(OpCodes.Stloc_0);//ObjectMapConfig.TypeConverter

            foreach (var item in propertyMapInfo)
            {
                var getMethod = item.Source.PropertyInfo.GetGetMethod();
                var setMethod = item.Target.PropertyInfo.GetSetMethod();
                //Target property is readonly
                if (setMethod == null)
                {
                    continue;
                }
                #region DefineLabel
                Label customConvertStartLabel = il.DefineLabel();
                Label setValueStartLabel      = il.DefineLabel();
                Label endOfCode            = il.DefineLabel();
                Label setNullToTargetLabel = il.DefineLabel();
                Label sourceHasValueLabel  = il.DefineLabel();
                #endregion
                var sourceVal = il.DeclareLocal(item.Source.ActualType);
                var targetVal = il.DeclareLocal(item.Target.ActualType);

                #region GetValue from SourceObject

                if (item.Source.IsIndexedProperty == true)
                {
                    #region Dictionary<String, String> or Dictionary<String, Object>
                    //Call TryGetValue method to avoid KeyNotFoundException
                    if (sourceType.IsInheritanceFrom(typeof(Dictionary <String, String>)) == true ||
                        sourceType.IsInheritanceFrom(typeof(Dictionary <String, Object>)) == true)
                    {
                        MethodInfo   tryGetValue = null;
                        LocalBuilder outValue    = null;
                        //Call TryGetValue method
                        tryGetValue = sourceType.GetMethod("TryGetValue");
                        outValue    = il.DeclareLocal(item.Source.PropertyType);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldstr, item.Source.IndexedPropertyKey);
                        il.LoadLocala(outValue);
                        //TryGetValue(item.Source.IndexedPropertyKey, sourceVal) --> Boolean
                        il.Emit(OpCodes.Callvirt, tryGetValue);
                        il.Emit(OpCodes.Pop);
                        il.LoadLocal(outValue);
                    }
                    else
                    {
                        //source[string key]
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldstr, item.Source.IndexedPropertyKey);
                        il.Emit(OpCodes.Callvirt, getMethod);
                    }
                    #endregion
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Callvirt, getMethod);
                }

                //Check source.P1 is null
                if (item.Source.CanBeNull == true)
                {
                    if (item.Source.IsNullableT == true)
                    {
                        #region if (source.P1.HasValue == false)
                        var sourceValN = il.DeclareLocal(item.Source.PropertyType);

                        il.SetLocal(sourceValN);
                        //if (sourceValue.HasValue == true)
                        il.LoadLocala(sourceValN);
                        il.Emit(OpCodes.Call, item.Source.PropertyType.GetProperty("HasValue").GetGetMethod());
                        il.Emit(OpCodes.Brfalse, setNullToTargetLabel); //null --> set target null
                        il.LoadLocala(sourceValN);
                        //sourceVal.Value
                        il.Emit(OpCodes.Call, item.Source.PropertyType.GetMethod("GetValueOrDefault", Type.EmptyTypes));
                        #endregion
                    }
                    else if (item.Source.CanBeNull == true)
                    {
                        #region if (source.P1 == null)
                        Type sourceTypeN = item.Source.ActualType;
                        var  sourceValN  = il.DeclareLocal(sourceTypeN);
                        il.SetLocal(sourceValN);
                        //if (sourceValue == null)
                        il.LoadLocal(sourceValN);
                        il.Emit(OpCodes.Ldnull);
                        il.Emit(OpCodes.Ceq);
                        il.Emit(OpCodes.Brtrue, setNullToTargetLabel); //null --> set target null
                        il.LoadLocal(sourceValN);
                        #endregion
                    }
                }
                il.Emit(OpCodes.Br, sourceHasValueLabel);

                il.MarkLabel(sourceHasValueLabel);
                //store sourceVal (never be null)
                il.SetLocal(sourceVal);
                #endregion

                #region Convert value to target type.
                LocalBuilder convertedVal = null;
                var          methodName   = GetMethodName(item.Target.ActualType);
                if (item.Target.ActualType.IsEnum == false && methodName == null)
                {
                    if (item.Target.PropertyType.IsValueType == true &&
                        item.Source.ActualType == item.Target.ActualType)
                    {
                        #region target.Struct = source.Struct;
                        il.LoadLocal(sourceVal);
                        il.LoadLocal(targetVal);
                        #endregion
                    }
                    else
                    {
                        convertedVal = il.DeclareLocal(item.Target.ActualType);
                        il.Emit(OpCodes.Br_S, customConvertStartLabel);
                    }
                }
                else
                {
                    #region var convertedValue = TypeConverter.ToXXX(sourceVal);
                    //Call TypeConverter.ToXXX(sourceVal);
                    il.Emit(OpCodes.Ldloc_0);//MapConfig.Current.TypeConverter
                    il.LoadLocal(sourceVal);
                    if (item.Source.ActualType.IsValueType == true)
                    {
                        il.Emit(OpCodes.Box, item.Source.ActualType);
                    }
                    if (item.Target.ActualType.IsEnum == true)
                    {
                        il.Emit(OpCodes.Callvirt, typeof(TypeConverter).GetMethod("ToEnum", new Type[] { typeof(Object) }).MakeGenericMethod(item.Target.ActualType));
                    }
                    else
                    {
                        il.Emit(OpCodes.Callvirt, typeof(TypeConverter).GetMethod(methodName, new Type[] { typeof(Object) }));
                    }

                    Label ifConvertedValueNotNullBlock = il.DefineLabel();
                    if (item.Target.ActualType == typeof(String))
                    {
                        convertedVal = il.DeclareLocal(item.Target.ActualType);
                        il.SetLocal(targetVal);
                        il.LoadLocal(targetVal);
                        il.Emit(OpCodes.Ldnull);
                        il.Emit(OpCodes.Ceq);
                        il.Emit(OpCodes.Brfalse_S, ifConvertedValueNotNullBlock);
                        {
                            //DoNothing when convert failed
                            il.Emit(OpCodes.Br_S, customConvertStartLabel);
                        }
                        il.MarkLabel(ifConvertedValueNotNullBlock);
                    }
                    else
                    {
                        Type targetTypeN = typeof(Nullable <>).MakeGenericType(item.Target.ActualType);
                        convertedVal = il.DeclareLocal(targetTypeN);
                        //SetValue to TargetObject
                        il.SetLocal(convertedVal);
                        il.LoadLocala(convertedVal);
                        il.Emit(OpCodes.Call, targetTypeN.GetProperty("HasValue").GetGetMethod());
                        il.Emit(OpCodes.Brtrue_S, ifConvertedValueNotNullBlock);
                        {
                            //Try custom convert when convert failed
                            il.Emit(OpCodes.Br_S, customConvertStartLabel);
                        }
                        il.MarkLabel(ifConvertedValueNotNullBlock);
                        //GetValue
                        il.LoadLocala(convertedVal);
                        il.Emit(OpCodes.Call, targetTypeN.GetMethod("GetValueOrDefault", Type.EmptyTypes));
                        il.SetLocal(targetVal);
                    }
                    #endregion
                }
                il.Emit(OpCodes.Br_S, setValueStartLabel);
                #endregion

                #region Call custom convert method or Map method when convert failed. //ObjectMapConfig.Current.Convert<T>(...)
                il.MarkLabel(customConvertStartLabel);
                convertedVal = il.DeclareLocal(item.Target.ActualType);
                //Set up parameter for ObjectMapConfig.Convert<>(sourceVal, convertedVal)
                il.Emit(OpCodes.Ldarg_0);//ObjectMapConfig instance
                il.LoadLocal(sourceVal);
                if (item.Source.ActualType.IsValueType == true)
                {
                    //Boxing to Object
                    il.Emit(OpCodes.Box, item.Source.ActualType);
                }
                il.LoadLocala(convertedVal);

                //public Boolean Convert<T>(Object value, out T convertedValue)
                il.Emit(OpCodes.Call, _ConvertMethod.MakeGenericMethod(item.Target.ActualType));
                var convertResult = il.DeclareLocal(typeof(Boolean));
                il.SetLocal(convertResult);
                il.LoadLocal(convertedVal);
                il.SetLocal(targetVal);

                il.LoadLocal(convertResult);
                il.Emit(OpCodes.Brtrue, setValueStartLabel);
                if (item.Target.IsIndexedProperty == false)
                {
                    //Try Map method when convert failed
                    #region source.P1.Map(target.P1); //Call Map method
                    var targetObj = il.DeclareLocal(item.Target.PropertyType);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Callvirt, item.Target.PropertyInfo.GetGetMethod());
                    il.SetLocal(targetObj);

                    il.Emit(OpCodes.Ldarg_0);//ObjectMapConfig instance
                    il.LoadLocal(sourceVal);
                    il.LoadLocal(targetObj);
                    il.Emit(OpCodes.Ldarg_3);//MappingContext
                    il.Emit(OpCodes.Call, _MapMethod.MakeGenericMethod(item.Source.ActualType, item.Target.PropertyType));
                    il.Emit(OpCodes.Pop);
                    il.Emit(OpCodes.Br, endOfCode);
                    #endregion
                }
                #endregion

                #region Set Null to Target property //tgt.P1 = null
                il.MarkLabel(setNullToTargetLabel);
                {
                    if (item.Target.CanBeNull == true)
                    {
                        il.Emit(OpCodes.Ldarg_2);
                        if (item.Target.IsIndexedProperty == true)
                        {
                            //target["P1"] = source.P1;
                            il.Emit(OpCodes.Ldstr, item.Target.IndexedPropertyKey);
                        }
                        if (item.Target.IsNullableT == true)
                        {
                            var targetValN = il.DeclareLocal(item.Target.PropertyType);
                            il.LoadLocala(targetValN);
                            il.Emit(OpCodes.Initobj, item.Target.PropertyType);
                            il.LoadLocal(targetValN);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldnull);
                        }
                        il.Emit(OpCodes.Callvirt, setMethod);
                    }
                    il.Emit(OpCodes.Br_S, endOfCode);
                }
                #endregion

                #region Set value to TargetProperty
                il.MarkLabel(setValueStartLabel);
                il.Emit(OpCodes.Ldarg_2);
                if (item.Target.IsIndexedProperty == true)
                {
                    //target["P1"] = source.P1;
                    il.Emit(OpCodes.Ldstr, item.Target.IndexedPropertyKey);
                }
                il.LoadLocal(targetVal);
                if (item.Target.IsNullableT == true)
                {
                    //new Nullable<T>(new T());
                    il.Emit(OpCodes.Newobj, item.Target.PropertyType.GetConstructor(new Type[] { item.Target.ActualType }));
                }
                il.Emit(OpCodes.Callvirt, setMethod);
                #endregion

                il.MarkLabel(endOfCode);
                il.Emit(OpCodes.Nop);
            }
            il.Emit(OpCodes.Ret);

            var f  = typeof(Action <, , ,>);
            var gf = f.MakeGenericType(typeof(ObjectMapConfig), sourceType, targetType, typeof(MappingContext));
            return((Action <ObjectMapConfig, TSource, TTarget, MappingContext>)dm.CreateDelegate(gf));
        }
Beispiel #41
0
 internal static Instruction Create(OpCode opcode, LocalBuilder lvar)
 {
     Instruction i = new Instruction();
     i.opCode = opcode;
     i.type = InstructionType.OpCode;
     i.operand = lvar;
     i.operandType = typeof(LocalBuilder);
     return i;
 }
        /// <summary>
        /// Creates the SpringServicedComponent base class to derive all <see cref="ServicedComponent"/>s from.
        /// </summary>
        /// <example>
        /// <code>
        /// internal class SpringServicedComponent: BaseType
        /// {
        ///    protected delegate object GetObjectHandler(ServicedComponent servicedComponent, string targetName);
        ///
        ///    protected static readonly GetObjectHandler getObjectRef;
        ///
        ///    static SpringServicedComponent()
        ///    {
        ///      // first look for a local copy
        ///      System.Reflection.Assembly servicesAssembly;
        ///      string servicesAssemblyPath = Path.Combine(
        ///                                 new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName
        ///                                 , &quot;Spring.Services.dll&quot; );
        ///      servicesAssembly = System.Reflection.Assembly.LoadFrom(servicesAssemblyPath);
        ///      if (servicesAssembly == null)
        ///      {
        ///        // then let the normal loader handle the typeload
        ///        servicesAssembly = System.Reflection.Assembly.Load(&quot;Spring.Services, culture=neutral, version=x.x.x.x, publicKey=xxxxxxxx&quot;);
        ///      }
        ///
        ///      Type componentHelperType = servicesAssembly.GetType(&quot;Spring.EnterpriseServices.ServicedComponentHelper&quot;);
        ///      getObjectRef = (GetObjectHandler) Delegate.CreateDelegate(typeof(GetObjectHandler)
        ///                                                                         , componentHelperType.GetMethod(&quot;GetObject&quot;));
        ///    }
        /// }
        /// </code>
        /// </example>
        public static Type CreateSpringServicedComponentType(ModuleBuilder module, Type baseType)
        {
            if (!typeof(ServicedComponent).IsAssignableFrom(baseType))
            {
                throw new ArgumentException(string.Format("baseType must derive from {0}, was {1}", typeof(ServicedComponent).FullName, baseType), "baseType");
            }

            Type delegateType = DefineDelegate(module);

            TypeBuilder  typeBuilder  = module.DefineType("SpringServicedComponent", System.Reflection.TypeAttributes.Public, baseType);
            ILGenerator  il           = null;
            FieldBuilder getObjectRef = typeBuilder.DefineField("getObject", delegateType, FieldAttributes.Family | FieldAttributes.Static);

            ConstructorBuilder typeCtor = typeBuilder.DefineTypeInitializer();

            il = typeCtor.GetILGenerator();
            Label        methodEnd   = il.DefineLabel();
            Label        loadType    = il.DefineLabel();
            Label        tryBegin    = il.BeginExceptionBlock();
            LocalBuilder fldAssembly = il.DeclareLocal(typeof(Assembly));
            LocalBuilder fldType     = il.DeclareLocal(typeof(Type));
            LocalBuilder fldArgs     = il.DeclareLocal(typeof(object[]));
            LocalBuilder fldMethod   = il.DeclareLocal(typeof(MethodBase));

            il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly"));
            il.Emit(OpCodes.Callvirt, typeof(Assembly).GetProperty("Location").GetGetMethod());
            il.Emit(OpCodes.Newobj, typeof(FileInfo).GetConstructor(new Type[] { typeof(string) }));
            il.Emit(OpCodes.Call, typeof(FileInfo).GetProperty("DirectoryName").GetGetMethod());
            il.Emit(OpCodes.Ldstr, new FileInfo(typeof(ServicedComponentHelper).Assembly.Location).Name);

            il.Emit(OpCodes.Call, typeof(Path).GetMethod("Combine", new Type[] { typeof(string), typeof(string) }));
            il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("LoadFrom", new Type[] { typeof(string) }));
            il.Emit(OpCodes.Stloc, fldAssembly);
            il.Emit(OpCodes.Ldloc, fldAssembly);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Brtrue_S, loadType);

            il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).Assembly.FullName);
            il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("Load", new Type[] { typeof(string) }));
            il.Emit(OpCodes.Stloc, fldAssembly);

            il.MarkLabel(loadType);
            il.Emit(OpCodes.Ldloc, fldAssembly);
            il.Emit(OpCodes.Ldstr, typeof(ServicedComponentHelper).FullName);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetType", new Type[] { typeof(string), typeof(bool) }));
            il.Emit(OpCodes.Stloc, fldType);

            il.Emit(OpCodes.Ldtoken, delegateType);
            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
            il.Emit(OpCodes.Ldloc, fldType);
            il.Emit(OpCodes.Ldstr, "GetObject");
            il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) }));
            il.Emit(OpCodes.Call, typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(MethodInfo) }));
            il.Emit(OpCodes.Castclass, delegateType);
            il.Emit(OpCodes.Stsfld, getObjectRef);

            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, fldArgs);

            il.Emit(OpCodes.Ldloc, fldArgs);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Ldtoken, typeBuilder);
            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
            il.Emit(OpCodes.Stelem_Ref);
            il.Emit(OpCodes.Ldloc, fldType);
            il.Emit(OpCodes.Ldstr, "EnsureComponentContextRegistryInitialized");
            il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) }));
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ldloc, fldArgs);
            il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }));
            il.Emit(OpCodes.Pop);

            il.Emit(OpCodes.Leave_S, methodEnd);

            il.BeginCatchBlock(typeof(Exception));
            il.Emit(OpCodes.Call, typeof(Trace).GetMethod("WriteLine", new Type[] { typeof(object) }));
            il.EndExceptionBlock();
            il.MarkLabel(methodEnd);
            il.Emit(OpCodes.Ret);
            return(typeBuilder.CreateType());
        }
Beispiel #43
0
 public TmpForNDimArr(LocalBuilder clb, Label tlabel, Label flabel)
 {
     this.clb = clb;
     this.tlabel = tlabel;
     this.flabel = flabel;
 }
        private void AddReturn(Type ReturnType, ILGenerator il, MethodBuilder Meth)
        {
            // Place a dummy return value on the stack before we return.
            if (ReturnType == typeof(void))
            {
                // There is nothing to place on the stack.
            }
            else if (ReturnType.IsPrimitive)
            {
                switch (System.Type.GetTypeCode(ReturnType))
                {
                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.Byte:
                case TypeCode.SByte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                    il.Emit(OpCodes.Ldc_I4_0);
                    break;

                case TypeCode.Int64:
                case TypeCode.UInt64:
                    il.Emit(OpCodes.Ldc_I4_0);
                    il.Emit(OpCodes.Conv_I8);
                    break;

                case TypeCode.Single:
                    il.Emit(OpCodes.Ldc_R4, 0);
                    break;

                case TypeCode.Double:
                    il.Emit(OpCodes.Ldc_R4, 0);
                    il.Emit(OpCodes.Conv_R8);
                    break;

                default:
                    // "TypeCode" does not include IntPtr, so special case it.
                    if (ReturnType == typeof(IntPtr))
                    {
                        il.Emit(OpCodes.Ldc_I4_0);
                    }
                    else
                    {
                        Contract.Assert(false, "Unexpected type for Primitive type.");
                    }
                    break;
                }
            }
            else if (ReturnType.IsValueType)
            {
                // Allocate stack space for the return value type.  Zero-init.
                Meth.InitLocals = true;
                LocalBuilder ltRetVal = il.DeclareLocal(ReturnType);

                // Load the value class on the stack.
                il.Emit(OpCodes.Ldloc_S, ltRetVal);
            }
            else
            {
                // The return type is a normal type.
                il.Emit(OpCodes.Ldnull);
            }
        }
Beispiel #45
0
		public virtual void Emit (OpCode opcode, LocalBuilder local)
		{
			throw new PlatformNotSupportedException ();
		}
        private void EmitNullableCoalesce(BinaryExpression b)
        {
            Debug.Assert(b.Method == null);

            LocalBuilder loc       = GetLocal(b.Left.Type);
            Label        labIfNull = _ilg.DefineLabel();
            Label        labEnd    = _ilg.DefineLabel();

            EmitExpression(b.Left);
            _ilg.Emit(OpCodes.Stloc, loc);
            _ilg.Emit(OpCodes.Ldloca, loc);
            _ilg.EmitHasValue(b.Left.Type);
            _ilg.Emit(OpCodes.Brfalse, labIfNull);

            Type nnLeftType = b.Left.Type.GetNonNullableType();

            if (b.Conversion != null)
            {
                Debug.Assert(b.Conversion.ParameterCount == 1);
                ParameterExpression p = b.Conversion.GetParameter(0);
                Debug.Assert(p.Type.IsAssignableFrom(b.Left.Type) ||
                             p.Type.IsAssignableFrom(nnLeftType));

                // emit the delegate instance
                EmitLambdaExpression(b.Conversion);

                // emit argument
                if (!p.Type.IsAssignableFrom(b.Left.Type))
                {
                    _ilg.Emit(OpCodes.Ldloca, loc);
                    _ilg.EmitGetValueOrDefault(b.Left.Type);
                }
                else
                {
                    _ilg.Emit(OpCodes.Ldloc, loc);
                }

                // emit call to invoke
                _ilg.Emit(OpCodes.Callvirt, b.Conversion.Type.GetMethod("Invoke"));
            }
            else if (!TypeUtils.AreEquivalent(b.Type, nnLeftType))
            {
                _ilg.Emit(OpCodes.Ldloca, loc);
                _ilg.EmitGetValueOrDefault(b.Left.Type);
                _ilg.EmitConvertToType(nnLeftType, b.Type, isChecked: true, locals: this);
            }
            else
            {
                _ilg.Emit(OpCodes.Ldloca, loc);
                _ilg.EmitGetValueOrDefault(b.Left.Type);
            }
            FreeLocal(loc);

            _ilg.Emit(OpCodes.Br, labEnd);
            _ilg.MarkLabel(labIfNull);
            EmitExpression(b.Right);
            if (!TypeUtils.AreEquivalent(b.Right.Type, b.Type))
            {
                _ilg.EmitConvertToType(b.Right.Type, b.Type, isChecked: true, locals: this);
            }
            _ilg.MarkLabel(labEnd);
        }
 public virtual void Emit(OpCode opcode, LocalBuilder local);
Beispiel #48
0
        public void StoreLocal(LocalBuilder local)
        {
            Pop(local.LocalType);

            m_Generator.Emit(OpCodes.Stloc, local);
        }
 internal ForState(LocalBuilder indexVar, Label beginLabel, Label testLabel, object end)
 {
     this.indexVar = indexVar;
     this.beginLabel = beginLabel;
     this.testLabel = testLabel;
     this.end = end;
 }
Beispiel #50
0
        public bool CompareTo(int sign, Callback argGenerator)
        {
            Type active = this.Active;

            MethodInfo compareTo = active.GetMethod("CompareTo", new Type[] { active });

            if (compareTo == null)
            {
                /* This gets a little tricky...
                 *
                 * There's a scenario where we might be trying to use CompareTo on an interface
                 * which, while it doesn't explicitly implement CompareTo itself, is said to
                 * extend IComparable indirectly.  The implementation is implicitly passed off
                 * to implementers...
                 *
                 * interface ISomeInterface : IComparable
                 * {
                 *    void SomeMethod();
                 * }
                 *
                 * class SomeClass : ISomeInterface
                 * {
                 *    void SomeMethod() { ... }
                 *    int CompareTo( object other ) { ... }
                 * }
                 *
                 * In this case, calling ISomeInterface.GetMethod( "CompareTo" ) will return null.
                 *
                 * Bleh.
                 */

                Type[] ifaces = active.FindInterfaces(delegate(Type type, object obj)
                {
                    return((type.IsGenericType) &&
                           (type.GetGenericTypeDefinition() == typeof(IComparable <>)) &&
                           (type.GetGenericArguments()[0].IsAssignableFrom(active)));
                }, null);

                if (ifaces.Length > 0)
                {
                    compareTo = ifaces[0].GetMethod("CompareTo", new Type[] { active });
                }
                else
                {
                    ifaces = active.FindInterfaces(delegate(Type type, object obj)
                    {
                        return(type == typeof(IComparable));
                    }, null);

                    if (ifaces.Length > 0)
                    {
                        compareTo = ifaces[0].GetMethod("CompareTo", new Type[] { active });
                    }
                }
            }

            if (compareTo == null)
            {
                return(false);
            }

            if (!active.IsValueType)
            {
                /* This object is a reference type, so we have to make it behave
                 *
                 * null.CompareTo( null ) =  0
                 * real.CompareTo( null ) = -1
                 * null.CompareTo( real ) = +1
                 *
                 */

                LocalBuilder aValue = AcquireTemp(active);
                LocalBuilder bValue = AcquireTemp(active);

                StoreLocal(aValue);

                argGenerator();

                StoreLocal(bValue);

                /* if ( aValue == null )
                 * {
                 *    if ( bValue == null )
                 *       v = 0;
                 *    else
                 *       v = +1;
                 * }
                 * else if ( bValue == null )
                 * {
                 *    v = -1;
                 * }
                 * else
                 * {
                 *    v = aValue.CompareTo( bValue );
                 * }
                 */

                Label store = CreateLabel();

                Label aNotNull = CreateLabel();

                LoadLocal(aValue);
                BranchIfTrue(aNotNull);
                // if ( aValue == null )
                {
                    Label bNotNull = CreateLabel();

                    LoadLocal(bValue);
                    BranchIfTrue(bNotNull);
                    // if ( bValue == null )
                    {
                        Load(0);
                        Pop(typeof(int));
                        Branch(store);
                    }
                    MarkLabel(bNotNull);
                    // else
                    {
                        Load(sign);
                        Pop(typeof(int));
                        Branch(store);
                    }
                }
                MarkLabel(aNotNull);
                // else
                {
                    Label bNotNull = CreateLabel();

                    LoadLocal(bValue);
                    BranchIfTrue(bNotNull);
                    // bValue == null
                    {
                        Load(-sign);
                        Pop(typeof(int));
                        Branch(store);
                    }
                    MarkLabel(bNotNull);
                    // else
                    {
                        LoadLocal(aValue);
                        BeginCall(compareTo);

                        LoadLocal(bValue);
                        ArgumentPushed();

                        FinishCall();

                        if (sign == -1)
                        {
                            Neg();
                        }
                    }
                }

                MarkLabel(store);

                ReleaseTemp(aValue);
                ReleaseTemp(bValue);
            }
            else
            {
                BeginCall(compareTo);

                argGenerator();

                ArgumentPushed();

                FinishCall();

                if (sign == -1)
                {
                    Neg();
                }
            }

            return(true);
        }
Beispiel #51
0
        /// <summary>
        /// do foreach loop
        /// </summary>
        /// <param name="typeBuilder"></param>
        private static void MakeForeachMethod(TypeBuilder typeBuilder)
        {
            //定义一个传入参数为Int32[],返回值为Int32的方法
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("ForeachMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(Int32), new Type[] { typeof(Int32[]) });
            ILGenerator   methodIL      = methodBuilder.GetILGenerator();

            //用来保存求和结果的局部变量
            LocalBuilder sum = methodIL.DeclareLocal(typeof(Int32));
            //foreach中的int i
            LocalBuilder i = methodIL.DeclareLocal(typeof(Int32));
            //用来保存传入的数组
            LocalBuilder ints = methodIL.DeclareLocal(typeof(Int32[]));
            //数组循环用临时变量
            LocalBuilder index = methodIL.DeclareLocal(typeof(Int32));

            Label compareLabel   = methodIL.DefineLabel();
            Label enterLoopLabel = methodIL.DefineLabel();

            //int sum=0;
            methodIL.Emit(OpCodes.Ldc_I4_0);
            methodIL.Emit(OpCodes.Stloc_0);
            //ints=ints
            methodIL.Emit(OpCodes.Ldarg_0);
            methodIL.Emit(OpCodes.Stloc_2);
            //int index=0
            methodIL.Emit(OpCodes.Ldc_I4_0);
            methodIL.Emit(OpCodes.Stloc_3);
            methodIL.Emit(OpCodes.Br, compareLabel);

            //定义一个标签,表示从下面开始进入循环体
            methodIL.MarkLabel(enterLoopLabel);
            //其中Ldelem_I4用来加载一个数组中的Int32类型的元素
            //加载i=ints[index]
            methodIL.Emit(OpCodes.Ldloc_2);
            methodIL.Emit(OpCodes.Ldloc_3);
            methodIL.Emit(OpCodes.Ldelem_I4);
            methodIL.Emit(OpCodes.Stloc_1);

            //sum+=i;
            methodIL.Emit(OpCodes.Ldloc_0);
            methodIL.Emit(OpCodes.Ldloc_1);
            methodIL.Emit(OpCodes.Add);
            methodIL.Emit(OpCodes.Stloc_0);

            //index++
            methodIL.Emit(OpCodes.Ldloc_3);
            methodIL.Emit(OpCodes.Ldc_I4_1);
            methodIL.Emit(OpCodes.Add);
            methodIL.Emit(OpCodes.Stloc_3);

            //定义一个标签,表示从下面开始进入循环的比较
            methodIL.MarkLabel(compareLabel);
            //index < ints.Length
            methodIL.Emit(OpCodes.Ldloc_3);
            methodIL.Emit(OpCodes.Ldloc_2);
            methodIL.Emit(OpCodes.Ldlen);
            methodIL.Emit(OpCodes.Conv_I4);
            methodIL.Emit(OpCodes.Clt);
            methodIL.Emit(OpCodes.Brtrue_S, enterLoopLabel);

            //return sum;
            methodIL.Emit(OpCodes.Ldloc_0);
            methodIL.Emit(OpCodes.Ret);
        }
Beispiel #52
0
        private static void EventMain()
        {
            #region Init

            string          name            = "DynamicPublisher";
            string          fileName        = name + ".dll";
            AssemblyName    asmName         = new AssemblyName(name);
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(name, fileName);

            #endregion

            #region RandGeneratedEventArgs

            TypeBuilder randGeneratedEventArgsTypeBuilder = moduleBuilder.DefineType("RandGeneratedEventArgs", TypeAttributes.Public, typeof(EventArgs));

            #region Field

            FieldBuilder randField = randGeneratedEventArgsTypeBuilder.DefineField("_rand", typeof(Int32), FieldAttributes.Private);

            #endregion

            #region Property

            PropertyBuilder randProperty = randGeneratedEventArgsTypeBuilder.DefineProperty("Rand", PropertyAttributes.HasDefault, typeof(Int32), null);

            #region 定义属性Rand的get方法

            //定义属性Rand的get方法

            MethodBuilder getPropertyRandBuilder = randGeneratedEventArgsTypeBuilder.DefineMethod("get",
                                                                                                  MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
                                                                                                  typeof(Int32),
                                                                                                  Type.EmptyTypes);

            //生成属性Rand的get方法的IL代码,即返回私有字段_a

            ILGenerator getRandIL = getPropertyRandBuilder.GetILGenerator();

            getRandIL.Emit(OpCodes.Ldarg_0);
            getRandIL.Emit(OpCodes.Ldfld, randField);
            getRandIL.Emit(OpCodes.Ret);

            //设置属性A的get和set方法
            randProperty.SetGetMethod(getPropertyRandBuilder);

            #endregion

            #endregion

            #region Ctor

            ConstructorBuilder constructorBuilder = randGeneratedEventArgsTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Int32) });

            ILGenerator ctorIL = constructorBuilder.GetILGenerator();

            //加载参数1填充到私有字段_rand
            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Ldarg_1);
            ctorIL.Emit(OpCodes.Stfld, randField);
            ctorIL.Emit(OpCodes.Ret);

            #endregion

            Type randGeneratedEventArgsType = randGeneratedEventArgsTypeBuilder.CreateType();

            #endregion

            #region Publisher

            TypeBuilder publisherTypeBuilder = moduleBuilder.DefineType("Publisher", TypeAttributes.Public);

            Type eventType = typeof(EventHandler <>).MakeGenericType(randGeneratedEventArgsType);

            #region Field

            FieldBuilder randomField  = publisherTypeBuilder.DefineField("random", typeof(Random), FieldAttributes.Private);
            FieldBuilder isStartField = publisherTypeBuilder.DefineField("isStart", typeof(Boolean), FieldAttributes.Private);
            //通过对自动生成的IL代码的仔细观察,发现系统自动生成了一个与事件同名的私有字段,用来在get set等方法中进行使用
            FieldBuilder randGeneratedField = publisherTypeBuilder.DefineField("RandGenerated", eventType, FieldAttributes.Private);

            #endregion

            #region Ctor

            //注类似private Random random = new Random(DateTime.Now.Millisecond); 的字段初始化,需要在构造函数中进行

            constructorBuilder = publisherTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);

            ctorIL = constructorBuilder.GetILGenerator();

            LocalBuilder dateTime = ctorIL.DeclareLocal(typeof(DateTime));

            //加载参数0/false填充到私有字段isStart
            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Ldc_I4_0);
            ctorIL.Emit(OpCodes.Stfld, isStartField);

            ctorIL.Emit(OpCodes.Ldarg_0);
            //获取DateTime.Now,这里由于DateTime是值类型,所以需要用Ldloca_S方法加载使用
            ctorIL.Emit(OpCodes.Call, typeof(DateTime).GetMethod("get_Now", Type.EmptyTypes));
            ctorIL.Emit(OpCodes.Stloc_0);
            ctorIL.Emit(OpCodes.Ldloca_S, dateTime);
            //获取DateTime.Millisecond,并用此初始化Random对象
            ctorIL.Emit(OpCodes.Call, typeof(DateTime).GetMethod("get_Millisecond", Type.EmptyTypes));
            ctorIL.Emit(OpCodes.Newobj, typeof(Random).GetConstructor(new Type[] { typeof(Int32) }));
            ctorIL.Emit(OpCodes.Stfld, randomField);

            //调用父类的无参构造函数
            ctorIL.Emit(OpCodes.Ldarg_0);
            ctorIL.Emit(OpCodes.Call, typeof(Object).GetConstructor(Type.EmptyTypes));
            ctorIL.Emit(OpCodes.Ret);

            #endregion

            #region Event

            //定义事件,事件的可访问性由和它相关的getset方法决定
            EventBuilder randGeneratedEvent = publisherTypeBuilder.DefineEvent("RandGenerated", EventAttributes.None, eventType);

            MethodBuilder addEventBuilder = publisherTypeBuilder.DefineMethod("add_RandGenerated", MethodAttributes.Public, null, new Type[] { eventType });
            //注意在我们使用事件时,使用的是+=操作,但在IL代码中并不是如此,应该使用Delegate.Combine方法
            ILGenerator addEventIL = addEventBuilder.GetILGenerator();

            addEventIL.Emit(OpCodes.Ldarg_0);
            addEventIL.Emit(OpCodes.Ldarg_0);
            addEventIL.Emit(OpCodes.Ldfld, randGeneratedField);
            addEventIL.Emit(OpCodes.Ldarg_1);
            addEventIL.Emit(OpCodes.Call, typeof(Delegate).GetMethod("Combine", new Type[] { eventType, eventType }));
            //返回的是Delegate类型,所以需要进行转换
            addEventIL.Emit(OpCodes.Castclass, eventType);
            addEventIL.Emit(OpCodes.Stfld, randGeneratedField);

            randGeneratedEvent.SetAddOnMethod(addEventBuilder);

            MethodBuilder removeEventBuilder = publisherTypeBuilder.DefineMethod("remove_RandGenerated", MethodAttributes.Public, null, new Type[] { eventType });
            //注意在我们使用事件时,使用的是-=操作,但在IL代码中并不是如此,应该使用Delegate.Remove方法
            ILGenerator removeEventIL = removeEventBuilder.GetILGenerator();

            removeEventIL.Emit(OpCodes.Ldarg_0);
            removeEventIL.Emit(OpCodes.Ldarg_0);
            removeEventIL.Emit(OpCodes.Ldfld, randGeneratedField);
            removeEventIL.Emit(OpCodes.Ldarg_1);
            removeEventIL.Emit(OpCodes.Call, typeof(Delegate).GetMethod("Remove", new Type[] { eventType, eventType }));
            //返回的是Delegate类型,所以需要进行转换
            removeEventIL.Emit(OpCodes.Castclass, eventType);
            removeEventIL.Emit(OpCodes.Stfld, randGeneratedField);

            randGeneratedEvent.SetRemoveOnMethod(removeEventBuilder);

            #endregion

            #region Method

            #region Stop

            MethodBuilder stopBuilder = publisherTypeBuilder.DefineMethod("Stop", MethodAttributes.Public, null, Type.EmptyTypes);

            ILGenerator stopIL = stopBuilder.GetILGenerator();

            stopIL.Emit(OpCodes.Ldarg_0);
            stopIL.Emit(OpCodes.Ldc_I4_0);
            stopIL.Emit(OpCodes.Stfld, isStartField);
            stopIL.Emit(OpCodes.Ret);

            #endregion

            #region RaiseRandGeneratedEvent

            MethodBuilder raiseRandGeneratedEventBuilder = publisherTypeBuilder.DefineMethod("RaiseRandGeneratedEvent", MethodAttributes.Private, null, new Type[] { typeof(Int32) });

            ILGenerator raiseRandGeneratedEventIL = raiseRandGeneratedEventBuilder.GetILGenerator();

            LocalBuilder temp        = raiseRandGeneratedEventIL.DeclareLocal(eventType);
            LocalBuilder arg         = raiseRandGeneratedEventIL.DeclareLocal(randGeneratedEventArgsType);
            Label        returnLabel = raiseRandGeneratedEventIL.DefineLabel();

            //EventHandler<RandGeneratedEventArgs> temp = RandGenerated;
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldarg_0);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldfld, randGeneratedField);
            raiseRandGeneratedEventIL.Emit(OpCodes.Stloc_0);

            //if (temp == null) return
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldloc_0);
            raiseRandGeneratedEventIL.Emit(OpCodes.Brfalse_S, returnLabel);

            //RandGeneratedEventArgs arg = new RandGeneratedEventArgs(rand);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldarg_1);
            raiseRandGeneratedEventIL.Emit(OpCodes.Newobj, randGeneratedEventArgsType.GetConstructor(new Type[] { typeof(Int32) }));
            raiseRandGeneratedEventIL.Emit(OpCodes.Stloc_1);

            //temp(this, arg);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldloc_0);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldarg_0);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ldloc_1);
            raiseRandGeneratedEventIL.Emit(OpCodes.Callvirt, eventType.GetMethod("Invoke"));

            raiseRandGeneratedEventIL.MarkLabel(returnLabel);
            raiseRandGeneratedEventIL.Emit(OpCodes.Ret);

            #endregion

            #region OnRandGenerated

            MethodBuilder onRandGeneratedBuilder = publisherTypeBuilder.DefineMethod("OnRandGenerated", MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.NewSlot, null, new Type[] { typeof(Int32) });

            ILGenerator onRandGeneratedIL = onRandGeneratedBuilder.GetILGenerator();

            onRandGeneratedIL.Emit(OpCodes.Ldarg_0);
            onRandGeneratedIL.Emit(OpCodes.Ldarg_1);
            onRandGeneratedIL.Emit(OpCodes.Call, raiseRandGeneratedEventBuilder);
            onRandGeneratedIL.Emit(OpCodes.Ret);

            #endregion

            #region GenerateRand

            MethodBuilder generateRandBuilder = publisherTypeBuilder.DefineMethod("GenerateRand", MethodAttributes.Private, null, Type.EmptyTypes);

            ILGenerator generateRandIL = generateRandBuilder.GetILGenerator();

            Label enterLoopLable = generateRandIL.DefineLabel();
            Label compareLable   = generateRandIL.DefineLabel();

            generateRandIL.Emit(OpCodes.Br_S, compareLable);

            generateRandIL.MarkLabel(enterLoopLable);
            //OnRandGenerated(random.Next(10000));
            generateRandIL.Emit(OpCodes.Ldarg_0);
            generateRandIL.Emit(OpCodes.Ldarg_0);
            generateRandIL.Emit(OpCodes.Ldfld, randomField);
            generateRandIL.Emit(OpCodes.Ldc_I4, 10000);
            generateRandIL.Emit(OpCodes.Call, typeof(Random).GetMethod("Next", new Type[] { typeof(Int32) }));
            generateRandIL.Emit(OpCodes.Call, onRandGeneratedBuilder);
            //Thread.Sleep(1000);
            generateRandIL.Emit(OpCodes.Ldc_I4, 1000);
            generateRandIL.Emit(OpCodes.Call, typeof(System.Threading.Thread).GetMethod("Sleep", new Type[] { typeof(Int32) }));

            generateRandIL.MarkLabel(compareLable);
            generateRandIL.Emit(OpCodes.Ldarg_0);
            generateRandIL.Emit(OpCodes.Ldfld, isStartField);
            generateRandIL.Emit(OpCodes.Brtrue_S, enterLoopLable);

            generateRandIL.Emit(OpCodes.Ret);

            #endregion

            #region Start

            MethodBuilder startBuilder = publisherTypeBuilder.DefineMethod("Start", MethodAttributes.Public, null, Type.EmptyTypes);

            ILGenerator startIL = startBuilder.GetILGenerator();

            returnLabel = startIL.DefineLabel();

            //if (isStart) return
            startIL.Emit(OpCodes.Ldarg_0);
            startIL.Emit(OpCodes.Ldfld, isStartField);
            startIL.Emit(OpCodes.Brtrue_S, returnLabel);
            startIL.Emit(OpCodes.Ldarg_0);
            startIL.Emit(OpCodes.Call, generateRandBuilder);

            startIL.MarkLabel(returnLabel);
            startIL.Emit(OpCodes.Ret);

            #endregion

            #endregion

            Type publisherType = publisherTypeBuilder.CreateType();

            #endregion

            //assemblyBuilder.Save(fileName);
            Publisher p = new Publisher();
            p.RandGenerated += new EventHandler <RandGeneratedEventArgs>(p_RandGenerated);
            p.Start();
        }
Beispiel #53
0
 private void freeLocal(LocalBuilder l)
 {
     m_localPool.Add(l);
 }
Beispiel #54
0
 static void EmitComputeBufferLoc(ILGenerator ilg, LocalBuilder bufLocal,
                                  int argnum)
 {
     ilg.Emit(OpCodes.Ldloc, bufLocal);
     ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE);
     ilg.Emit(OpCodes.Add);
 }