public JSExpression Translate(CilAssembly assembly, CilType type, CilMethod method) { if (type.IsIgnored) { throw new ArgumentException("cannot translate method of ignored class"); } if (method.NeedTranslation == false) { return(null); } var r = method.GetReplacement(); if (r != null && r.Kind == ReplacementKind.Function) { return(new JSRaw { Value = r.Replacement }); } if (type.IsUserDelegate) { return(TranslateDelegateMethod(method)); } else { return(TranslateNormalMethod(assembly, type, method)); } }
public void Visit(CilAssembly assembly) { _writer.WriteLine(); _writer.WriteLine("// Copyright (c) Microsoft Corporation. All rights reserved."); _writer.WriteLine(); _writer.WriteLine(); _writer.WriteLine(); foreach(var moduleRef in assembly.ModuleReferences) { moduleRef.Accept(this); } foreach (var assemblyRef in assembly.AssemblyReferences) { assemblyRef.Accept(this); } WriteAssemblyDefinition(assembly); _writer.WriteLine(); _writer.WriteLine("// =============== CLASS MEMBERS DECLARATION ==================="); _writer.WriteLine(); foreach (var type in assembly.TypeDefinitions) { if (type.Token == 33554433) continue; //skipping <Module> type definition for emitting correct IL. type.Accept(this); } }
public void Visit(CilAssembly assembly) { _writer.WriteLine(); _writer.WriteLine("// Copyright (c) Microsoft Corporation. All rights reserved."); _writer.WriteLine(); _writer.WriteLine(); _writer.WriteLine(); foreach (var moduleRef in assembly.ModuleReferences) { moduleRef.Accept(this); } foreach (var assemblyRef in assembly.AssemblyReferences) { assemblyRef.Accept(this); } WriteAssemblyDefinition(assembly); _writer.WriteLine(); _writer.WriteLine("// =============== CLASS MEMBERS DECLARATION ==================="); _writer.WriteLine(); foreach (var type in assembly.TypeDefinitions) { if (type.Token == 33554433) { continue; //skipping <Module> type definition for emitting correct IL. } type.Accept(this); } }
public void TestMethod1() { Stopwatch watch = new Stopwatch(); try { string path = "Assemblies/mscorlib.dll"; if (!File.Exists(path)) { Assert.Fail("File not found"); return; } var assembly = CilAssembly.Create(path); watch.Start(); using (StreamWriter file = new StreamWriter("../../Output/foo.il")) { assembly.WriteTo(file); watch.Stop(); file.WriteLine("//Time elapsed: " + watch.Elapsed); assembly.Dispose(); } } catch (Exception e) { Assert.Fail(e.Message); return; } Assert.IsTrue(true); }
public BlockTranslator(Context context, CilAssembly assembly, CilType type, CilMethod method, JSExpression this_) : base(context) { this.type = type; this.assembly = assembly; this.method = method; this.this_ = this_; }
private void WriteAssemblyDefinition(CilAssembly assembly) { WriteIndentation(); _writer.Write(".assembly "); _writer.Write(assembly.Flags); _writer.WriteLine(assembly.Name); WriteIndentation(); _writer.WriteLine('{'); Indent(); foreach (var attribute in assembly.CustomAttributes) { attribute.Accept(this); } _writer.WriteLine(); _writer.WriteLine(); WriteIndentation(); _writer.Write(".hash algorithm "); _writer.WriteLine(assembly.GetFormattedHashAlgorithm()); if (assembly.HasPublicKey) { WriteIndentation(); _writer.Write(".publickey = "); _writer.WriteLine(assembly.GetPublicKeyString()); } if (assembly.HasCulture) { WriteIndentation(); _writer.Write(".locale "); _writer.WriteLine("'{0}'", assembly.Culture); } WriteIndentation(); _writer.WriteLine(string.Format(".ver {0}", assembly.GetFormattedVersion())); Unindent(); WriteIndentation(); _writer.WriteLine('}'); WriteIndentation(); _writer.Write(".module "); _writer.WriteLine(assembly.ModuleDefinition.Name); WriteIndentation(); _writer.WriteLine(string.Format(".imagebase 0x{0:X8}", assembly.HeaderOptions.ImageBase)); WriteIndentation(); _writer.WriteLine(string.Format(".file alignment 0x{0:X8}", assembly.HeaderOptions.FileAlignment)); WriteIndentation(); _writer.WriteLine(string.Format(".stackreserve 0x{0:X8}", assembly.HeaderOptions.StackReserve)); WriteIndentation(); _writer.WriteLine(string.Format(".subsystem 0x{0:X}", assembly.HeaderOptions.SubSystem)); WriteIndentation(); _writer.WriteLine(string.Format(".corflags 0x{0:X}", assembly.HeaderOptions.Corflags)); }
public AssemblyNode(CilAssembly assm) { _assembly = assm; _children.Add(new AssemblyReferencesNode(_assembly.AssemblyReferences)); var groupings = _assembly.TypeDefinitions.GroupBy <CilTypeDefinition, string>((ctd) => ctd.Namespace); foreach (var ns in groupings) { _children.Add(new NamespaceNode(ns.Key, ns)); } }
public JSExpression Translate(List <CilAssembly> world, CilAssembly asm) { return(new JSFunctionDelcaration { Parameters = new List <JSFunctionParameter> { new JSFunctionParameter { Name = "asm" } }, Body = GetBody(world, asm).Select(JSFactory.Statement).ToList() }); }
public async void TryOpenAssembly(string path) { try { CilAssembly newAssm = await Task.Run(() => CilAssembly.Create(path)); AddAssembly(newAssm); } catch { Console.WriteLine("Failed to open " + path); } }
public void TestMethod1() { var watch = new Stopwatch(); var path = "demo1.exe"; if (!File.Exists(path)) { var thisAssembly = typeof(CilTests).GetTypeInfo().Assembly; var resourceName = thisAssembly.GetManifestResourceNames().First(r => r.EndsWith("Demo1.exe")); var fileName = GetFileNameFromResourceName(resourceName); using (var fileStream = File.Create(fileName)) { using (var resource = thisAssembly.GetManifestResourceStream(resourceName)) { resource.CopyTo(fileStream); } } } const string outputDirectory = "Output"; if (!File.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } var assembly = CilAssembly.Create(path); watch.Start(); using (var file = new StreamWriter(new FileStream($"{outputDirectory}/foo.il", FileMode.Create))) { assembly.WriteTo(file); watch.Stop(); file.WriteLine("//Time elapsed: " + watch.Elapsed); assembly.Dispose(); } Assert.True(true); }
public void Analyze(CilAssembly asm) { foreach (var t in asm.Types) { if (t.IsIgnored || t.IsUserDelegate) { continue; } foreach (var method in t.Methods) { if (method.NeedTranslation && method.GetReplacement() == null) { foreach (var rewriter in GetPasses()) { rewriter.Run(method); } } } } }
private CilAssembly Process(Universe universe, AssemblySettings settings, int index) { var asm = universe.LoadFile(settings.Path); var result = new CilAssembly { Name = asm.FullName, EntryPoint = asm.EntryPoint, ReflectionAssembly = asm, Identifier = "asm" + index, Settings = settings }; var types = new List <CilType>(); result.Types = types; foreach (var type in asm.GetTypes()) { types.Add(ProcessType(type)); } return(result); }
public JSFunctionDelcaration GetFirstCallInitializer(CilAssembly assembly, CilType type, CilMethod method) { if (type.IsIgnored) { throw new ArgumentException("cannot translate method of ignored class"); } if (!method.NeedInitializer) { throw new ArgumentException("method need no initialization"); } var functionBlock = new List <JSStatement>(); JSExpression closedMethodInitializer; JSExpression openMethodInitializer = JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod) + "_init"); if (HasGenericParameters(method)) { closedMethodInitializer = new JSCallExpression { Function = openMethodInitializer, Arguments = GetGenericParameterList(method.ReflectionMethod) .Select(t => JSFactory.Identifier(t.Name)) .ToList() }; } else { closedMethodInitializer = openMethodInitializer; } functionBlock.Add( new JSCallExpression { Function = JSFactory.Identifier(closedMethodInitializer, "apply"), Arguments = { JSFactory.Identifier("this"), JSFactory.Identifier("arguments") } }.ToStatement()); JSExpression openMethodImplementation = JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod) + "_"); JSExpression closedMethodImplementation; if (HasGenericParameters(method)) { closedMethodImplementation = new JSCallExpression { Function = openMethodImplementation, Arguments = GetGenericParameterList(method.ReflectionMethod) .Select(t => JSFactory.Identifier(t.Name)) .ToList() }; } else { closedMethodImplementation = openMethodImplementation; } functionBlock.Add( new JSReturnExpression { Expression = new JSCallExpression { Function = JSFactory.Identifier(closedMethodImplementation, "apply"), Arguments = { JSFactory.Identifier("this"), JSFactory.Identifier("arguments") } } }.ToStatement()); var ps = GetParameterCount(method); var f = new JSFunctionDelcaration { Body = functionBlock, Parameters = Enumerable.Range(0, ps).Select(i => new JSFunctionParameter { Name = "arg" + i }).ToList() }; return(HasGenericParameters(method) ? CreateGenericFunction(method, f) : f); }
private JSFunctionDelcaration TranslateNormalMethod(CilAssembly asm, CilType type, CilMethod method) { var functionBlock = new List <JSStatement>(); if (method.Name == ".cctor") { var type_id = GetTypeIdentifier(type.ReflectionType, method.ReflectionMethod); var has_init = JSFactory.Identifier(type_id, "FieldsInitialized"); functionBlock.Add( new JSIfStatement { Condition = has_init, Statements = { new JSReturnExpression().ToStatement() } }); functionBlock.Add( JSFactory .Assignment(has_init, JSFactory.Literal(true)) .ToStatement()); } var thisScope = GetThisScope(method.ReflectionMethod, method.ReflectionMethod.DeclaringType); if (method.ReferencedTypes != null) { var tIdx = 0; var typesInScope = new List <Type>(); foreach (var t in method.ReferencedTypes) { functionBlock.Add( new JSVariableDelcaration { Name = "t" + tIdx, Value = GetTypeIdentifier(t, method.ReflectionMethod, method.ReflectionMethod.DeclaringType, thisScope, typesInScope) } .ToStatement()); typesInScope.Add(t); tIdx++; } } if (method.MethodBody.InitLocals) { var locIdx = 0; foreach (var loc in method.MethodBody.LocalVariables) { if (method.Locals[locIdx].NeedInit) { functionBlock.Add( new JSExpressionStatement { Expression = new JSVariableDelcaration { Name = "loc" + locIdx, Value = GetDefaultValue(loc.LocalType, methodScope: method.ReflectionMethod, typeScope: method.ReflectionMethod.DeclaringType, thisScope: thisScope) } }); } locIdx++; } } functionBlock.AddRange( method .Block .GetExpressions() .Where(o => o.StoreLocations != null) .SelectMany(o => o.StoreLocations) .Select(l => l.Name) .Distinct() .OrderBy(n => n) .Select( n => new JSExpressionStatement { Expression = new JSVariableDelcaration { Name = n } })); var blockTranslator = new BlockTranslator(context, asm, type, method, thisScope); functionBlock.AddRange( blockTranslator .Translate(method.Block) .Where(s => !(s is JSSwitchCase) && !((s is JSExpressionStatement) && ( ((JSExpressionStatement)s).Expression is JSBreakExpression))) .StartWith( new JSVariableDelcaration { Name = "__pos__", Value = JSFactory.Hex(0) } .ToStatement())); var ps = GetParameterCount(method); var function = new JSFunctionDelcaration { Body = functionBlock, Name = GetSimpleName(method.ReflectionMethod), Parameters = Enumerable.Range(0, ps).Select(i => new JSFunctionParameter { Name = "arg" + i }).ToList() }; return (HasGenericParameters(method) ? CreateGenericFunction(method, function) : function); }
public JSFunctionDelcaration GetInitializer(CilAssembly assembly, CilType type, CilMethod method) { if (type.IsIgnored) { throw new ArgumentException("cannot translate method of ignored class"); } if (method.NeedInitializer == false) { return(null); } var functionBlock = new List <JSStatement>(); var thisScope = GetThisScope(method.ReflectionMethod, method.ReflectionMethod.DeclaringType); foreach (var t in method.ReferencedTypes) { if (t.IsGenericParameter) // types shall be initialized before they are used as generic parameters { continue; } functionBlock.Add( new JSCallExpression { Function = JSFactory.Identifier(GetTypeIdentifier(t, method.ReflectionMethod, method.ReflectionMethod.DeclaringType, thisScope), "init") } .ToStatement()); } bool mustInitialize = false; if (method.DeclaringType.ReflectionType.IsGenericTypeDefinition && method.ReflectionMethod.IsConstructor) { mustInitialize = true; } else if (HasGenericParameters(method) || type.ReflectionType.IsGenericType) { var args = GetGenericParameterList(method.ReflectionMethod) .Concat(type.ReflectionType.GetGenericArguments()) .ToList() ; mustInitialize = method .ReferencedTypes .Where(r => r.IsGenericType || r.IsArray) .Any(r => r .GetGenericArguments() .Intersect(args) .Any() || (r.IsArray && args.Contains(r.GetElementType()))); } // We need to always call the initializer for // 1. constructors of generic types, since we have no type arguments // 2. any method with generic arguments which are used in the initializer // // TODO: we should inline the initialization for those cases. if (!mustInitialize) { functionBlock.Add( JSFactory .Assignment( JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod)), JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod) + "_")) .ToStatement()); } var f = new JSFunctionDelcaration { Body = functionBlock }; return(HasGenericParameters(method) ? CreateGenericFunction(method, f) : f); }
internal void AddAssembly(CilAssembly assm) { _loadedAssemblies = _loadedAssemblies.Add(assm); _listNodes = _listNodes.Add(new AssemblyNode(assm)); }
public ComparisonTranslator(Context context, CilAssembly assembly, CilType type, CilMethod method, Block block) : base(context, assembly, type, method, block) { }
private IEnumerable <JSExpression> GetBody(List <CilAssembly> world, CilAssembly asm) { yield return(JSFactory .Assignment( JSFactory.Identifier("asm", "FullName"), JSFactory.Literal(asm.ReflectionAssembly.FullName))); yield return(JSFactory.Assignment( JSFactory.Identifier("asm", "next_hash"), JSFactory.Literal(1))); foreach (var type in asm.Types) { if (type.IsIgnored || type.IsInterface) { continue; } foreach (var method in type.Methods) { var function = methodTranslator.Translate(asm, type, method); if (function == null) { continue; } var rmtd = method.ReflectionMethod; var mtdInfo = rmtd as MethodInfo; yield return(new JSLineComment { Text = string.Format("{0}{1} {2}.{3}{4}({5})", rmtd.IsStatic ? "static " : "", mtdInfo != null ? mtdInfo.ReturnType.ToString() : null, method.DeclaringType.Name, method.Name, rmtd.IsGenericMethod ? "<" + string.Join(",", rmtd.GetGenericArguments().Select(g => g.Name)) + ">" : "", string.Join(",", rmtd.GetParameters().Select(p => p.ParameterType.Name))) }); var accessor = JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod)); var initializer = methodTranslator.GetInitializer(asm, type, method); JSExpression firstCallFunction = null; if (initializer != null) { firstCallFunction = methodTranslator.GetFirstCallInitializer(asm, type, method); yield return(JSFactory .Assignment( JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod) + "_init"), initializer) .ToStatement()); } yield return(JSFactory .Assignment( accessor, firstCallFunction ?? function) .ToStatement()); if (firstCallFunction != null) { yield return(JSFactory .Assignment( JSFactory.Identifier("asm", GetMethodIdentifier(method.ReflectionMethod) + "_"), function)); } if (method.IsAssemblyStatic) { Debug.Assert(method.ReflectionMethod.IsStatic); var name = method.AssemblyStaticName ?? method.Name; yield return(JSFactory .Assignment( new JSPropertyAccessExpression { Host = new JSIdentifier { Name = "asm" }, // CHECKER TODO: check that there are no name conflicts for Assembly Statics Property = name }, accessor)); } } } foreach (var t in asm.Types) { if (t.IsIgnored) { continue; } yield return(JSFactory .Assignment( new JSPropertyAccessExpression { Host = new JSIdentifier { Name = "asm" }, Property = t.ReflectionType.FullName }, typeTranslator.Translate(t))); } if (asm.EntryPoint != null) { yield return(JSFactory .Assignment( JSFactory.Identifier("asm", "entryPoint"), JSFactory.Identifier("asm", "x" + asm.EntryPoint.MetadataToken.ToString("x")))); } }
public ArithmeticTranslator(Context context, CilAssembly assembly, CilType type, CilMethod method, Block block) : base(context, assembly, type, method, block) { }
public override void Init(AstContext context, ParseTreeNode parseNode) { // classHead + _("{") + classDecls + _("}") var classChildren = AstChildren.Empty() .Add <ClassHeadAstNode>() .Add("{") .Add <ClassDeclsAstNode>() .Add("}"); if (classChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Class; ClassDecl = new CilClass { Name = new CilClassName { ClassName = classChildren.Child1.ClassName }, Methods = classChildren.Child3.ClassDecls.Methods, Fields = classChildren.Child3.ClassDecls.Fields, Classes = classChildren.Child3.ClassDecls.Classes, ExtendsName = classChildren.Child1.ExtendsClassName, Attributes = classChildren.Child1.ClassAttributes }; return; } // assemblyHead + _("{") + assemblyDecls + _("}") var assemblyChildren = AstChildren.Empty() .Add <AssemblyHeadAstNode>() .Add("{") .Add <AssemblyDeclsAstNode>() .Add("}"); if (assemblyChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Assembly; AssemblyDecl = new CilAssembly { Name = assemblyChildren.Child1.AssemblyName }; return; } // assemblyRefHead + _("{") + assemblyRefDecls + _("}") var assemblyRefChildren = AstChildren.Empty() .Add <AssemblyRefHeadAstNode>() .Add("{") .Add <AssemblyRefDeclsAstNode>() .Add("}"); if (assemblyRefChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.AssemblyRef; AssemblyRefDecl = new CilAssemblyRef { Name = assemblyRefChildren.Child1.AssemblyName, PublicKeyTokens = assemblyRefChildren.Child3.AssemblyRefDecls.PublicKeyTokens, Versions = assemblyRefChildren.Child3.AssemblyRefDecls.Versions }; return; } // moduleHead var moduleChildren = AstChildren.Empty() .Add <ModuleHeadAstNode>(); if (moduleChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Module; return; } // _(".file") + _("alignment") + int32 var fileAlignmentChildren = AstChildren.Empty() .Add(".file") .Add("alignment") .Add <Int32AstNode>(); if (fileAlignmentChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.FileAlignment; return; } // _(".subsystem") + int32 var subsystemChildren = AstChildren.Empty() .Add(".subsystem") .Add <Int32AstNode>(); if (subsystemChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Subsystem; return; } // _(".corflags") + int32 var corFlagsChildren = AstChildren.Empty() .Add(".corflags") .Add <Int32AstNode>(); if (corFlagsChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.CorFlags; return; } // _(".imagebase") + int64 var imageBaseChildren = AstChildren.Empty() .Add(".imagebase") .Add <Int64AstNode>(); if (imageBaseChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.ImageBase; return; } // _(".stackreserve") + int64 var stackReserveChildren = AstChildren.Empty() .Add(".stackreserve") .Add <Int64AstNode>(); if (stackReserveChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.StackReserve; return; } // manifestResHead + _("{") + manifestResDecls + _("}") var manifestResChildren = AstChildren.Empty() .Add <ManifestResHeadAstNode>() .Add("{") .Add <ManifestResDeclsAstNode>() .Add("}"); if (manifestResChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.ManifestRes; return; } // methodHead + methodDecls + _("}") var methodChildren = AstChildren.Empty() .Add <MethodHeadAstNode>() .Add <MethodDeclsAstNode>() .Add("}"); if (methodChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Method; MethodDecl = new CilMethod { Name = methodChildren.Child1.MethodName, IsEntryPoint = methodChildren.Child2.MethodDecls.IsEntryPoint, Instructions = methodChildren.Child2.MethodDecls.Instructions, Locals = methodChildren.Child2.MethodDecls.Locals }; return; } // customAttrDecl var customAttrDeclChildren = AstChildren.Empty() .Add <CustomAttrDeclAstNode>(); if (customAttrDeclChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.CustomAttribute; return; } // dataDecl var dataDeclChildren = AstChildren.Empty() .Add <DataDeclAstNode>(); if (dataDeclChildren.PopulateWith(parseNode)) { DeclType = Other.DeclType.Data; DataDecl = dataDeclChildren.Child1.Data; DataId = dataDeclChildren.Child1.DataId; return; } throw new NotImplementedException(); }