Exemplo n.º 1
0
        private Type GenerateEvent(Type eventHandlerType)
        {
            string         str;
            CodeGeneration generation = this;

            lock (generation)
            {
                str = "LuaGeneratedClass" + this.luaClassNumber;
                this.luaClassNumber++;
            }
            TypeBuilder builder = this.newModule.DefineType(str, TypeAttributes.Public, this.eventHandlerParent);

            Type[]      parameterTypes = new Type[] { typeof(object), eventHandlerType };
            Type        returnType     = typeof(void);
            ILGenerator iLGenerator    = builder.DefineMethod("HandleEvent", MethodAttributes.HideBySig | MethodAttributes.Public, returnType, parameterTypes).GetILGenerator();

            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldarg_1);
            iLGenerator.Emit(OpCodes.Ldarg_2);
            MethodInfo method = this.eventHandlerParent.GetMethod("handleEvent");

            iLGenerator.Emit(OpCodes.Call, method);
            iLGenerator.Emit(OpCodes.Ret);
            return(builder.CreateType());
        }
Exemplo n.º 2
0
 static CodeGeneration()
 {
     CodeGeneration.instance = new CodeGeneration();
 }
Exemplo n.º 3
0
        public void GenerateClass(Type klass, out Type newType, out Type[][] returnTypes, LuaTable luaTable)
        {
            string         str;
            TypeBuilder    builder;
            CodeGeneration generation = this;

            lock (generation)
            {
                str = "LuaGeneratedClass" + this.luaClassNumber;
                this.luaClassNumber++;
            }
            if (klass.IsInterface)
            {
                Type[] interfaces = new Type[] { klass, typeof(ILuaGeneratedType) };
                builder = this.newModule.DefineType(str, TypeAttributes.Public, typeof(object), interfaces);
            }
            else
            {
                Type[] typeArray2 = new Type[] { typeof(ILuaGeneratedType) };
                builder = this.newModule.DefineType(str, TypeAttributes.Public, klass, typeArray2);
            }
            FieldBuilder field    = builder.DefineField("__luaInterface_luaTable", typeof(LuaTable), FieldAttributes.Public);
            FieldBuilder builder3 = builder.DefineField("__luaInterface_returnTypes", typeof(Type[][]), FieldAttributes.Public);

            Type[]      parameterTypes = new Type[] { typeof(LuaTable), typeof(Type[][]) };
            ILGenerator iLGenerator    = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes).GetILGenerator();

            iLGenerator.Emit(OpCodes.Ldarg_0);
            if (klass.IsInterface)
            {
                iLGenerator.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
            }
            else
            {
                iLGenerator.Emit(OpCodes.Call, klass.GetConstructor(Type.EmptyTypes));
            }
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldarg_1);
            iLGenerator.Emit(OpCodes.Stfld, field);
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldarg_2);
            iLGenerator.Emit(OpCodes.Stfld, builder3);
            iLGenerator.Emit(OpCodes.Ret);
            BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;

            MethodInfo[] methods = klass.GetMethods(bindingAttr);
            returnTypes = new Type[methods.Length][];
            int methodIndex = 0;

            foreach (MethodInfo info in methods)
            {
                if (klass.IsInterface)
                {
                    this.GenerateMethod(builder, info, MethodAttributes.NewSlot | MethodAttributes.HideBySig | MethodAttributes.Virtual, methodIndex, field, builder3, false, out returnTypes[methodIndex]);
                    methodIndex++;
                }
                else if ((!info.IsPrivate && !info.IsFinal) && (info.IsVirtual && (luaTable[info.Name] != null)))
                {
                    this.GenerateMethod(builder, info, (info.Attributes | MethodAttributes.NewSlot) ^ MethodAttributes.NewSlot, methodIndex, field, builder3, true, out returnTypes[methodIndex]);
                    methodIndex++;
                }
            }
            MethodBuilder methodInfoBody = builder.DefineMethod("__luaInterface_getLuaTable", MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public, typeof(LuaTable), new Type[0]);

            builder.DefineMethodOverride(methodInfoBody, typeof(ILuaGeneratedType).GetMethod("__luaInterface_getLuaTable"));
            iLGenerator = methodInfoBody.GetILGenerator();
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldfld, field);
            iLGenerator.Emit(OpCodes.Ret);
            newType = builder.CreateType();
        }
Exemplo n.º 4
0
        private Type GenerateDelegate(Type delegateType)
        {
            string         str;
            CodeGeneration generation = this;

            lock (generation)
            {
                str = "LuaGeneratedClass" + this.luaClassNumber;
                this.luaClassNumber++;
            }
            TypeBuilder builder = this.newModule.DefineType(str, TypeAttributes.Public, this.delegateParent);
            MethodInfo  method  = delegateType.GetMethod("Invoke");

            ParameterInfo[] parameters     = method.GetParameters();
            Type[]          parameterTypes = new Type[parameters.Length];
            Type            returnType     = method.ReturnType;
            int             num            = 0;
            int             arg            = 0;

            for (int i = 0; i < parameterTypes.Length; i++)
            {
                parameterTypes[i] = parameters[i].ParameterType;
                if (!parameters[i].IsIn && parameters[i].IsOut)
                {
                    num++;
                }
                if (parameterTypes[i].IsByRef)
                {
                    arg++;
                }
            }
            int[]       numArray    = new int[arg];
            ILGenerator iLGenerator = builder.DefineMethod("CallFunction", method.Attributes, returnType, parameterTypes).GetILGenerator();

            iLGenerator.DeclareLocal(typeof(object[]));
            iLGenerator.DeclareLocal(typeof(object[]));
            iLGenerator.DeclareLocal(typeof(int[]));
            if (returnType != typeof(void))
            {
                iLGenerator.DeclareLocal(returnType);
            }
            else
            {
                iLGenerator.DeclareLocal(typeof(object));
            }
            iLGenerator.Emit(OpCodes.Ldc_I4, parameterTypes.Length);
            iLGenerator.Emit(OpCodes.Newarr, typeof(object));
            iLGenerator.Emit(OpCodes.Stloc_0);
            iLGenerator.Emit(OpCodes.Ldc_I4, (int)(parameterTypes.Length - num));
            iLGenerator.Emit(OpCodes.Newarr, typeof(object));
            iLGenerator.Emit(OpCodes.Stloc_1);
            iLGenerator.Emit(OpCodes.Ldc_I4, arg);
            iLGenerator.Emit(OpCodes.Newarr, typeof(int));
            iLGenerator.Emit(OpCodes.Stloc_2);
            int num4 = 0;
            int num5 = 0;
            int num6 = 0;

            while (num4 < parameterTypes.Length)
            {
                iLGenerator.Emit(OpCodes.Ldloc_0);
                iLGenerator.Emit(OpCodes.Ldc_I4, num4);
                iLGenerator.Emit(OpCodes.Ldarg, (int)(num4 + 1));
                if (parameterTypes[num4].IsByRef)
                {
                    if (parameterTypes[num4].GetElementType().IsValueType)
                    {
                        iLGenerator.Emit(OpCodes.Ldobj, parameterTypes[num4].GetElementType());
                        iLGenerator.Emit(OpCodes.Box, parameterTypes[num4].GetElementType());
                    }
                    else
                    {
                        iLGenerator.Emit(OpCodes.Ldind_Ref);
                    }
                }
                else if (parameterTypes[num4].IsValueType)
                {
                    iLGenerator.Emit(OpCodes.Box, parameterTypes[num4]);
                }
                iLGenerator.Emit(OpCodes.Stelem_Ref);
                if (parameterTypes[num4].IsByRef)
                {
                    iLGenerator.Emit(OpCodes.Ldloc_2);
                    iLGenerator.Emit(OpCodes.Ldc_I4, num6);
                    iLGenerator.Emit(OpCodes.Ldc_I4, num4);
                    iLGenerator.Emit(OpCodes.Stelem_I4);
                    numArray[num6] = num4;
                    num6++;
                }
                if (parameters[num4].IsIn || !parameters[num4].IsOut)
                {
                    iLGenerator.Emit(OpCodes.Ldloc_1);
                    iLGenerator.Emit(OpCodes.Ldc_I4, num5);
                    iLGenerator.Emit(OpCodes.Ldarg, (int)(num4 + 1));
                    if (parameterTypes[num4].IsByRef)
                    {
                        if (parameterTypes[num4].GetElementType().IsValueType)
                        {
                            iLGenerator.Emit(OpCodes.Ldobj, parameterTypes[num4].GetElementType());
                            iLGenerator.Emit(OpCodes.Box, parameterTypes[num4].GetElementType());
                        }
                        else
                        {
                            iLGenerator.Emit(OpCodes.Ldind_Ref);
                        }
                    }
                    else if (parameterTypes[num4].IsValueType)
                    {
                        iLGenerator.Emit(OpCodes.Box, parameterTypes[num4]);
                    }
                    iLGenerator.Emit(OpCodes.Stelem_Ref);
                    num5++;
                }
                num4++;
            }
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldloc_0);
            iLGenerator.Emit(OpCodes.Ldloc_1);
            iLGenerator.Emit(OpCodes.Ldloc_2);
            MethodInfo meth = this.delegateParent.GetMethod("callFunction");

            iLGenerator.Emit(OpCodes.Call, meth);
            if (returnType == typeof(void))
            {
                iLGenerator.Emit(OpCodes.Pop);
                iLGenerator.Emit(OpCodes.Ldnull);
            }
            else if (returnType.IsValueType)
            {
                iLGenerator.Emit(OpCodes.Unbox, returnType);
                iLGenerator.Emit(OpCodes.Ldobj, returnType);
            }
            else
            {
                iLGenerator.Emit(OpCodes.Castclass, returnType);
            }
            iLGenerator.Emit(OpCodes.Stloc_3);
            for (int j = 0; j < numArray.Length; j++)
            {
                iLGenerator.Emit(OpCodes.Ldarg, (int)(numArray[j] + 1));
                iLGenerator.Emit(OpCodes.Ldloc_0);
                iLGenerator.Emit(OpCodes.Ldc_I4, numArray[j]);
                iLGenerator.Emit(OpCodes.Ldelem_Ref);
                if (parameterTypes[numArray[j]].GetElementType().IsValueType)
                {
                    iLGenerator.Emit(OpCodes.Unbox, parameterTypes[numArray[j]].GetElementType());
                    iLGenerator.Emit(OpCodes.Ldobj, parameterTypes[numArray[j]].GetElementType());
                    iLGenerator.Emit(OpCodes.Stobj, parameterTypes[numArray[j]].GetElementType());
                }
                else
                {
                    iLGenerator.Emit(OpCodes.Castclass, parameterTypes[numArray[j]].GetElementType());
                    iLGenerator.Emit(OpCodes.Stind_Ref);
                }
            }
            if (returnType != typeof(void))
            {
                iLGenerator.Emit(OpCodes.Ldloc_3);
            }
            iLGenerator.Emit(OpCodes.Ret);
            return(builder.CreateType());
        }