protected void OptimizeAll() { var pr = new ProgressReporter(); if (Optimizing != null) Optimizing(pr); int i = 0; while (FunctionCache.OptimizationQueue.Count > 0) { var id = FunctionCache.OptimizationQueue.First(); FunctionCache.OptimizationQueue.Remove(id); var e = FunctionCache.Cache[id]; if (e.Expression == null) { i++; continue; } pr.OnProgressChanged(i++, i + FunctionCache.OptimizationQueue.Count); OptimizeFunction(e.SpecialIdentifiers, e.ParameterNames, e.Variables, e.Expression); } pr.OnFinished(); }
protected AssemblyDefinition[] LoadAssembly(string path, bool useSymbols, bool includeDependencies) { if (String.IsNullOrWhiteSpace(path)) throw new InvalidDataException("Path was empty."); var readerParameters = GetReaderParameters(useSymbols, path); var pr = new ProgressReporter(); if (LoadingAssembly != null) LoadingAssembly(path, pr); var assembly = AssemblyDefinition.ReadAssembly( path, readerParameters ); var result = new List<AssemblyDefinition>(); result.Add(assembly); if (includeDependencies) { var modulesToVisit = new Queue<ModuleDefinition>(assembly.Modules); var visitedModules = new HashSet<string>(); var assemblyNames = new HashSet<string>(); while (modulesToVisit.Count > 0) { var module = modulesToVisit.Dequeue(); if (visitedModules.Contains(module.FullyQualifiedName)) continue; visitedModules.Add(module.FullyQualifiedName); foreach (var reference in module.AssemblyReferences) { bool ignored = false; foreach (var ia in IgnoredAssemblies) { if (ia.IsMatch(reference.FullName)) { ignored = true; break; } } if (ignored) continue; if (assemblyNames.Contains(reference.FullName)) continue; var childParameters = new ReaderParameters { ReadingMode = ReadingMode.Deferred, ReadSymbols = true, SymbolReaderProvider = SymbolProvider }; var pr2 = new ProgressReporter(); if (LoadingAssembly != null) LoadingAssembly(reference.Name, pr2); AssemblyDefinition refAssembly = null; assemblyNames.Add(reference.FullName); try { refAssembly = readerParameters.AssemblyResolver.Resolve(reference, readerParameters); } catch (Exception ex) { if (useSymbols) { try { refAssembly = readerParameters.AssemblyResolver.Resolve(reference, GetReaderParameters(false, path)); if (CouldNotLoadSymbols != null) CouldNotLoadSymbols(reference.Name, ex); } catch (Exception ex2) { if (CouldNotResolveAssembly != null) CouldNotResolveAssembly(reference.FullName, ex2); } } else { if (CouldNotResolveAssembly != null) CouldNotResolveAssembly(reference.FullName, ex); } } if (refAssembly != null) { result.Add(refAssembly); foreach (var refModule in refAssembly.Modules) modulesToVisit.Enqueue(refModule); } pr2.OnFinished(); } } } pr.OnFinished(); return result.ToArray(); }
public AssemblyDefinition[] Translate(string assemblyPath, Stream outputStream = null, bool scanForProxies = true) { var assemblies = LoadAssembly(assemblyPath); if (scanForProxies) TypeInfoProvider.AddProxyAssemblies(assemblies); GeneratedFiles.Add(assemblyPath); var context = new DecompilerContext(assemblies.First().MainModule); context.Settings.YieldReturn = false; context.Settings.AnonymousMethods = true; context.Settings.QueryExpressions = false; context.Settings.LockStatement = false; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.ForEachStatement = false; var pr = new ProgressReporter(); if (Decompiling != null) Decompiling(pr); for (int i = 0; i < assemblies.Length; i++) { pr.OnProgressChanged(i, assemblies.Length); Analyze(context, assemblies[i]); } pr.OnFinished(); OptimizeAll(); Action<AssemblyDefinition> handler; if (outputStream == null) { handler = (assembly) => { var outputPath = Path.Combine(OutputDirectory, assembly.Name + ".js"); if (File.Exists(outputPath)) File.Delete(outputPath); using (outputStream = File.OpenWrite(outputPath)) Translate(context, assembly, outputStream); }; if (!Directory.Exists(OutputDirectory)) Directory.CreateDirectory(OutputDirectory); } else { handler = (assembly) => Translate(context, assembly, outputStream); } pr = new ProgressReporter(); if (Writing != null) Writing(pr); for (int i = 0; i < assemblies.Length; i++) { pr.OnProgressChanged(i, assemblies.Length); handler(assemblies[i]); } pr.OnFinished(); return assemblies; }
internal JSFunctionExpression TranslateMethodExpression(DecompilerContext context, MethodReference method, MethodDefinition methodDef) { var oldMethod = context.CurrentMethod; try { if (method == null) throw new ArgumentNullException("method"); if (methodDef == null) throw new ArgumentNullException("methodDef"); var methodInfo = TypeInfoProvider.GetMemberInformation<JSIL.Internal.MethodInfo>(methodDef); var identifier = new QualifiedMemberIdentifier( methodInfo.DeclaringType.Identifier, methodInfo.Identifier ); JSFunctionExpression function = null; if (FunctionCache.TryGetExpression(identifier, out function)) return function; if (methodInfo.IsExternal) { FunctionCache.CreateNull(methodInfo, method, identifier); return null; } var bodyDef = methodDef; if (methodInfo.IsFromProxy && methodInfo.Member.HasBody) bodyDef = methodInfo.Member; var pr = new ProgressReporter(); context.CurrentMethod = methodDef; if ((methodDef.Body.Instructions.Count > LargeMethodThreshold) && (this.DecompilingMethod != null)) this.DecompilingMethod(method.FullName, pr); ILBlock ilb; var decompiler = new ILAstBuilder(); var optimizer = new ILAstOptimizer(); try { ilb = new ILBlock(decompiler.Build(bodyDef, true)); optimizer.Optimize(context, ilb); } catch (Exception exception) { if (CouldNotDecompileMethod != null) CouldNotDecompileMethod(bodyDef.FullName, exception); FunctionCache.CreateNull(methodInfo, method, identifier); pr.OnFinished(); return null; } var allVariables = ilb.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable) .Where(v => v != null && !v.IsParameter).Distinct(); foreach (var v in allVariables) { if (ILBlockTranslator.IsIgnoredType(v.Type)) { FunctionCache.CreateNull(methodInfo, method, identifier); pr.OnFinished(); return null; } } NameVariables.AssignNamesToVariables(context, decompiler.Parameters, allVariables, ilb); var translator = new ILBlockTranslator( this, context, method, methodDef, ilb, decompiler.Parameters, allVariables ); var body = translator.Translate(); if (body == null) { FunctionCache.CreateNull(methodInfo, method, identifier); pr.OnFinished(); return null; } var parameters = from p in translator.ParameterNames select translator.Variables[p]; if (method.HasGenericParameters) { var type = new TypeReference("System", "Type", context.CurrentModule.TypeSystem.Object.Module, context.CurrentModule.TypeSystem.Object.Scope); parameters = (from gp in method.GenericParameters select new JSVariable(gp.Name, type, method)).Concat(parameters); } function = FunctionCache.Create( methodInfo, methodDef, method, identifier, translator, parameters, body ); pr.OnFinished(); return function; } finally { context.CurrentMethod = oldMethod; } }
protected void OptimizeAll() { var pr = new ProgressReporter(); if (Optimizing != null) Optimizing(pr); int i = 0, c = FunctionCache.Cache.Count; foreach (var e in FunctionCache.Cache.Values) { if (e.Expression == null) { i++; continue; } pr.OnProgressChanged(i++, c); OptimizeFunction(e.SpecialIdentifiers, e.ParameterNames, e.Variables, e.Expression); } pr.OnFinished(); }