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()); }
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)"); }
/// <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!")) )); }
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]); }
public void TestAstExpression() { ; Assert.AreEqual("(3 + 5)", GeneratorCSharp.GenerateRoot(ast.Binary(3, "+", 5)).ToString()); }