Example #1
0
        public Label DefineLabel()
        {
            if (il == null)
                il = builder.GetILGenerator();

            return il.DefineLabel();
        }
Example #2
0
        public void Emit_UnknownOpCode_ThrowsNotSupportedException()
        {
            var ilGenerator = new ILGenerator(null);
            var opCode = new OpCode(-1);

            ExceptionAssert.Throws<NotSupportedException>(() => ilGenerator.Emit(opCode));
        }
Example #3
0
        public LocalBuilder AddLocal(IKType type)
        {
            if (il == null)
                il = builder.GetILGenerator();

            return il.DeclareLocal(type);
        }
Example #4
0
		public ILGenerator GetILGenerator(int streamSize)
		{
			if (ilgen == null)
			{
				ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize);
			}
			return ilgen;
		}
Example #5
0
		public ILGenerator GetILGenerator(int streamSize)
		{
			if (rva != -1)
			{
				throw new InvalidOperationException();
			}
			if (ilgen == null)
			{
				ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize);
			}
			return ilgen;
		}
Example #6
0
 public EmitCalculator(string term, int a, int b, int c, int d)
 {
     this.dm = new DynamicMethod( "Evaluate"
                                , typeof(int)
                                , new Type[] {typeof(int),typeof(int),typeof(int),typeof(int),typeof(int)}
                                , typeof(int)
                                );
     this.tokens = term.Split(new Char[] {' '});
     this.ilGen = dm.GetILGenerator();
     this.GenCode();
     Evaluate eval = (Evaluate) dm.CreateDelegate(typeof(Evaluate));
     Console.WriteLine(eval(a, b, c, d, 0));
 }
Example #7
0
    public CodeGen(Stmt stmt, string moduleName)
    {
        if (string.IsNullOrEmpty(moduleName)) throw new ArgumentException("must have a module name", "moduleName");

        _stmt = stmt;
        _moduleName = moduleName;
        if (Path.GetFileName(moduleName) != moduleName) throw new Exception("can only output into current directory!");

        var filename = Path.GetFileNameWithoutExtension(moduleName);
        var asmName = new AssemblyName(filename);
        _asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save);
        _modb = _asmb.DefineDynamicModule(moduleName);
        _typeBuilder = _modb.DefineType("Foo");

        _methb = _typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void),
            Type.EmptyTypes);

        _il = _methb.GetILGenerator();
        SymbolTable = new Dictionary<string, LocalBuilder>();
    }
Example #8
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)
        {
            var lblValidateArrayLength = ilg.DefineLabel();
            var lblExit = ilg.DefineLabel();

            // read the array length
            var count = ilg.DeclareLocal(typeof(int));

            ilg.Emit(OpCodes.Ldloc, unpacker);
            ilg.Emit(OpCodes.Ldloca, count);
            ilg.Emit(OpCodes.Call, Methods.Unpacker_TryReadArrayLength);
            ilg.Emit(OpCodes.Brtrue_S, lblValidateArrayLength);

            // test for empty map (empty type)
            ilg.Emit(OpCodes.Ldloc, unpacker);
            ilg.Emit(OpCodes.Call, Methods.Unpacker_TryPeekEmptyMap);

            throwBlocks.ThrowIfFalse(() =>
            {
                ilg.Emit(OpCodes.Ldstr, "Union values must be encoded as an array for property \"{0}\" of type \"{1}\"");
                ilg.Emit(OpCodes.Ldstr, name);
                ilg.LoadType(value.LocalType);
                ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object);
                ilg.LoadType(targetType);
                ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type);
                ilg.Emit(OpCodes.Throw);
            });

            ilg.Emit(OpCodes.Ldnull);
            ilg.Emit(OpCodes.Stloc, value);
            ilg.Emit(OpCodes.Br, lblExit);

            // ensure we have two items in the array
            ilg.MarkLabel(lblValidateArrayLength);
            ilg.Emit(OpCodes.Ldloc, count);
            ilg.Emit(OpCodes.Ldc_I4_2);
            throwBlocks.ThrowIfNotEqual(() =>
            {
                ilg.Emit(OpCodes.Ldstr, "Union array should have 2 elements (not {0}) for property \"{1}\" of type \"{2}\"");
                ilg.Emit(OpCodes.Ldloc, count);
                ilg.Emit(OpCodes.Box, typeof(int));
                ilg.Emit(OpCodes.Ldstr, name);
                ilg.LoadType(value.LocalType);
                ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object_Object);
                ilg.LoadType(targetType);
                ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type);
                ilg.Emit(OpCodes.Throw);
            });

            // read the serialised type name
            var typeName = ilg.DeclareLocal(typeof(string));

            ilg.Emit(OpCodes.Ldloc, unpacker);
            ilg.Emit(OpCodes.Ldloca, typeName);
            ilg.Emit(OpCodes.Call, Methods.Unpacker_TryReadString);

            throwBlocks.ThrowIfFalse(() =>
            {
                ilg.Emit(OpCodes.Ldstr, "Unable to read union type name for property \"{0}\" of type \"{1}\"");
                ilg.Emit(OpCodes.Ldstr, name);
                ilg.LoadType(value.LocalType);
                ilg.Emit(OpCodes.Call, Methods.String_Format_String_Object_Object);
                ilg.LoadType(targetType);
                ilg.Emit(OpCodes.Newobj, Methods.DeserialisationException_Ctor_String_Type);
                ilg.Emit(OpCodes.Throw);
            });

            var success = true;

            // loop through types within the union, looking for a matching type name
            var labelNextType = ilg.DefineLabel();

            foreach (var type in value.LocalType.GetGenericArguments())
            {
                var expectedTypeName = UnionEncoding.GetTypeName(type);

                ilg.Emit(OpCodes.Ldloc, typeName);
                ilg.Emit(OpCodes.Ldstr, expectedTypeName);
                ilg.Emit(OpCodes.Call, Methods.String_Equals_String_String);

                // continue if this type doesn't match the union's values
                ilg.Emit(OpCodes.Brfalse, labelNextType);

                // we have a match
                // read the value
                var readValue = ilg.DeclareLocal(type);
                if (!DeserialiserEmitter.TryEmitDeserialiseCode(ilg, throwBlocks, errors, name, targetType, readValue, unpacker, context, contextLocal, unexpectedFieldBehaviour))
                {
                    errors.Add($"Unable to deserialise union member type {type}");
                    success = false;
                }

                // create the union
                ilg.Emit(OpCodes.Ldloc, readValue);
                ilg.Emit(OpCodes.Call, value.LocalType.GetMethod(nameof(Union <int, int> .Create), new[] { type }));

                // store it in the result value
                ilg.Emit(OpCodes.Stloc, value);

                // exit the loop
                ilg.Emit(OpCodes.Br, lblExit);

                ilg.MarkLabel(labelNextType);
                labelNextType = ilg.DefineLabel();
            }

            // If we exhaust the loop, throws
            ilg.MarkLabel(labelNextType);
            throwBlocks.Throw(() =>
            {
                // TODO include received type name in error message and some more general info
                ilg.Emit(OpCodes.Ldstr, "No match on union type");
                ilg.Emit(OpCodes.Newobj, Methods.Exception_Ctor_String);
                ilg.Emit(OpCodes.Throw);
            });

            ilg.MarkLabel(lblExit);

            return(success);
        }
Example #9
0
        public static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo)
        {
            var         dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
            ILGenerator il            = dynamicMethod.GetILGenerator();

            ParameterInfo[] ps         = methodInfo.GetParameters();
            var             paramTypes = new Type[ps.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    paramTypes[i] = ps[i].ParameterType.GetElementType();
                }
                else
                {
                    paramTypes[i] = ps[i].ParameterType;
                }
            }
            var locals = new LocalBuilder[paramTypes.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                locals[i] = il.DeclareLocal(paramTypes[i], true);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                EmitFastInt(il, i);
                il.Emit(OpCodes.Ldelem_Ref);
                EmitCastToReference(il, paramTypes[i]);
                il.Emit(OpCodes.Stloc, locals[i]);
            }
            if (!methodInfo.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldloca_S, locals[i]);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, locals[i]);
                }
            }
            if (methodInfo.IsStatic)
            {
                il.EmitCall(OpCodes.Call, methodInfo, null);
            }
            else
            {
                il.EmitCall(OpCodes.Callvirt, methodInfo, null);
            }
            if (methodInfo.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                EmitBoxIfNeeded(il, methodInfo.ReturnType);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldarg_1);
                    EmitFastInt(il, i);
                    il.Emit(OpCodes.Ldloc, locals[i]);
                    if (locals[i].LocalType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, locals[i].LocalType);
                    }
                    il.Emit(OpCodes.Stelem_Ref);
                }
            }

            il.Emit(OpCodes.Ret);
            return((FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler)));
        }
Example #10
0
 private void Store(string name, Type type, ILGenerator il)
 {
     if (symbolTable.ContainsKey(name))
     {
         LocalBuilder locb = (LocalBuilder)symbolTable[name];
         if (locb.LocalType == type || (locb.LocalType == typeof(double) && type == typeof(int)))
         {
             il.Emit(OpCodes.Stloc, locb);
         }
         else
         {
             throw new Exception("'" + name + "' is of type " + locb.LocalType.Name
                                     + " but attempted to store value of type " + type.Name);
         }
     }
     else
     {
         throw new Exception("undeclared variable '" + name + "'");
     }
 }
        public static IEnumerable <CodeInstruction> HandleBlockingThingJob(MethodBase __originalMethod, IEnumerable <CodeInstruction> instructions, ILGenerator ilGen)
        {
            var code = instructions.ToList();

            int insertIdx = -1;

            for (int i = 0; i < code.Count; i++)
            {
                if (code[i].opcode == OpCodes.Ldc_I4_4 && code[i + 1].opcode == OpCodes.Bne_Un_S) // if (thing.def.category == ThingCategory.Plant)
                {
                    insertIdx = i + 2;
                }
            }

            if (insertIdx == -1)
            {
                Log.Error($"[HandleBlockingPlants] Can't find insertion place");
                return(code);
            }

            bool isRoofUtility = __originalMethod.DeclaringType == typeof(RoofUtility);
            var  continueLabel = ilGen.DefineLabel();

            code[insertIdx].labels.Add(continueLabel);
            code.InsertRange(insertIdx, new []
            {
                // if (!CanCutBlockingPlant(worker, thing)) return null
                new CodeInstruction(OpCodes.Ldarg_1),
                isRoofUtility ? new CodeInstruction(OpCodes.Ldarg_0) : new CodeInstruction(OpCodes.Ldloc_0), // RoofUtility blocker from argument, GenConstruct blocker from local var
                new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(HandleBlockingPlants), nameof(HandleBlockingPlants.CanCutBlockingPlant))),
                new CodeInstruction(OpCodes.Brtrue_S, continueLabel),
                new CodeInstruction(OpCodes.Ldnull),
                new CodeInstruction(OpCodes.Ret)
            });

            return(code);
        }
Example #12
0
        void EmitSpecial(ILGenerator gen)
        {
            switch (special)
            {
                case Specials.Label:
                    gen.MarkLabel((Label)operand);
                    break;
                case Specials.BeginTry:
                    gen.BeginExceptionBlock();
                    break;
                case Specials.BeginFinally:
                    gen.BeginFinallyBlock();
                    break;
                case Specials.EndTry:
                    gen.EndExceptionBlock();
                    break;
                case Specials.BeginTotemScope:
                    gen.Emit(OpCodes.Nop);
                    gen.Emit(OpCodes.Ldarg_0);
                    gen.Emit(OpCodes.Newobj, Generator.scope_ctor);
                    gen.Emit(OpCodes.Stloc, (LocalBuilder)operand);
                    gen.BeginExceptionBlock();
                    break;
                case Specials.EndTotemScope:
                    var endFinallyLabel = gen.DefineLabel();
                    gen.BeginFinallyBlock();
                    gen.Emit(OpCodes.Ldloc, (LocalBuilder)operand);
                    gen.Emit(OpCodes.Ldnull);
                    gen.Emit(OpCodes.Ceq);
                    gen.Emit(OpCodes.Brtrue, endFinallyLabel);

                    gen.Emit(OpCodes.Ldloc, (LocalBuilder)operand);
                    gen.Emit(OpCodes.Callvirt, Generator.dispose);
                    gen.Emit(OpCodes.Nop);

                    gen.MarkLabel(endFinallyLabel);
                    gen.EndExceptionBlock();
                    break;
                default:
                    throw new InvalidOperationException("default:special");
            }
        }
Example #13
0
	public void Implement(ILGenerator ilg)
	{
		DMethodBody body = Body;

		body.DeclareLocals(ilg);

		for (int i = 0 ; i != body.Code.Length ; i++) {
			if (!body.Code[i].Emit(ilg))
				throw new Exception(String.Format("Code gen failure at i={0} {1}", i, body.Code[i].opCode));
		}
	}
Example #14
0
        private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet)
        {
            OpCode obj, index, value;

            var fail = il.DefineLabel();

            if (mapField == null)
            {
                index = OpCodes.Ldarg_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_2;
            }
            else
            {
                il.DeclareLocal(typeof(int));
                index = OpCodes.Ldloc_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_3;

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, mapField);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldloca_S, (byte)0);
                il.EmitCall(OpCodes.Callvirt, tryGetValue, null);
                il.Emit(OpCodes.Brfalse, fail);
            }
            var labels = new Label[members.Count];

            for (var i = 0; i < labels.Length; i++)
            {
                labels[i] = il.DefineLabel();
            }
            il.Emit(index);
            il.Emit(OpCodes.Switch, labels);
            il.MarkLabel(fail);
            il.Emit(OpCodes.Ldstr, "name");
            il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
            il.Emit(OpCodes.Throw);
            for (var i = 0; i < labels.Length; i++)
            {
                il.MarkLabel(labels[i]);
                var member = members[i];
                var isFail = true;

                void WriteField(FieldInfo fieldToWrite)
                {
                    if (!fieldToWrite.FieldType.IsByRef)
                    {
                        il.Emit(obj);
                        Cast(il, type, true);
                        if (isGet)
                        {
                            il.Emit(OpCodes.Ldfld, fieldToWrite);
                            if (fieldToWrite.FieldType.IsValueType)
                            {
                                il.Emit(OpCodes.Box, fieldToWrite.FieldType);
                            }
                        }
                        else
                        {
                            il.Emit(value);
                            Cast(il, fieldToWrite.FieldType, false);
                            il.Emit(OpCodes.Stfld, fieldToWrite);
                        }
                        il.Emit(OpCodes.Ret);
                        isFail = false;
                    }
                }

                if (member is FieldInfo field)
                {
                    WriteField(field);
                }
                else if (member is PropertyInfo prop)
                {
                    var  propType = prop.PropertyType;
                    bool isByRef = propType.IsByRef, isValid = true;
                    if (isByRef)
                    {
                        if (!isGet && prop.CustomAttributes.Any(x => x.AttributeType.FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute"))
                        {
                            isValid = false;                             // can't assign indirectly to ref-readonly
                        }
                        propType = propType.GetElementType();            // from "ref Foo" to "Foo"
                    }

                    var accessor = (isGet | isByRef) ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors);
                    if (accessor == null && allowNonPublicAccessors && !isByRef)
                    {
                        // No getter/setter, use backing field instead if it exists
                        var backingField = $"<{prop.Name}>k__BackingField";
                        field = prop.DeclaringType?.GetField(backingField, BindingFlags.Instance | BindingFlags.NonPublic);

                        if (field != null)
                        {
                            WriteField(field);
                        }
                    }
                    else if (isValid && prop.CanRead && accessor != null)
                    {
                        il.Emit(obj);
                        Cast(il, type, true);                         // cast the input object to the right target type

                        if (isGet)
                        {
                            il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                            if (isByRef)
                            {
                                il.Emit(OpCodes.Ldobj, propType);                                 // defererence if needed
                            }

                            if (propType.IsValueType)
                            {
                                il.Emit(OpCodes.Box, propType);                                 // box the value if needed
                            }
                        }
                        else
                        {
                            // when by-ref, we get the target managed pointer *first*, i.e. put obj.TheRef on the stack
                            if (isByRef)
                            {
                                il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                            }

                            // load the new value, and type it
                            il.Emit(value);
                            Cast(il, propType, false);

                            if (isByRef)                                 // assign to the managed pointer
                            {
                                il.Emit(OpCodes.Stobj, propType);
                            }
                            else                                   // call the setter
                            {
                                il.EmitCall(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                            }
                        }
                        il.Emit(OpCodes.Ret);
                        isFail = false;
                    }
                }
                if (isFail)
                {
                    il.Emit(OpCodes.Br, fail);
                }
            }
        }
		public void __ReleaseILGenerator()
		{
			if (ilgen != null)
			{
#if !NO_SYMBOL_WRITER
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000), this);
				}
#endif
				rva = ilgen.WriteBody(initLocals);
#if !NO_SYMBOL_WRITER
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.CloseMethod();
				}
#endif
				ilgen = null;
			}
		}
        internal override void MarkSequencePoint(LambdaExpression method, MethodBase methodBase, ILGenerator ilg, DebugInfoExpression sequencePoint)
        {
            MethodBuilder builder = methodBase as MethodBuilder;

            if (builder != null)
            {
                ilg.MarkSequencePoint(GetSymbolWriter(builder, sequencePoint.Document), sequencePoint.StartLine, sequencePoint.StartColumn, sequencePoint.EndLine, sequencePoint.EndColumn);
            }
        }
Example #17
0
        private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult)
        {
            const int dispatchPointerIndex = 0;
            const int memberDispIdIndex    = 1;
            const int flagsIndex           = 2;
            const int dispParamsIndex      = 3;
            const int resultIndex          = 4;
            const int exceptInfoIndex      = 5;
            const int argErrIndex          = 6;

            Debug.Assert(argErrIndex + 1 == typeof(IDispatchInvokeDelegate).GetMethod("Invoke").GetParameters().Length);

            Type[] paramTypes = new Type[argErrIndex + 1];
            paramTypes[dispatchPointerIndex] = typeof(IntPtr);
            paramTypes[memberDispIdIndex]    = typeof(int);
            paramTypes[flagsIndex]           = typeof(ComTypes.INVOKEKIND);
            paramTypes[dispParamsIndex]      = typeof(ComTypes.DISPPARAMS).MakeByRefType();
            paramTypes[resultIndex]          = typeof(Variant).MakeByRefType();
            paramTypes[exceptInfoIndex]      = typeof(ExcepInfo).MakeByRefType();
            paramTypes[argErrIndex]          = typeof(uint).MakeByRefType();

            // Define the dynamic method in our assembly so we skip verification
            DynamicMethod dm     = new DynamicMethod("IDispatchInvoke", typeof(int), paramTypes, DynamicModule);
            ILGenerator   method = dm.GetILGenerator();

            // return functionPtr(...)

            EmitLoadArg(method, dispatchPointerIndex);
            EmitLoadArg(method, memberDispIdIndex);

            // burn the address of our empty IID in directly.  This is never freed, relocated, etc...
            // Note passing this as a Guid directly results in a ~30% perf hit for IDispatch invokes so
            // we also pass it directly as an IntPtr instead.
            if (IntPtr.Size == 4)
            {
                method.Emit(OpCodes.Ldc_I4, UnsafeMethods.NullInterfaceId.ToInt32()); // riid
            }
            else
            {
                method.Emit(OpCodes.Ldc_I8, UnsafeMethods.NullInterfaceId.ToInt64()); // riid
            }

            method.Emit(OpCodes.Conv_I);

            method.Emit(OpCodes.Ldc_I4_0); // lcid
            EmitLoadArg(method, flagsIndex);

            EmitLoadArg(method, dispParamsIndex);

            if (returnResult)
            {
                EmitLoadArg(method, resultIndex);
            }
            else
            {
                method.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField("Zero"));
            }

            EmitLoadArg(method, exceptInfoIndex);
            EmitLoadArg(method, argErrIndex);

            // functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET)
            int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr));

            EmitLoadArg(method, dispatchPointerIndex);
            method.Emit(OpCodes.Ldind_I);
            method.Emit(OpCodes.Ldc_I4, idispatchInvokeOffset);
            method.Emit(OpCodes.Add);
            method.Emit(OpCodes.Ldind_I);

            System.Reflection.Emit.SignatureHelper signature = System.Reflection.Emit.SignatureHelper.GetMethodSigHelper(CallingConvention.Winapi, typeof(int));
            Type[] invokeParamTypes = new Type[] {
                typeof(IntPtr),     // dispatchPointer
                typeof(int),        // memberDispId
                typeof(IntPtr),     // riid
                typeof(int),        // lcid
                typeof(ushort),     // flags
                typeof(IntPtr),     // dispParams
                typeof(IntPtr),     // result
                typeof(IntPtr),     // excepInfo
                typeof(IntPtr),     // argErr
            };
            signature.AddArguments(invokeParamTypes, null, null);
            method.Emit(OpCodes.Calli, signature);

            method.Emit(OpCodes.Ret);
            return((IDispatchInvokeDelegate)dm.CreateDelegate(typeof(IDispatchInvokeDelegate)));
        }
Example #18
0
    static void Main()
    {
        string name = "InMemory";

        AssemblyBuilder asmBldr =
            AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name),
                                                          AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule(name);

        TypeBuilder tb = modBldr.DefineType("DemoVararg");

        // Create a vararg method with no return value and one
        // string argument. (The string argument type is the only
        // element of an array of Type objects.)
        //
        MethodBuilder mb1 = tb.DefineMethod("VarargMethod",
                                            MethodAttributes.Public | MethodAttributes.Static,
                                            CallingConventions.VarArgs,
                                            null,
                                            new Type[] { typeof(string) });

        ILGenerator il1 = mb1.GetILGenerator();

        LocalBuilder locAi   = il1.DeclareLocal(typeof(ArgIterator));
        LocalBuilder locNext = il1.DeclareLocal(typeof(bool));

        Label labelCheckCondition = il1.DefineLabel();
        Label labelNext           = il1.DefineLabel();

        // Load the fixed argument and print it.
        il1.Emit(OpCodes.Ldarg_0);
        il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }));

        // Load the address of the local variable represented by
        // locAi, which will hold the ArgIterator.
        il1.Emit(OpCodes.Ldloca_S, locAi);

        // Load the address of the argument list, and call the
        // ArgIterator constructor that takes an array of runtime
        // argument handles.
        il1.Emit(OpCodes.Arglist);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetConstructor(new Type[] { typeof(RuntimeArgumentHandle) }));

        // Enter the loop at the point where the remaining argument
        // count is tested.
        il1.Emit(OpCodes.Br_S, labelCheckCondition);

        // At the top of the loop, call GetNextArg to get the next
        // argument from the ArgIterator. Convert the typed reference
        // to an object reference and write the object to the console.
        il1.MarkLabel(labelNext);
        il1.Emit(OpCodes.Ldloca_S, locAi);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetNextArg", Type.EmptyTypes));
        il1.Emit(OpCodes.Call, typeof(TypedReference).GetMethod("ToObject"));
        il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(object) }));

        il1.MarkLabel(labelCheckCondition);
        il1.Emit(OpCodes.Ldloca_S, locAi);
        il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetRemainingCount"));

        // If the remaining count is greater than zero, go to
        // the top of the loop.
        il1.Emit(OpCodes.Ldc_I4_0);
        il1.Emit(OpCodes.Cgt);
        il1.Emit(OpCodes.Stloc_1);
        il1.Emit(OpCodes.Ldloc_1);
        il1.Emit(OpCodes.Brtrue_S, labelNext);

        il1.Emit(OpCodes.Ret);

        // Create a method that contains a call to the vararg
        // method.
        MethodBuilder mb2 = tb.DefineMethod("CallVarargMethod",
                                            MethodAttributes.Public | MethodAttributes.Static,
                                            CallingConventions.Standard,
                                            typeof(void), Type.EmptyTypes);
        ILGenerator il2 = mb2.GetILGenerator();

        // Push arguments on the stack: one for the fixed string
        // parameter, and two for the list.
        il2.Emit(OpCodes.Ldstr, "Hello ");
        il2.Emit(OpCodes.Ldstr, "world ");
        il2.Emit(OpCodes.Ldc_I4, 2006);

        // Call the vararg method, specifying the types of the
        // arguments in the list.
        il2.EmitCall(OpCodes.Call, mb1, new Type[] { typeof(string), typeof(int) });

        il2.Emit(OpCodes.Ret);

        Type type = tb.CreateType();

        type.GetMethod("CallVarargMethod").Invoke(null, null);
    }
Example #19
0
 static void emit_ldarg(ILGenerator code, int index)
 {
     switch (index)
     {
     case 0:
         code.Emit(OpCodes.Ldarg_0);
         break;
     case 1:
         code.Emit(OpCodes.Ldarg_1);
         break;
     case 2:
         code.Emit(OpCodes.Ldarg_2);
         break;
     case 3:
         code.Emit(OpCodes.Ldarg_3);
         break;
     default:
         if (index < 0x100)
             code.Emit(OpCodes.Ldarg_S, (byte) index);
         else if (index < 0x8000)
             code.Emit(OpCodes.Ldarg_S, (short) index);
         else
             code.Emit(OpCodes.Ldarg, index);
         break;
     }
 }
Example #20
0
 static void EmitPrepareArgStore(ILGenerator ilg, LocalBuilder bufLocal,
                                 int argnum)
 {
     EmitComputeBufferLoc(ilg, bufLocal, argnum);
     EmitLoadArg(ilg, argnum);
 }
Example #21
0
		public override void GenerateAsStatement (ILGenerator gen)
		{
			exp.GenerateSet (gen, new CodeAddOne (exp));
		}
Example #22
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);
 }
Example #23
0
        private void GenerateMethod(Type interfaceType, FieldBuilder handlerField, TypeBuilder typeBuilder)
        {
            MetaDataFactory.Add(interfaceType);
            MethodInfo[] interfaceMethods = interfaceType.GetMethods();
            if (interfaceMethods != null)
            {
                for (int i = 0; i < interfaceMethods.Length; i++)
                {
                    MethodInfo methodInfo = interfaceMethods[i];
                    // Get the method parameters since we need to create an array
                    // of parameter types
                    ParameterInfo[] methodParams     = methodInfo.GetParameters();
                    int             numOfParams      = methodParams.Length;
                    Type[]          methodParameters = new Type[numOfParams];

                    // convert the ParameterInfo objects into Type
                    for (int j = 0; j < numOfParams; j++)
                    {
                        methodParameters[j] = methodParams[j].ParameterType;
                    }

                    // create a new builder for the method in the interface
                    MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                        methodInfo.Name,
                        MethodAttributes.Public | MethodAttributes.Virtual,
                        CallingConventions.Standard,
                        methodInfo.ReturnType, methodParameters);

                    #region ( "Handler Method IL Code" )
                    ILGenerator methodIL = methodBuilder.GetILGenerator();

                    // Emit a declaration of a local variable if there is a return
                    // type defined
                    if (!methodInfo.ReturnType.Equals(typeof(void)))
                    {
                        methodIL.DeclareLocal(methodInfo.ReturnType);
                        if (methodInfo.ReturnType.IsValueType && !methodInfo.ReturnType.IsPrimitive)
                        {
                            methodIL.DeclareLocal(methodInfo.ReturnType);
                        }
                    }

                    // if we have any parameters for the method, then declare an
                    // Object array local var.
                    if (numOfParams > 0)
                    {
                        methodIL.DeclareLocal(typeof(System.Object[]));
                    }

                    // declare a label for invoking the handler
                    Label handlerLabel = methodIL.DefineLabel();
                    // declare a lable for returning from the mething
                    Label returnLabel = methodIL.DefineLabel();

                    // load "this"
                    methodIL.Emit(OpCodes.Ldarg_0);
                    // load the handler instance variable
                    methodIL.Emit(OpCodes.Ldfld, handlerField);
                    // jump to the handlerLabel if the handler instance variable is not null
                    methodIL.Emit(OpCodes.Brtrue_S, handlerLabel);
                    // the handler is null, so return null if the return type of
                    // the method is not void, otherwise return nothing
                    if (!methodInfo.ReturnType.Equals(typeof(void)))
                    {
                        if (methodInfo.ReturnType.IsValueType && !methodInfo.ReturnType.IsPrimitive && !methodInfo.ReturnType.IsEnum)
                        {
                            methodIL.Emit(OpCodes.Ldloc_1);
                        }
                        else
                        {
                            // load null onto the stack
                            methodIL.Emit(OpCodes.Ldnull);
                        }
                        // store the null return value
                        methodIL.Emit(OpCodes.Stloc_0);
                        // jump to return
                        methodIL.Emit(OpCodes.Br_S, returnLabel);
                    }

                    // the handler is not null, so continue with execution
                    methodIL.MarkLabel(handlerLabel);

                    // load "this"
                    methodIL.Emit(OpCodes.Ldarg_0);
                    // load the handler
                    methodIL.Emit(OpCodes.Ldfld, handlerField);
                    // load "this" since its needed for the call to invoke
                    methodIL.Emit(OpCodes.Ldarg_0);
                    // load the name of the interface, used to get the MethodInfo object
                    // from MetaDataFactory
                    methodIL.Emit(OpCodes.Ldstr, interfaceType.FullName);
                    // load the index, used to get the MethodInfo object
                    // from MetaDataFactory
                    methodIL.Emit(OpCodes.Ldc_I4, i);
                    // invoke GetMethod in MetaDataFactory
                    methodIL.Emit(OpCodes.Call,
                                  typeof(DynamicProxy.MetaDataFactory).GetMethod(
                                      "GetMethod", new Type[] { typeof(string), typeof(int) }));

                    // load the number of parameters onto the stack
                    methodIL.Emit(OpCodes.Ldc_I4, numOfParams);
                    // create a new array, using the size that was just pused on the stack
                    methodIL.Emit(OpCodes.Newarr, typeof(System.Object));

                    // if we have any parameters, then iterate through and set the values
                    // of each element to the corresponding arguments
                    if (numOfParams > 0)
                    {
                        methodIL.Emit(OpCodes.Stloc_1);
                        for (int j = 0; j < numOfParams; j++)
                        {
                            methodIL.Emit(OpCodes.Ldloc_1);
                            methodIL.Emit(OpCodes.Ldc_I4, j);
                            methodIL.Emit(OpCodes.Ldarg, j + 1);
                            if (methodParameters[j].IsValueType)
                            {
                                methodIL.Emit(OpCodes.Box, methodParameters[j]);
                            }
                            methodIL.Emit(OpCodes.Stelem_Ref);
                        }
                        methodIL.Emit(OpCodes.Ldloc_1);
                    }

                    // call the Invoke method
                    methodIL.Emit(OpCodes.Callvirt,
                                  typeof(DynamicProxy.IProxyInvocationHandler).GetMethod("Invoke"));

                    if (!methodInfo.ReturnType.Equals(typeof(void)))
                    {
                        // if the return type if a value type, then unbox the return value
                        // so that we don't get junk.
                        if (methodInfo.ReturnType.IsValueType)
                        {
                            methodIL.Emit(OpCodes.Unbox, methodInfo.ReturnType);
                            if (methodInfo.ReturnType.IsEnum)
                            {
                                methodIL.Emit(OpCodes.Ldind_I4);
                            }
                            else if (!methodInfo.ReturnType.IsPrimitive)
                            {
                                methodIL.Emit(OpCodes.Ldobj, methodInfo.ReturnType);
                            }
                            else
                            {
                                methodIL.Emit((OpCode)opCodeTypeMapper[methodInfo.ReturnType]);
                            }
                        }

                        // store the result
                        methodIL.Emit(OpCodes.Stloc_0);
                        // jump to the return statement
                        methodIL.Emit(OpCodes.Br_S, returnLabel);
                        // mark the return statement
                        methodIL.MarkLabel(returnLabel);
                        // load the value stored before we return.  This will either be
                        // null (if the handler was null) or the return value from Invoke
                        methodIL.Emit(OpCodes.Ldloc_0);
                    }
                    else
                    {
                        // pop the return value that Invoke returned from the stack since
                        // the method's return type is void.
                        methodIL.Emit(OpCodes.Pop);
                        //mark the return statement
                        methodIL.MarkLabel(returnLabel);
                    }

                    // Return
                    methodIL.Emit(OpCodes.Ret);
                    #endregion
                }
            }

            // Iterate through the parent interfaces and recursively call this method
            foreach (Type parentType in interfaceType.GetInterfaces())
            {
                GenerateMethod(parentType, handlerField, typeBuilder);
            }
        }
		public static IEnumerable<CodeInstruction> Formatted(IEnumerable<CodeInstruction> instructions, ILGenerator iLGenerator)
		{
			List<CodeInstruction> instructionsList = instructions.ToList();
			Type loadLockObjectType = typeof(List<string>);
			List<CodeInstruction> loadLockObjectInstructions = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Ldarg_1),
			};
			List<CodeInstruction> searchInstructions = loadLockObjectInstructions.ListFullCopy();
			searchInstructions.Add(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Enumerable), "ToList").MakeGenericMethod(typeof(string))));
			searchInstructions.Add(new CodeInstruction(OpCodes.Stloc_S, 5));

			Type loadLockObjectType2 = typeof(List<object>);
			List<CodeInstruction> loadLockObjectInstructions2 = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Ldarg_2),
			};
			List<CodeInstruction> searchInstructions2 = loadLockObjectInstructions2.ListFullCopy();
			searchInstructions2.Add(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Enumerable), "ToList").MakeGenericMethod(typeof(object))));
			searchInstructions2.Add(new CodeInstruction(OpCodes.Stloc_S, 6));

			/* Original PathFinder.FindPath
			
			---START ORIG---	IL_000b: ldsfld bool Verse.GrammarResolverSimple::working
			
			---END ORIG---

			---START TARGET---
			IL_0000: ldc-i4-1
			---END TARGET---


			*/
			//LocalBuilder tmpCells = iLGenerator.DeclareLocal(typeof(List<IntVec3>));
			int i = 0;
			//yield return new CodeInstruction(OpCodes.Newobj, typeof(List<IntVec3>).GetConstructor(Type.EmptyTypes));
			//yield return new CodeInstruction(OpCodes.Stloc_S, tmpCells.LocalIndex);
			int matchesFound = 0;
			
			while (i < instructionsList.Count)
			{
				//---START ORIG-- -
				//	IL_000b: ldsfld bool Verse.GrammarResolverSimple::working
				//-- - END ORIG-- -

				//---START TARGET-- -
				//IL_0000: Ldc_I4_0
				//-- - END TARGET-- -
				if (
					instructionsList[i].opcode == OpCodes.Ldsfld &&
					(FieldInfo)instructionsList[i].operand == AccessTools.Field(typeof(GrammarResolverSimple), "working")
					)
				{
					instructionsList[i].opcode = OpCodes.Ldc_I4_1;
					instructionsList[i].operand = null;
					yield return instructionsList[i];
					i++;
				}
				else if (RimThreadedHarmony.IsCodeInstructionsMatching(searchInstructions, instructionsList, i))
				{
					matchesFound++;
					foreach (CodeInstruction codeInstruction in RimThreadedHarmony.GetLockCodeInstructions(
						iLGenerator, instructionsList, i, searchInstructions.Count, loadLockObjectInstructions, loadLockObjectType))
					{
						yield return codeInstruction;
					}
					i += searchInstructions.Count;
				}
				else if (RimThreadedHarmony.IsCodeInstructionsMatching(searchInstructions2, instructionsList, i))
				{
					matchesFound++;
					foreach (CodeInstruction codeInstruction in RimThreadedHarmony.GetLockCodeInstructions(
						iLGenerator, instructionsList, i, searchInstructions2.Count, loadLockObjectInstructions2, loadLockObjectType2))
					{
						yield return codeInstruction;
					}
					i += searchInstructions.Count;
				}
				else
				{
					yield return instructionsList[i];
					i++;
				}
			}
			if (matchesFound < 2)
			{
				Log.Error("IL code instructions not found");
			}
		}
Example #25
0
 public void Emit(ILGenerator gen)
 {
     switch (type)
     {
         case InstructionType.OpCode:
             EmitOpCode(gen);
             break;
         case InstructionType.Special:
             EmitSpecial(gen);
             break;
         default:
             throw new InvalidOperationException("Invalid type");
     }
 }
Example #26
0
 private static void EmitCreationMethod(Type targetType, ConstructorInfo constructor, ILGenerator il)
 {
     EmitParameters(il, constructor.GetParameters());
     EmitObjectCreationAndExit(constructor, il, targetType);
 }
Example #27
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);
 }
Example #28
0
 private static void EmitArrayElementToStack(ILGenerator il, int i)
 {
     il.Emit(OpCodes.Ldarg_0);
     il.Emit(OpCodes.Ldc_I4, i);
     il.Emit(OpCodes.Ldelem_Ref);
 }
Example #29
0
 static void EmitLoadArg(ILGenerator ilg, int argnum)
 {
     switch (argnum) {
     case 0:
         ilg.Emit(OpCodes.Ldarg_1);
         break;
     case 1:
         ilg.Emit(OpCodes.Ldarg_2);
         break;
     case 2:
         ilg.Emit(OpCodes.Ldarg_3);
         break;
     default:
         if (argnum < 254)
             ilg.Emit(OpCodes.Ldarg_S, argnum + 1);
         else
             ilg.Emit(OpCodes.Ldarg, argnum + 1);
         break;
     }
 }
Example #30
0
        private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField, bool allowNonPublicAccessors, bool isGet)
        {
            OpCode obj, index, value;

            Label fail = il.DefineLabel();

            if (mapField == null)
            {
                index = OpCodes.Ldarg_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_2;
            }
            else
            {
                il.DeclareLocal(typeof(int));
                index = OpCodes.Ldloc_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_3;

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, mapField);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldloca_S, (byte)0);
                il.EmitCall(OpCodes.Callvirt, tryGetValue, null);
                il.Emit(OpCodes.Brfalse, fail);
            }
            Label[] labels = new Label[members.Count];
            for (int i = 0; i < labels.Length; i++)
            {
                labels[i] = il.DefineLabel();
            }
            il.Emit(index);
            il.Emit(OpCodes.Switch, labels);
            il.MarkLabel(fail);
            il.Emit(OpCodes.Ldstr, "name");
            il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new Type[] { typeof(string) }));
            il.Emit(OpCodes.Throw);
            for (int i = 0; i < labels.Length; i++)
            {
                il.MarkLabel(labels[i]);
                var          member = members[i];
                bool         isFail = true;
                FieldInfo    field;
                PropertyInfo prop;
                if ((field = member as FieldInfo) != null)
                {
                    il.Emit(obj);
                    Cast(il, type, true);
                    if (isGet)
                    {
                        il.Emit(OpCodes.Ldfld, field);
                        if (_IsValueType(field.FieldType))
                        {
                            il.Emit(OpCodes.Box, field.FieldType);
                        }
                    }
                    else
                    {
                        il.Emit(value);
                        Cast(il, field.FieldType, false);
                        il.Emit(OpCodes.Stfld, field);
                    }
                    il.Emit(OpCodes.Ret);
                    isFail = false;
                }
                else if ((prop = member as PropertyInfo) != null)
                {
                    MethodInfo accessor;
                    if (prop.CanRead && (accessor = isGet ? prop.GetGetMethod(allowNonPublicAccessors) : prop.GetSetMethod(allowNonPublicAccessors)) != null)
                    {
                        il.Emit(obj);
                        Cast(il, type, true);
                        if (isGet)
                        {
                            il.EmitCall(_IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                            if (_IsValueType(prop.PropertyType))
                            {
                                il.Emit(OpCodes.Box, prop.PropertyType);
                            }
                        }
                        else
                        {
                            il.Emit(value);
                            Cast(il, prop.PropertyType, false);
                            il.EmitCall(_IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                        }
                        il.Emit(OpCodes.Ret);
                        isFail = false;
                    }
                }
                if (isFail)
                {
                    il.Emit(OpCodes.Br, fail);
                }
            }
        }
Example #31
0
        /// <summary>
        /// TOO MUCH OF A MESS TO EXPLAIN
        /// </summary>
        /// <returns>Madness.</returns>
        private static IEnumerable <CodeInstruction> ReorderWidgetFromEventToInputTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            MethodInfo GetCurrent            = AccessTools.Property(typeof(Event), nameof(Event.current)).GetGetMethod();
            MethodInfo GetRawType            = AccessTools.Property(typeof(Event), nameof(Event.rawType)).GetGetMethod();
            MethodInfo NoMouseButtonsPressed = AccessTools.Method(typeof(Numbers), nameof(NoMouseButtonsPressed));
            MethodInfo WasClicked            = AccessTools.Method(typeof(Numbers), nameof(WasClicked));

            FieldInfo released = AccessTools.Field(typeof(ReorderableWidget), "released");

            bool yieldNext = true;

            List <CodeInstruction> instructionArr = instructions.ToList();

            for (int i = 0; i < instructionArr.ToArray().Length; i++)
            {
                CodeInstruction instruction = instructionArr[i];
                if (instruction.operand != null && instruction.operand == GetCurrent)
                {
                    if (instructionArr[i + 1].operand != null && instructionArr[i + 1].operand == GetRawType)
                    {
                        //L_02bc: Label1
                        //L_02bc: call UnityEngine.Event get_current()
                        //L_02c1: callvirt EventType get_rawType()
                        //L_02c6: ldc.i4.1
                        // =>
                        // call Input.GetMouseButtonUp(1) (or 0)
                        yield return(new CodeInstruction(OpCodes.Nop)
                        {
                            labels = new List <Label> {
                                generator.DefineLabel()
                            }
                        });

                        instruction.opcode  = OpCodes.Call;
                        instruction.operand = NoMouseButtonsPressed;
                        instructionArr.RemoveAt(i + 1);
                    }
                }
                if (instruction.opcode == OpCodes.Stsfld && instruction.operand == released)
                {
                    yield return(instruction);

                    CodeInstruction codeInst = new CodeInstruction(OpCodes.Ldarg_2)
                    {
                        labels = new List <Label> {
                            generator.DefineLabel(),
                        }
                    };
                    codeInst.labels.AddRange(instructionArr[i + 1].labels);
                    yield return(codeInst);

                    yield return(new CodeInstruction(OpCodes.Call, WasClicked));

                    yieldNext = false;
                }

                if (!yieldNext && instruction.opcode == OpCodes.Ldarg_1)
                {
                    yieldNext = true;
                }

                if (yieldNext)
                {
                    yield return(instruction);
                }

                if (instruction.opcode == OpCodes.Call && instruction.operand == AccessTools.Method(typeof(Mouse), nameof(Mouse.IsOver)))
                {
                    yield return(new CodeInstruction(OpCodes.And));
                }
            }
        }
 private void EmitArrayIndexer()
 {
     Node.Target.AcceptVisitor(ILGenerator, Visitor);
     Node.Arguments.ForEach(arg => arg.AcceptVisitor(ILGenerator, Visitor));
     ILGenerator.EmitLoadElementByType(Type.GetElementType());
 }
        private static void AddProperty(
            PropertyInfo propertyInfo,
            Type composedPropertyType,
            DataMemberAttribute dataMemberAttribute,
            TypeBuilder typeBuilder
        )
        {
            string propertyName = dataMemberAttribute.Name as string ?? propertyInfo.Name;

            // generating property
            PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, composedPropertyType, null);

            Type dataMemberAttributeType = typeof(DataMemberAttribute);
            var dataMemberProps = new PropertyInfo[]
            {
                dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.Name)),
                dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.IsRequired)),
                dataMemberAttributeType.GetProperty(nameof(DataMemberAttribute.EmitDefaultValue))
            };

            var dataMemberPropValues = new object[] {
                propertyName,
                dataMemberAttribute.IsRequired,
                dataMemberAttribute.EmitDefaultValue
            };

            CustomAttributeBuilder dataMemberAttributeBuilder = new CustomAttributeBuilder(
                dataMemberAttributeType.GetConstructor(Type.EmptyTypes),
                new object[0],
                dataMemberProps,
                dataMemberPropValues
            );

            propertyBuilder.SetCustomAttribute(dataMemberAttributeBuilder);

            // generating private field
            FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, composedPropertyType, FieldAttributes.Private);
            CustomAttributeBuilder hideFieldAttributeBuilder = new CustomAttributeBuilder(
                typeof(DebuggerBrowsableAttribute).GetConstructor(new[] { typeof(DebuggerBrowsableState) }),
                new object[] { DebuggerBrowsableState.Never }
            );
            fieldBuilder.SetCustomAttribute(hideFieldAttributeBuilder);

            // generating public getter/setter
            MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, composedPropertyType, Type.EmptyTypes);
            ILGenerator getIl = getPropMthdBldr.GetILGenerator();

            getIl.Emit(OpCodes.Ldarg_0);
            getIl.Emit(OpCodes.Ldfld, fieldBuilder);
            getIl.Emit(OpCodes.Ret);

            MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName,
                MethodAttributes.Public |
                MethodAttributes.SpecialName |
                MethodAttributes.HideBySig,
                null, new[] { composedPropertyType });

            ILGenerator setIl = setPropMthdBldr.GetILGenerator();
            Label modifyProperty = setIl.DefineLabel();
            Label exitSet = setIl.DefineLabel();

            setIl.MarkLabel(modifyProperty);
            setIl.Emit(OpCodes.Ldarg_0);
            setIl.Emit(OpCodes.Ldarg_1);
            setIl.Emit(OpCodes.Stfld, fieldBuilder);

            setIl.Emit(OpCodes.Nop);
            setIl.MarkLabel(exitSet);
            setIl.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
Example #34
0
        private static TypeBuilder AddPropertyToTypeBuilder(TypeBuilder typeBuilder, Type properType, string name)
        {
            if (typeof(IList).IsAssignableFrom(properType))
            {
                //ignore
            }

            //if complex type - use recurrence
            else if (!(properType.GetTypeInfo().IsValueType ||
                       properType == typeof(string)))
            {
                properType = DecorateObjectWithAvroAttributes(properType).GetType();
            }

            //mimic property
            PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, properType, null);

            var attributeConstructor = typeof(DataMemberAttribute).GetConstructor(new Type[] { });
            var attributeProperties  = typeof(DataMemberAttribute).GetProperties();
            var attributeBuilder     = new CustomAttributeBuilder(attributeConstructor, new string[] { }, attributeProperties.Where(p => p.Name == "Name").ToArray(), new object[] { name });

            propertyBuilder.SetCustomAttribute(attributeBuilder);

            //Add nullable attribute
            if (Nullable.GetUnderlyingType(properType) != null ||
                properType == typeof(string))
            {
                var nullableAttributeConstructor = typeof(NullableSchemaAttribute).GetConstructor(new Type[] { });
                var nullableAttributeBuilder     = new CustomAttributeBuilder(nullableAttributeConstructor, new string[] { }, new PropertyInfo[] { }, new object[] { });

                propertyBuilder.SetCustomAttribute(nullableAttributeBuilder);
            }

            // Define field
            FieldBuilder fieldBuilder = typeBuilder.DefineField(name, properType, FieldAttributes.Public);

            // Define "getter" for property
            MethodBuilder getterBuilder = typeBuilder.DefineMethod("get_" + name,
                                                                   MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
                                                                   properType,
                                                                   Type.EmptyTypes);
            ILGenerator getterIL = getterBuilder.GetILGenerator();

            getterIL.Emit(OpCodes.Ldarg_0);
            getterIL.Emit(OpCodes.Ldfld, fieldBuilder);
            getterIL.Emit(OpCodes.Ret);


            // Define "setter" for property
            MethodBuilder setterBuilder = typeBuilder.DefineMethod("set_" + name,
                                                                   MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
                                                                   null,
                                                                   new Type[] { properType });
            ILGenerator setterIL = setterBuilder.GetILGenerator();

            setterIL.Emit(OpCodes.Ldarg_0);
            setterIL.Emit(OpCodes.Ldarg_1);
            setterIL.Emit(OpCodes.Stfld, fieldBuilder);
            setterIL.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getterBuilder);
            propertyBuilder.SetSetMethod(setterBuilder);


            return(typeBuilder);
        }
Example #35
0
        public bool TryEmitSerialiseCode(ILGenerator ilg, ThrowBlockGatherer throwBlocks, ICollection <string> errors, LocalBuilder value, LocalBuilder packer, LocalBuilder contextLocal, DasherContext context)
        {
            // write header
            ilg.Emit(OpCodes.Ldloc, packer);
            ilg.Emit(OpCodes.Ldc_I4_2);
            ilg.Emit(OpCodes.Call, Methods.Packer_PackArrayHeader);

            // TODO might be faster if we a generated class having members for use with called 'Union<>.Match'

            var typeObj = ilg.DeclareLocal(typeof(Type));

            ilg.Emit(OpCodes.Ldloc, value);
            ilg.Emit(OpCodes.Callvirt, value.LocalType.GetProperty(nameof(Union <int, int> .Type)).GetMethod);
            ilg.Emit(OpCodes.Stloc, typeObj);

            // write type name
            ilg.Emit(OpCodes.Ldloc, packer);
            ilg.Emit(OpCodes.Ldloc, typeObj);
            ilg.Emit(OpCodes.Call, Methods.UnionEncoding_GetTypeName);
            ilg.Emit(OpCodes.Call, Methods.Packer_Pack_String);

            var success = true;

            // loop through types within the union, looking for a match
            var doneLabel     = ilg.DefineLabel();
            var labelNextType = ilg.DefineLabel();

            foreach (var type in value.LocalType.GetGenericArguments())
            {
                ilg.LoadType(type);
                ilg.Emit(OpCodes.Ldloc, typeObj);
                ilg.Emit(OpCodes.Call, Methods.Object_Equals_Object_Object);

                // continue if this type doesn't match the union's values
                ilg.Emit(OpCodes.Brfalse, labelNextType);

                // we have a match

                // get the value
                var valueObj = ilg.DeclareLocal(type);
                ilg.Emit(OpCodes.Ldloc, value);
                ilg.Emit(OpCodes.Callvirt, value.LocalType.GetProperty(nameof(Union <int, int> .Value)).GetMethod);
                ilg.Emit(type.GetTypeInfo().IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);
                ilg.Emit(OpCodes.Stloc, valueObj);

                // write value
                if (!SerialiserEmitter.TryEmitSerialiseCode(ilg, throwBlocks, errors, valueObj, packer, context, contextLocal))
                {
                    errors.Add($"Unable to serialise union member type {type}");
                    success = false;
                }

                ilg.Emit(OpCodes.Br, doneLabel);

                ilg.MarkLabel(labelNextType);
                labelNextType = ilg.DefineLabel();
            }

            ilg.MarkLabel(labelNextType);

            throwBlocks.Throw(() =>
            {
                ilg.Emit(OpCodes.Ldstr, "No match on union type");
                ilg.Emit(OpCodes.Newobj, Methods.Exception_Ctor_String);
                ilg.Emit(OpCodes.Throw);
            });

            ilg.MarkLabel(doneLabel);

            return(success);
        }
        /// <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());
        }
Example #37
0
		public override void Generate (ILGenerator gen)
		{
			exp.GenerateSet (gen, new CodeAddOne (exp));
			exp.Generate (gen);
		}
Example #38
0
        private static TypeBuilder CreateDynamicPropertyAccessor(Type _targetType, String mProperty)
        {
            Hashtable   hashtable = getInitTypes();
            TypeBuilder builder   = getDynamicType(_targetType, mProperty);

            builder.AddInterfaceImplementation(typeof(IPropertyAccessor));
            Type[]      parameterTypes = new Type[] { typeof(Object) };
            Type        returnType     = typeof(Object);
            ILGenerator iLGenerator    = builder.DefineMethod("Get", MethodAttributes.Virtual | MethodAttributes.Public, returnType, parameterTypes).GetILGenerator();
            MethodInfo  method         = _targetType.GetMethod("get_" + mProperty);

            if (method != null)
            {
                iLGenerator.DeclareLocal(typeof(Object));
                iLGenerator.Emit(OpCodes.Ldarg_1);
                iLGenerator.Emit(OpCodes.Castclass, _targetType);
                iLGenerator.EmitCall(OpCodes.Call, method, null);
                if (method.ReturnType.IsValueType)
                {
                    iLGenerator.Emit(OpCodes.Box, method.ReturnType);
                }
                iLGenerator.Emit(OpCodes.Stloc_0);
                iLGenerator.Emit(OpCodes.Ldloc_0);
            }
            else
            {
                iLGenerator.ThrowException(typeof(MissingMethodException));
            }
            iLGenerator.Emit(OpCodes.Ret);
            Type[]      arrTypes   = new Type[] { typeof(Object), typeof(Object) };
            Type        t          = null;
            ILGenerator mGenerator = builder.DefineMethod("Set", MethodAttributes.Virtual | MethodAttributes.Public, t, arrTypes).GetILGenerator();
            MethodInfo  methodInfo = _targetType.GetMethod("set_" + mProperty);

            if (methodInfo != null)
            {
                Type parameterType = methodInfo.GetParameters()[0].ParameterType;
                mGenerator.DeclareLocal(parameterType);
                mGenerator.Emit(OpCodes.Ldarg_1);
                mGenerator.Emit(OpCodes.Castclass, _targetType);
                mGenerator.Emit(OpCodes.Ldarg_2);
                if (parameterType.IsValueType)
                {
                    mGenerator.Emit(OpCodes.Unbox, parameterType);
                    if (hashtable[parameterType] != null)
                    {
                        OpCode opcode = (OpCode)hashtable[parameterType];
                        mGenerator.Emit(opcode);
                    }
                    else
                    {
                        mGenerator.Emit(OpCodes.Ldobj, parameterType);
                    }
                }
                else
                {
                    mGenerator.Emit(OpCodes.Castclass, parameterType);
                }
                mGenerator.EmitCall(OpCodes.Callvirt, methodInfo, null);
            }
            else
            {
                mGenerator.ThrowException(typeof(MissingMethodException));
            }
            mGenerator.Emit(OpCodes.Ret);
            return(_typeBuilder);
        }
Example #39
0
		public override void GenerateSet (ILGenerator gen, CodeExpression value)
		{
			exp.GenerateSet (gen, value);
		}
Example #40
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! */
    }
Example #41
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);
 }
Example #42
0
    public void FunctionDef(FunctionDef e)
    {
	Type[] param = new Type[e.Count];
	DoVars = new Hashtable();
	
	for (int i = 0; i < e.Count; i++){
	    param[i] = (Type)e.Params[i];
	}
	
	//DescriptorInfo di = new DescriptorInfo(param);
	//di.SetReturnType(e.ExpType);
	//di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public;
	methodb = tb.DefineMethod(e.Name, MethodAttributes.Static | MethodAttributes.Public, e.ExpType, param);
	Functions.Add(e.Name, methodb);
	ILGenerator ilmain = il;
	il = methodb.GetILGenerator();

	e.Body.Visit(this);
	
	il.Emit(OpCodes.Ret);
	il = ilmain;
    }
Example #43
0
 void Generate()
 {
     if (il == null)
         il = builder.GetILGenerator();
     foreach (var i in instructions)
         i.Emit(il);
 }
 // UnboxIfNeeded
 private static void UnboxIfNeeded(Type type, ILGenerator generator)
 {
     if (type.IsValueType)
     {
         generator.Emit(OpCodes.Unbox_Any, type);
     }
 }
Example #45
0
 void EmitOpCode(ILGenerator gen)
 {
     TypeSwitch(
         new Action<Empty>(v => gen.Emit(opCode)),
         new Action<IKMethod>(m => gen.Emit(opCode, m)),
         new Action<IKCtor>(ctor => gen.Emit(opCode, ctor)),
         new Action<IKType>(type => gen.Emit(opCode, type)),
         new Action<string>(str => gen.Emit(opCode, str)),
         new Action<long>(num => gen.Emit(opCode, num)),
         new Action<LocalBuilder>(lvar => gen.Emit(opCode, lvar)),
         new Action<Label>(label => gen.Emit(opCode, label))
     );
 }
Example #46
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);
 }
Example #47
0
        public EventLogger(object item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            log = new EventLog();

            Type         itemType = item.GetType();
            AssemblyName name     = new AssemblyName();

            name.Name = "EventLoggerAssembly";
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder   module   = assembly.DefineDynamicModule("EventLoggerAssembly", "EventLoggerAssembly.dll");

            Type ListType = log.GetType();

            TypeBuilder        logType  = module.DefineType("Logger");
            FieldBuilder       logField = logType.DefineField("log", ListType, FieldAttributes.Public);
            ConstructorBuilder logCtor  = logType.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type [] { ListType, typeof(object) });

            logCtor.DefineParameter(1, ParameterAttributes.None, "test");
            logCtor.DefineParameter(2, ParameterAttributes.None, "obj");
            ILGenerator logIL = logCtor.GetILGenerator();

            logIL.Emit(OpCodes.Ldarg_0);
            logIL.Emit(OpCodes.Ldarg_1);
            logIL.Emit(OpCodes.Stfld, logField);


            foreach (EventInfo Event in itemType.GetEvents())
            {
                ILGenerator il;

                MethodInfo    invoke = Event.EventHandlerType.GetMethod("Invoke");
                MethodBuilder method = logType.DefineMethod(Event.Name, MethodAttributes.Public, null, new Type [] { invoke.GetParameters() [0].ParameterType, invoke.GetParameters() [1].ParameterType });
                method.DefineParameter(1, ParameterAttributes.None, "test");
                method.DefineParameter(2, ParameterAttributes.None, "test2");
                il = method.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, logField);
                il.Emit(OpCodes.Ldstr, Event.Name);
                il.Emit(OpCodes.Callvirt, ListType.GetMethod("Add"));
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ret);

                logIL.Emit(OpCodes.Ldarg_2);
                logIL.Emit(OpCodes.Ldarg_0);
                logIL.Emit(OpCodes.Dup);
                logIL.Emit(OpCodes.Ldvirtftn, method);
                logIL.Emit(OpCodes.Newobj, Event.EventHandlerType.GetConstructor(new Type [] { typeof(object), typeof(IntPtr) }));
                logIL.Emit(OpCodes.Call, Event.GetAddMethod());
            }

            logIL.Emit(OpCodes.Ret);
            Type builtLogType = logType.CreateType();

            instance = builtLogType.GetConstructors() [0].Invoke(new object [] { log, item });
            TestHelper.RemoveWarning(instance);

            //assembly.Save ("EventLoggerAssembly.dll");
        }
Example #48
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);
    }
Example #49
0
 private void VerifyDeclareLocal(ILGenerator generator)
 {
     for (int i = 0; i < TestData.Length; i++)
     {
         LocalBuilder local = generator.DeclareLocal(TestData[i]);
         Assert.Equal(TestData[i], local.LocalType);
         Assert.Equal(i, local.LocalIndex);
         Assert.False(local.IsPinned);
     }
 }
        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();
        }
Example #51
0
    public void Generate(String filename)
    {
	AppDomain ad = Thread.GetDomain(); //AppDomain.CreateDomain("First", null, null);
	AssemblyName an = new AssemblyName();
    an.Name = filename + ".exe"; //AssemblyName.CreateSimpleName(filename + ".exe", "LispExe", "Lisp Executable", "default_alias");
	AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
	ModuleBuilder mb = ab.DefineDynamicModule(filename + ".exe", filename + ".exe");
	MethodBuilder methodb;
	//DescriptorInfo di = new DescriptorInfo(0);
	tb = mb.DefineType(filename);
	
	//di.SetReturnType(typeof(void));
	//di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public;
	methodb = tb.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), null);
	il = methodb.GetILGenerator();

	do{
	    expr.Head.Visit(this);
    	    if (expr.Head is FunctionDef)
    		GenerateDefStub(((FunctionDef)expr.Head).Name);
     	    else if (expr.Head is GlobalVarDef)
    		GenerateDefStub(((GlobalVarDef)expr.Head).Name);
 	    else if (expr.Head.ExpType == typeof(int))
  		GenerateNumericExpStub();
    	    else if (expr.Head.ExpType == typeof(bool))
		GenerateBoolExpStub();
    	    else if (expr.Head.ExpType == typeof(CList)) 
    		GenerateListExpStub();
	    
	    expr = expr.Tail;
	}while(expr != null);
	
	il.Emit(OpCodes.Ret);
	tb.CreateType();
	
	ab.SetEntryPoint((mb.GetType(filename)).GetMethod("Main"));
	ab.Save(filename + ".exe");
    }
Example #52
0
        public void EmitMethodBody(ILGenerator il, MethodInfo method, int methodIndex, FieldInfo field)
        {
            Type actualReturnType;

            if (method.ReturnType == typeof(Task))
            {
                actualReturnType = null;
            }
            else if (method.ReturnType.GetTypeInfo().IsGenericType&&
                     method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                actualReturnType = method.ReturnType.GenericTypeArguments[0];
            }
            else
            {
                throw new ArgumentException("Only tasks are supported as return type.", method.ToString());
            }


            var parameters = method.GetParameters();

            il.DeclareLocal(typeof(object[]));
            il.DeclareLocal(typeof(InvocationInfo));
            il.DeclareLocal(typeof(MethodInfo));

            //load all parameters in object[]
            PushArguments(parameters, il);

            //load the method
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, _getMethods);
            il.Emit(OpCodes.Ldc_I4, methodIndex);
            il.Emit(OpCodes.Ldelem_Ref);             //load array[index]
            il.Emit(OpCodes.Stloc_2);

            //new InvocationInfo(method, object[])
            il.Emit(OpCodes.Ldloc_2);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Newobj, _invocationInfoCtor);

            il.Emit(OpCodes.Stloc_1);

            il.Emit(OpCodes.Ldarg_0);


            il.Emit(OpCodes.Call, _getInterceptor);
            il.Emit(OpCodes.Ldloc_1);

            var interceptionMethod = actualReturnType == null
                                ? _asyncHandlerMethod
                                : _asyncHandlerMethodGeneric.MakeGenericMethod(actualReturnType);

            il.Emit(OpCodes.Callvirt, interceptionMethod);

            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Call, _invocationReturn);

            if (actualReturnType != null)
            {
                il.Emit(OpCodes.Castclass, method.ReturnType);
            }

            il.Emit(OpCodes.Ret);
        }
Example #53
0
		internal void Bake()
		{
			this.signature = this.ModuleBuilder.GetSignatureBlobIndex(this.MethodSignature);

			if (ilgen != null)
			{
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000));
				}
				rva = ilgen.WriteBody(initLocals);
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.CloseMethod();
				}
				ilgen = null;
			}
			else
			{
				rva = -1;
			}

			if (declarativeSecurity != null)
			{
				this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity);
			}
		}
Example #54
0
 abstract public void BuildAssembly(ILGenerator il);
Example #55
0
	public void DeclareLocals(ILGenerator ilg)
	{
		foreach (string local in Locals) {
			Type t;
			if (!ILReader2.TryGetType(local, out t))
				break;
			ilg.DeclareLocal(t);
		}
	}
Example #56
0
    public static void Main()
    {
        // Get the assembly that contains the Timer type (Sytem.dll).
        // The following code uses the fact that System.dll has the
        // same public key as mscorlib.dll to construct a string
        // representing the full assembly name.
        string fullName = "";

        foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies())
        {
            if (assem.GetName().Name == "mscorlib")
            {
                fullName = assem.FullName;
            }
        }
        Assembly sys = Assembly.Load("System" + fullName.Substring(fullName.IndexOf(",")));

        // Get a Type object representing the Timer type.
        Type t = sys.GetType("System.Timers.Timer");

        // Create an instance of the Timer type.
        timer = Activator.CreateInstance(t);

        // Use reflection to get the Elapsed event.
        EventInfo eInfo = t.GetEvent("Elapsed");

        // In order to create a method to handle the Elapsed event,
        // it is necessary to know the signature of the delegate
        // used to raise the event. Reflection.Emit can then be
        // used to construct a dynamic class with a static method
        // that has the correct signature.

        // Get the event handler type of the Elapsed event. This is
        // a delegate type, so it has an Invoke method that has
        // the same signature as the delegate. The following code
        // creates an array of Type objects that represent the
        // parameter types of the Invoke method.
        //
        Type       handlerType  = eInfo.EventHandlerType;
        MethodInfo invokeMethod = handlerType.GetMethod("Invoke");

        ParameterInfo[] parms     = invokeMethod.GetParameters();
        Type[]          parmTypes = new Type[parms.Length];
        for (int i = 0; i < parms.Length; i++)
        {
            parmTypes[i] = parms[i].ParameterType;
        }

        // Use Reflection.Emit to create a dynamic assembly that
        // will be run but not saved. An assembly must have at
        // least one module, which in this case contains a single
        // type. The only purpose of this type is to contain the
        // event handler method. (In the .NET Framework version
        // 2.0 you can use dynamic methods, which are simpler
        // because there is no need to create an assembly, module,
        // or type.)
        AssemblyName aName = new AssemblyName();

        aName.Name = "DynamicTypes";
        AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
        ModuleBuilder   mb = ab.DefineDynamicModule(aName.Name);
        TypeBuilder     tb = mb.DefineType("Handler", TypeAttributes.Class | TypeAttributes.Public);

        // Create the method that will handle the event. The name
        // is not important. The method is static, because there is
        // no reason to create an instance of the dynamic type.
        //
        // The parameter types and return type of the method are
        // the same as those of the delegate's Invoke method,
        // captured earlier.
        MethodBuilder handler = tb.DefineMethod("DynamicHandler",
                                                MethodAttributes.Public | MethodAttributes.Static,
                                                invokeMethod.ReturnType, parmTypes);

        // Generate code to handle the event. In this case, the
        // handler simply prints a text string to the console.
        //
        ILGenerator il = handler.GetILGenerator();

        il.EmitWriteLine("Timer's Elapsed event is raised.");
        il.Emit(OpCodes.Ret);

        // CreateType must be called before the Handler type can
        // be used. In order to create the delegate that will
        // handle the event, a MethodInfo from the finished type
        // is required.
        Type       finished     = tb.CreateType();
        MethodInfo eventHandler = finished.GetMethod("DynamicHandler");

        // Use the MethodInfo to create a delegate of the correct
        // type, and call the AddEventHandler method to hook up
        // the event.
        Delegate d = Delegate.CreateDelegate(handlerType, eventHandler);

        eInfo.AddEventHandler(timer, d);

        // Late-bound calls to the Interval and Enabled property
        // are required to enable the timer with a one-second
        // interval.
        t.InvokeMember("Interval", BindingFlags.SetProperty, null, timer, new Object[] { 1000 });
        t.InvokeMember("Enabled", BindingFlags.SetProperty, null, timer, new Object[] { true });

        Console.WriteLine("Press the Enter key to end the program.");
        Console.ReadLine();
    }
Example #57
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}");
                }
            }
        }
Example #58
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            List <CodeInstruction> newInstructions = ListPool <CodeInstruction> .Shared.Rent(instructions);

            int offset = -6;
            int index  = newInstructions.FindIndex(i => i.opcode == OpCodes.Ret) + offset;

            Label returnLabel = generator.DefineLabel();

            newInstructions.InsertRange(index, new CodeInstruction[]
            {
                // Player.Get(ReferenceHub);
                new(OpCodes.Ldarg_0),
                new(OpCodes.Ldfld, Field(typeof(InventorySystem.Inventory), nameof(InventorySystem.Inventory._hub))),
                new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),

                // ammoType
                new(OpCodes.Ldarg_1),

                // amount
                new(OpCodes.Ldarg_2),

                // var ev = DroppingAmmoEventArgs(...)
                new(OpCodes.Ldc_I4_1),
                new(OpCodes.Newobj, GetDeclaredConstructors(typeof(DroppingAmmoEventArgs))[0]),
                new(OpCodes.Dup),

                // Player.OnDroppingAmmo(ev);
                new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnDroppingAmmo))),

                // if (!ev.IsAllowed) return;
                new(OpCodes.Callvirt, PropertyGetter(typeof(DroppingAmmoEventArgs), nameof(DroppingAmmoEventArgs.IsAllowed))),
                new(OpCodes.Brfalse_S, returnLabel),
            });
Example #59
0
		public void __ReleaseILGenerator()
		{
			if (ilgen != null)
			{
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000));
				}
				rva = ilgen.WriteBody(initLocals);
				if (this.ModuleBuilder.symbolWriter != null)
				{
					this.ModuleBuilder.symbolWriter.CloseMethod();
				}
				ilgen = null;
			}
		}
Example #60
0
 private void GenStmt(Stmt stmt, ILGenerator il, Type[] argtypes)
 {
     if (stmt is VarDeclaration)
     {
         VarDeclaration var = (VarDeclaration)stmt;
         string tname = var.Type.GetTypeName();
         if (typeTable.ContainsKey(tname))
         {
             TypeBuilder typeBuilder = typeTable[tname];
             ConstructorBuilder ctorBuilder = ctorTable[tname];
             LocalBuilder localBuilder = il.DeclareLocal(typeBuilder);
             symbolTable[var.Name] = localBuilder;
             il.Emit(OpCodes.Newobj, ctorBuilder);
             il.Emit(OpCodes.Stloc, localBuilder);
         }
         else
         {
             Type vtype = var.Type.GetAType();
             symbolTable[var.Name] = il.DeclareLocal(vtype);
             GenExpr(var.Expr, TypeOfExpr(var.Expr, argtypes), il, argtypes);
             Store(var.Name, TypeOfExpr(var.Expr, argtypes), il);
         }
     }
     else if (stmt is Assign)
     {
         Assign assign = (Assign)stmt;
         GenExpr(assign.Expr, TypeOfExpr(assign.Expr, argtypes), il, argtypes);
         Store(assign.Name, TypeOfExpr(assign.Expr, argtypes), il);
     }
     else if (stmt is ExprStmt)
     {
         Expr expr = ((ExprStmt)stmt).Expr;
         if (expr is FuncCall)
         {
             FuncCall funcCall = (FuncCall)expr;
             if (funcCall.Name.Count > 1 && funcCall.Name[0] != "System")
             {
                 if (symbolTable.ContainsKey(funcCall.Name[0]))
                 {
                     LocalBuilder localBuilder = (LocalBuilder)symbolTable[funcCall.Name[0]];
                     il.Emit(OpCodes.Ldloc, localBuilder);
                 }
             }
             Type[] typeArgs = new Type[funcCall.Args.Count];
             for (int i = 0; i < funcCall.Args.Count; i++)
             {
                 typeArgs[i] = TypeOfExpr(funcCall.Args[i], argtypes);
                 GenExpr(funcCall.Args[i], typeArgs[i], il, argtypes);
             }
             string strFunc = funcCall.Name[funcCall.Name.Count - 1];    // "WriteLine"
             if (funcCall.Name[0] == "System")
             {
                 string strType = funcCall.Name[0];
                 for (int i = 1; i < funcCall.Name.Count - 1; i++)
                 {
                     strType += "." + funcCall.Name[i];
                 }
                 Type typeFunc = Type.GetType(strType);          // System.Console
                 il.Emit(OpCodes.Call, typeFunc.GetMethod(strFunc, typeArgs));
             }
             else if (funcCall.Name.Count > 1)
             {
                 MethodBuilder methodBuilder = funcTable[strFunc];
                 il.EmitCall(OpCodes.Call, methodBuilder, null);
             }
             else
             {
                 if (!funcTable.ContainsKey(strFunc))
                 {
                     throw new Exception("undeclared function '" + strFunc + "'");
                 }
                 MethodBuilder funcBuilder = funcTable[strFunc];
                 il.EmitCall(OpCodes.Call, funcBuilder, null);
             }
         }
     }
 }