Ejemplo n.º 1
0
        public void TestZeroMinusNumber()
        {
            var Node = (AstNode)ast.Binary(ast.Immediate(0), "-", ast.Argument <int>(0, "Arg"));

            Assert.AreEqual("(0 - Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
            Node = new AstOptimizer().Optimize(Node);
            Assert.AreEqual("(-Arg)", new GeneratorCSharp().GenerateRoot(Node).ToString());
        }
Ejemplo n.º 2
0
        public void TestBenchmark()
        {
            var generatorCSharp = new GeneratorCSharp();
            var astNode         = ast.Ternary(ast.Unary("-", ast.Binary(ast.Binary(10, "+", 11), "*", 2)), 1, 2);

            for (var n = 0; n < 20000; n++)
            {
                generatorCSharp.Reset().GenerateRoot(astNode);
            }
            Assert.Equal(generatorCSharp.ToString(), "((-((10 + 11) * 2)) ? 1 : 2)");
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Generates an assembly code that will decode an integer with a set of InstructionInfo.
        /// </summary>
        /// <param name="instructionInfoList"></param>
        /// <param name="generateCallDelegate"></param>
        /// <param name="level"></param>
        public static AstNodeStm GenerateSwitchCode(IEnumerable <InstructionInfo> instructionInfoList,
                                                    Func <InstructionInfo, AstNodeStm> generateCallDelegate, int level = 0)
        {
            //var ILGenerator = SafeILGenerator._UnsafeGetILGenerator();
            var instructionInfos = instructionInfoList as InstructionInfo[] ?? instructionInfoList.ToArray();
            var commonMask       =
                instructionInfos.Aggregate(0xFFFFFFFF, (Base, instructionInfo) => Base & instructionInfo.Mask);
            var maskGroups = instructionInfos.GroupBy(instructionInfo => instructionInfo.Value & commonMask);

#if false
            int  ShiftOffset       = 0;
            var  CommonMaskShifted = CommonMask >> ShiftOffset;
            uint MinValue          = 0;
#else
            var shiftOffset       = BitUtils.GetFirstBit1(commonMask);
            var commonMaskShifted = commonMask >> shiftOffset;
            var enumerable        = maskGroups as IGrouping <uint, InstructionInfo>[] ?? maskGroups.ToArray();
            var minValue          = enumerable
                                    .Select(maskGroup => (maskGroup.First().Value >> shiftOffset) & commonMaskShifted).Min();
#endif

            //var MaskGroupsCount = MaskGroups.Count();

            //Console.WriteLine("[" + Level + "]{0:X}", CommonMask);
            //var MaskedLocal = SafeILGenerator.DeclareLocal<int>();

            return(Ast.Statements(
                       Ast.Switch(
                           Ast.Binary(
                               Ast.Binary(Ast.Binary(Ast.Argument <uint>(0), ">>", shiftOffset), "&", commonMaskShifted),
                               "-", minValue),
                           Ast.Default(generateCallDelegate(null)),
                           enumerable.Select(maskGroup =>
                                             Ast.Case(
                                                 ((maskGroup.First().Value >> shiftOffset) & commonMaskShifted) - minValue,
                                                 (maskGroup.Count() > 1)
                                ? GenerateSwitchCode(maskGroup, generateCallDelegate, level + 1)
                                : generateCallDelegate(maskGroup.First())
                                                 )
                                             ).ToArray()
                           ),
                       Ast.Throw(Ast.New <Exception>("Unexpected reach!"))
                       ));
        }
Ejemplo n.º 4
0
        public static MethodInfo GetFastMemoryReader(IntPtr fixedGlobalAddress)
        {
            var cacheKey = new CacheKey {
                FixedGlobalAddress = fixedGlobalAddress
            };

            if (Cache.ContainsKey(cacheKey))
            {
                return(Cache[cacheKey]);
            }
            const string dllName    = "FastPspMemoryUtils_Gen.dll";
            const string typeName   = "Memory";
            const string methodName = "Get";
            //var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("FastPspMemoryUtils_Gen"), AssemblyBuilderAccess.RunAndCollect, dllName);
            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("FastPspMemoryUtils_Gen"), AssemblyBuilderAccess.RunAndCollect);

            //var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyBuilder.GetName().Name, dllName, true);
            var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyBuilder.GetName().Name);
            var typeBuilder   = moduleBuilder.DefineType(typeName,
                                                         TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.Class);
            var method = typeBuilder.DefineMethod(methodName,
                                                  MethodAttributes.Final | MethodAttributes.Public | MethodAttributes.Static,
                                                  CallingConventions.Standard, typeof(void *), new[] { typeof(uint) });
            var constructorInfo = typeof(MethodImplAttribute).GetConstructor(new[] { typeof(MethodImplOptions) });

            method.SetCustomAttribute(new CustomAttributeBuilder(
                                          constructorInfo,
                                          new object[] { MethodImplOptions.AggressiveInlining }));

            var constructor = typeof(TargetedPatchingOptOutAttribute).GetConstructor(new[] { typeof(string) });

            method.SetCustomAttribute(new CustomAttributeBuilder(
                                          constructor,
                                          new object[] { "Performance critical to inline across NGen image boundaries" }));
            //Method.GetILGenerator();

            var astTree = ast.Return(
                ast.Cast(
                    typeof(void *),
                    ast.Immediate(fixedGlobalAddress) + ast.Binary(ast.Argument <uint>(0), "&",
                                                                   ast.Immediate(FastPspMemory.FastMemoryMask))
                    )
                );

            new GeneratorIl().Reset().Init(method, method.GetILGenerator()).GenerateRoot(astTree);

            var type = typeBuilder.CreateType();

            Cache[cacheKey] = type.GetMethod(methodName);
            return(Cache[cacheKey]);
        }
Ejemplo n.º 5
0
 public void TestAstExpression()
 {
     ;
     Assert.AreEqual("(3 + 5)", GeneratorCSharp.GenerateRoot(ast.Binary(3, "+", 5)).ToString());
 }