コード例 #1
0
        public static void GenerateLoop(GenerationContextBase context, LocalBuilder countLocal, LocalBuilder loopControlLocal, Action loopAction, bool reversed = false)
        {
            var loopLabel       = context.Generator.DefineLabel();
            var loopFinishLabel = context.Generator.DefineLabel();

            if (reversed)
            {
                context.Generator.PushLocalValueOntoStack(countLocal);
                context.Generator.PushIntegerOntoStack(1);
                context.Generator.Emit(OpCodes.Sub); // put <<countLocal>> - 1 on stack
            }
            else
            {
                context.Generator.PushIntegerOntoStack(0); // put <<0> on stack
            }

            context.Generator.StoreLocalValueFromStack(loopControlLocal); // initialize <<loopControl>> variable using value from stack

            context.Generator.MarkLabel(loopLabel);
            context.Generator.PushLocalValueOntoStack(loopControlLocal);

            if (reversed)
            {
                context.Generator.PushIntegerOntoStack(-1);
            }
            else
            {
                context.Generator.PushLocalValueOntoStack(countLocal);
            }
            context.Generator.Emit(OpCodes.Beq, loopFinishLabel);

            loopAction();

            context.Generator.PushLocalValueOntoStack(loopControlLocal);
            context.Generator.PushIntegerOntoStack(reversed ? -1 : 1);
            context.Generator.Emit(OpCodes.Add);
            context.Generator.StoreLocalValueFromStack(loopControlLocal); // change <<loopControl>> variable by one

            context.Generator.Emit(OpCodes.Br, loopLabel);                // jump to the next loop iteration

            context.Generator.MarkLabel(loopFinishLabel);
        }
コード例 #2
0
        public static void DumpToLibrary <T>(GenerationContextBase context, Action <GenerationContextBase> generateCodeAction, string postfix = null)
        {
            var invokeMethod  = typeof(T).GetMethod("Invoke");
            var returnType    = invokeMethod.ReturnType;
            var argumentTypes = invokeMethod.GetParameters().Select(x => x.ParameterType).ToArray();

            if (postfix != null)
            {
                foreach (var c in new[] { '`', '<', '>', ',', '[', ']' })
                {
                    postfix = postfix.Replace(c, '_');
                }
            }

            var name            = string.Format("{0}_{1}", counter++, postfix);
            var aname           = new AssemblyName(name);
            var assembly        = AppDomain.CurrentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Save);
            var customAttribute = new CustomAttributeBuilder(
                typeof(DebuggableAttribute).GetConstructor(new[] { typeof(DebuggableAttribute.DebuggingModes) }),
                new object[] { DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.Default }
                );

            assembly.SetCustomAttribute(customAttribute);

            var module = assembly.DefineDynamicModule(aname.Name, aname.Name + ".dll", true);
            var type   = module.DefineType("T");
            var method = type.DefineMethod("M", MethodAttributes.Public, returnType, argumentTypes);

            var generator = method.GetILGenerator();

            generateCodeAction(context.WithGenerator(generator));
            generator.Emit(OpCodes.Ret);

            type.CreateType();
            assembly.Save(aname.Name + ".dll");
        }
コード例 #3
0
        public static void GenerateLoop(GenerationContextBase context, LocalBuilder countLocal, Action <LocalBuilder> loopAction, bool reversed = false)
        {
            var loopControlLocal = context.Generator.DeclareLocal(typeof(int));

            GenerateLoop(context, countLocal, loopControlLocal, () => loopAction(loopControlLocal), reversed);
        }