public FunctionAnalysis1stPass GetFirstPass(QualifiedMemberIdentifier method) { var entry = GetCacheEntry(method, false); if ((entry == null) || (entry.Expression == null)) { return(null); } if (entry.InProgress) { return(null); } if (entry.FirstPass == null) { entry.InProgress = true; try { var analyzer = new StaticAnalyzer(entry.Definition.Module.TypeSystem, this); entry.FirstPass = analyzer.FirstPass(entry.Expression); } finally { entry.InProgress = false; } } return(entry.FirstPass); }
protected void EliminateVariable (JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) { { var replacer = new VariableEliminator( variable, JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem) ); replacer.Visit(context); } { var replacer = new VariableEliminator(variable, replaceWith); var assignments = (from a in FirstPass.Assignments where variable.Equals(a.NewValue) || a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals) select a).ToArray(); foreach (var a in assignments) { if (!variable.Equals(a.NewValue)) replacer.Visit(a.NewValue); } } Variables.Remove(variable.Identifier); FunctionSource.InvalidateFirstPass(method); }
public void EmitMain() { var typeId = new TypeIdentifier(Assembly.EntryPoint.DeclaringType); var memberId = new MemberIdentifier(Translator.TypeInfoProvider, Assembly.EntryPoint); var entryPointIdentifier = new QualifiedMemberIdentifier(typeId, memberId); var mainExpression = Translator.FunctionCache.GetExpression(entryPointIdentifier); var astEmitter = (AstEmitter)EntryPointAstEmitter; var mainEmitter = new AstEmitter(this, Formatter, astEmitter.JSIL, astEmitter.TypeSystem, astEmitter.TypeInfo, astEmitter.Configuration, isTopLevel: true); Switch(PrecedingType.TopLevel); if (NeedStaticInit) { Formatter.ConditionalNewLine(); Formatter.WriteRaw("(invoke \"__static_init\")"); Formatter.NewLine(); Formatter.NewLine(); } var body = mainExpression.Body; foreach (var stmt in body.Statements) { mainEmitter.Visit(stmt); Formatter.ConditionalNewLine(); } }
private JSCachedMethod GetCachedMethod(JSMethod method) { if (!IsCacheable(method)) { return(null); } var type = method.Reference.DeclaringType.Resolve(); if (type == null) { return(null); } var identifier = new QualifiedMemberIdentifier( new TypeIdentifier(type), new MemberIdentifier(TypeInfo, method.Reference) ); CachedMethodRecord record; if (!CachedMethods.TryGetValue(identifier, out record)) { CachedMethods.Add(identifier, record = new CachedMethodRecord(method, NextID++)); } return(new JSCachedMethod( method.Reference, method.Method, method.MethodTypes, method.GenericArguments, record.Index )); }
internal JSFunctionExpression Create( MethodInfo info, MethodDefinition methodDef, MethodReference method, QualifiedMemberIdentifier identifier, ILBlockTranslator translator, IEnumerable <JSVariable> parameters, JSBlockStatement body ) { return(Cache.GetOrCreate(identifier, () => { var result = new JSFunctionExpression( new JSMethod(method, info, MethodTypes), translator.Variables, parameters, body, MethodTypes ); OptimizationQueue.TryEnqueue(identifier); return new Entry { Identifier = identifier, Info = info, Reference = method, Expression = result, Variables = translator.Variables, ParameterNames = translator.ParameterNames, SpecialIdentifiers = translator.SpecialIdentifiers }; }).Expression); }
private static bool TryAcquireStaticAnalysisDataLock(Entry entry, QualifiedMemberIdentifier method) { const int lockTimeoutMs = 33; var result = entry.StaticAnalysisDataLock.TryBlockingEnter(recursive: true, timeoutMs: lockTimeoutMs); if (!result.Success) { if (result.FailureReason == TrackedLockFailureReason.Deadlock) { throw new StaticAnalysisDataTemporarilyUnavailableException(method); } else { return(false); } } else { // Detect too-deep recursion and abort. if (entry.StaticAnalysisDataLock.RecursionDepth > 1) { entry.StaticAnalysisDataLock.Exit(); return(false); } } return(true); }
public FunctionAnalysis2ndPass GetSecondPass(JSMethod method, QualifiedMemberIdentifier forCaller) { if (method == null) { return(null); } var id = method.QualifiedIdentifier; Entry entry = Cache.GetOrCreate( id, method, MakeCacheEntry ); if (entry == null) { return(null); } GetFirstPass(id, forCaller); if (!TryAcquireStaticAnalysisDataLock(entry, method.QualifiedIdentifier)) { return(null); } try { return(_GetOrCreateSecondPass(entry)); } finally { entry.StaticAnalysisDataLock.Exit(); } }
public Entry GetCacheEntry(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGet(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); return entry; }
public void InvalidateSecondPass(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGetValue(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); entry.SecondPass = null; }
public JSFunctionExpression GetExpression(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGetValue(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); return entry.Expression; }
public EmulateStructAssignment(QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, TypeInfoProvider typeInfo, CLRSpecialIdentifiers clr, bool optimizeCopies) : base(member, functionSource) { TypeSystem = typeSystem; TypeInfo = typeInfo; CLR = clr; OptimizeCopies = optimizeCopies; }
protected StaticAnalysisJSAstVisitor (QualifiedMemberIdentifier member, IFunctionSource functionSource) { if (functionSource == null) throw new ArgumentNullException("functionSource"); Member = member; FunctionSource = functionSource; // Console.WriteLine("Static analysis visitor used in function {0}", new System.Diagnostics.StackFrame(2).GetMethod().Name); }
public EliminateSingleUseTemporaries ( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, Dictionary<string, JSVariable> variables, ITypeInfoSource typeInfo ) : base (member, functionSource) { TypeSystem = typeSystem; Variables = variables; TypeInfo = typeInfo; }
public EliminateSingleUseTemporaries( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, Dictionary <string, JSVariable> variables, ITypeInfoSource typeInfo ) : base(member, functionSource) { TypeSystem = typeSystem; Variables = variables; TypeInfo = typeInfo; }
public HoistAllocations ( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, MethodTypeFactory methodTypes ) : base (member, functionSource) { TypeSystem = typeSystem; MethodTypes = methodTypes; }
public bool TryGetExpression(QualifiedMemberIdentifier method, out JSFunctionExpression function) { Entry entry; if (!Cache.TryGetValue(method, out entry)) { function = null; return false; } function = entry.Expression; return true; }
public FunctionAnalysis2ndPass GetSecondPass(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGetValue(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); if (entry.SecondPass == null) entry.SecondPass = new FunctionAnalysis2ndPass(this, GetFirstPass(method)); return entry.SecondPass; }
public void InvalidateSecondPass(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGet(method, out entry)) { throw new KeyNotFoundException("No cache entry for method '" + method + "'."); } entry.SecondPass = null; }
public HoistAllocations( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, MethodTypeFactory methodTypes ) : base(member, functionSource) { TypeSystem = typeSystem; MethodTypes = methodTypes; }
public Entry GetCacheEntry(QualifiedMemberIdentifier method, bool throwOnFail = true) { Entry entry; if (!Cache.TryGet(method, out entry)) { if (throwOnFail) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); else return null; } return entry; }
protected StaticAnalysisJSAstVisitor(QualifiedMemberIdentifier member, IFunctionSource functionSource) { if (functionSource == null) { throw new ArgumentNullException("functionSource"); } Member = member; FunctionSource = functionSource; // Console.WriteLine("Static analysis visitor used in function {0}", new System.Diagnostics.StackFrame(2).GetMethod().Name); }
internal void CreateNull( MethodInfo info, MethodReference method, QualifiedMemberIdentifier identifier ) { var args = new NullCacheEntryArgs { Info = info, Method = method }; Cache.TryCreate(identifier, args, MakeNullCacheEntry); }
public bool TryGetExpression(QualifiedMemberIdentifier method, out JSFunctionExpression function) { Entry entry; if (!Cache.TryGet(method, out entry)) { function = null; return(false); } function = entry.Expression; return(true); }
public EliminatePointlessRetargeting ( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, MethodTypeFactory methodTypes ) : base (member, functionSource) { TypeSystem = typeSystem; MethodTypes = methodTypes; SeenRetargetsInScope.Push(new Dictionary<RetargetKey, int>()); ScopeNodeIndices.Push(-1); }
public void InvalidateSecondPass(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGet(method, out entry)) { throw new KeyNotFoundException("No cache entry for method '" + method + "'."); } entry.StaticAnalysisDataLock.BlockingEnter(recursive: true); entry.SecondPass = null; entry.StaticAnalysisDataLock.Exit(); }
public FunctionAnalysis1stPass GetFirstPass(QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGetValue(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); if (entry.FirstPass == null) { var analyzer = new StaticAnalyzer(entry.Definition.Module.TypeSystem, this); entry.FirstPass = analyzer.FirstPass(entry.Expression); } return entry.FirstPass; }
internal void CreateNull( MethodInfo info, MethodReference method, QualifiedMemberIdentifier identifier ) { Cache.TryCreate(identifier, () => { return(new Entry { Identifier = identifier, Info = info, Reference = method, Expression = null }); }); }
public EliminatePointlessRetargeting( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, MethodTypeFactory methodTypes ) : base(member, functionSource) { TypeSystem = typeSystem; MethodTypes = methodTypes; SeenRetargetsInScope.Push(new Dictionary <RetargetKey, int>()); ScopeNodeIndices.Push(-1); }
public FunctionAnalysis1stPass FirstPass(QualifiedMemberIdentifier identifier, JSFunctionExpression function) { State = new FunctionAnalysis1stPass(identifier, function); Visit(function); State.Accesses.Sort(FunctionAnalysis1stPass.ItemComparer); State.Assignments.Sort(FunctionAnalysis1stPass.ItemComparer); var result = State; State = null; if (false) { var bg = new StaticAnalysis.BarrierGenerator(TypeSystem, function); bg.Generate(); var targetFolder = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Barriers" ); Directory.CreateDirectory(targetFolder); var typeName = function.Method.QualifiedIdentifier.Type.ToString(); var methodName = function.Method.Method.Name; if (typeName.Length >= 96) { typeName = typeName.Substring(0, 93) + "…"; } if (methodName.Length >= 32) { methodName = methodName.Substring(0, 29) + "…"; } var filename = String.Format("{0}.{1}", typeName, methodName); filename = filename.Replace("<", "").Replace(">", "").Replace("/", ""); var targetFile = Path.Combine( targetFolder, String.Format("{0}.xml", filename) ); bg.SaveXML(targetFile); } return(result); }
public FunctionAnalysis1stPass FirstPass(QualifiedMemberIdentifier identifier, JSFunctionExpression function) { State = new FunctionAnalysis1stPass(identifier, function); Visit(function); State.Accesses.Sort(FunctionAnalysis1stPass.ItemComparer); State.Assignments.Sort(FunctionAnalysis1stPass.ItemComparer); var result = State; State = null; return(result); }
internal JSFunctionExpression Create( MethodInfo info, MethodDefinition methodDef, MethodReference method, QualifiedMemberIdentifier identifier, ILBlockTranslator translator, JSVariable[] parameters, JSBlockStatement body ) { var args = new PopulatedCacheEntryArgs { Info = info, Method = method, Translator = translator, Parameters = parameters, Body = body, }; return(Cache.GetOrCreate(identifier, args, MakePopulatedCacheEntry).Expression); }
public EmulateStructAssignment( QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, TypeInfoProvider typeInfo, CLRSpecialIdentifiers clr, MethodTypeFactory methodTypes, bool optimizeCopies ) : base(member, functionSource) { TypeSystem = typeSystem; TypeInfo = typeInfo; CLR = clr; MethodTypes = methodTypes; OptimizeCopies = optimizeCopies; }
public Entry GetCacheEntry(QualifiedMemberIdentifier method, bool throwOnFail = true) { Entry entry; if (!Cache.TryGet(method, out entry)) { if (throwOnFail) { throw new KeyNotFoundException("No cache entry for method '" + method + "'."); } else { return(null); } } return(entry); }
public FunctionAnalysis1stPass GetFirstPass(QualifiedMemberIdentifier method, QualifiedMemberIdentifier forCaller) { var entry = GetCacheEntry(method, false); if ((entry == null) || (entry.Expression == null)) { return(null); } if (!TryAcquireStaticAnalysisDataLock(entry, method)) { return(null); } try { return(_GetOrCreateFirstPass(entry)); } finally { entry.StaticAnalysisDataLock.Exit(); } }
public FunctionAnalysis1stPass GetFirstPass(QualifiedMemberIdentifier method) { Entry entry = GetCacheEntry(method); if (entry.Expression == null) return null; if (entry.InProgress) return null; if (entry.FirstPass == null) { entry.InProgress = true; try { var analyzer = new StaticAnalyzer(entry.Definition.Module.TypeSystem, this); entry.FirstPass = analyzer.FirstPass(entry.Expression); } finally { entry.InProgress = false; } } return entry.FirstPass; }
private JSCachedMethod GetCachedMethod (JSMethod method) { if (!IsCacheable(method)) return null; var type = method.Reference.DeclaringType.Resolve(); if (type == null) return null; var identifier = new QualifiedMemberIdentifier( new TypeIdentifier(type), new MemberIdentifier(TypeInfo, method.Reference) ); CachedMethodRecord record; if (!CachedMethods.TryGetValue(identifier, out record)) CachedMethods.Add(identifier, record = new CachedMethodRecord(method, NextID++)); return new JSCachedMethod( method.Reference, method.Method, method.MethodTypes, method.GenericArguments, record.Index ); }
public JSFunctionExpression GetExpression (QualifiedMemberIdentifier method) { var entry = GetCacheEntry(method); return entry.Expression; }
public FunctionAnalysis1stPass GetFirstPass (QualifiedMemberIdentifier method, QualifiedMemberIdentifier forCaller) { var entry = GetCacheEntry(method, false); if ((entry == null) || (entry.Expression == null)) return null; if (!TryAcquireStaticAnalysisDataLock(entry, method)) return null; try { return _GetOrCreateFirstPass(entry); } finally { entry.StaticAnalysisDataLock.Exit(); } }
protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) { { var replacer = new VariableEliminator( variable, JSChangeTypeExpression.New(replaceWith, TypeSystem, variable.GetActualType(TypeSystem)) ); replacer.Visit(context); } { var replacer = new VariableEliminator(variable, replaceWith); var assignments = (from a in FirstPass.Assignments where variable.Equals(a.NewValue) || a.NewValue.SelfAndChildrenRecursive.Any((_n) => variable.Equals(_n)) select a).ToArray(); foreach (var a in assignments) { if (variable.Equals(a.NewValue)) { FirstPass.Assignments.Remove(a); FirstPass.Assignments.Add( new FunctionAnalysis1stPass.Assignment( a.ParentNodeIndices, a.StatementIndex, a.NodeIndex, a.Target, replaceWith, a.Operator, a.TargetType, a.SourceType ) ); } else { replacer.Visit(a.NewValue); } } } Variables.Remove(variable.Identifier); FunctionSource.InvalidateFirstPass(method); }
protected FunctionAnalysis1stPass GetFirstPass(QualifiedMemberIdentifier method) { return FunctionSource.GetFirstPass(method, Member); }
public OptimizeArrayEnumerators(QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem) : base(member, functionSource) { TypeSystem = typeSystem; }
public EliminatePointlessFinallyBlocks(QualifiedMemberIdentifier member, IFunctionSource functionSource, TypeSystem typeSystem, ITypeInfoSource typeInfo) : base(member, functionSource) { TypeSystem = typeSystem; TypeInfo = typeInfo; }
public StaticAnalysisDataTemporarilyUnavailableException (QualifiedMemberIdentifier identifier) : base (identifier) { }
public Entry (QualifiedMemberIdentifier identifier, TrackedLockCollection lockCollection) { Identifier = identifier; StaticAnalysisDataLock = new TrackedLock(lockCollection, () => String.Format("{0}", this.Identifier.ToString())); }
public JSFunctionExpression GetExpression(QualifiedMemberIdentifier method) { var entry = GetCacheEntry(method); return(entry.Expression); }
public StaticAnalysisDataTemporarilyUnavailableException(QualifiedMemberIdentifier identifier) : base(identifier) { }
public FunctionAnalysis2ndPass GetSecondPass (JSMethod method, QualifiedMemberIdentifier forCaller) { if (method == null) return null; var id = method.QualifiedIdentifier; Entry entry = Cache.GetOrCreate( id, method, MakeCacheEntry ); if (entry == null) return null; GetFirstPass(id, forCaller); if (!TryAcquireStaticAnalysisDataLock(entry, method.QualifiedIdentifier)) return null; try { return _GetOrCreateSecondPass(entry); } finally { entry.StaticAnalysisDataLock.Exit(); } }
public FunctionAnalysis1stPass(QualifiedMemberIdentifier identifier, JSFunctionExpression function) { Identifier = identifier; Function = function; }
private static bool TryAcquireStaticAnalysisDataLock (Entry entry, QualifiedMemberIdentifier method) { const int lockTimeoutMs = 33; var result = entry.StaticAnalysisDataLock.TryBlockingEnter(recursive: true, timeoutMs: lockTimeoutMs); if (!result.Success) { if (result.FailureReason == TrackedLockFailureReason.Deadlock) throw new StaticAnalysisDataTemporarilyUnavailableException(method); else return false; } else { // Detect too-deep recursion and abort. if (entry.StaticAnalysisDataLock.RecursionDepth > 1) { entry.StaticAnalysisDataLock.Exit(); return false; } } return true; }
internal JSFunctionExpression Create ( MethodInfo info, MethodDefinition methodDef, MethodReference method, QualifiedMemberIdentifier identifier, ILBlockTranslator translator, JSVariable[] parameters, JSBlockStatement body ) { var args = new PopulatedCacheEntryArgs { Info = info, Method = method, Translator = translator, Parameters = parameters, Body = body, }; return Cache.GetOrCreate(identifier, args, MakePopulatedCacheEntry).Expression; }
protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) { { var replacer = new VariableEliminator( variable, JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem) ); replacer.Visit(context); } { var replacer = new VariableEliminator(variable, replaceWith); var assignments = (from a in FirstPass.Assignments where variable.Equals(a.NewValue) || a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals) select a).ToArray(); foreach (var a in assignments) { if (!variable.Equals(a.NewValue)) { replacer.Visit(a.NewValue); } } } Variables.Remove(variable.Identifier); FunctionSource.InvalidateFirstPass(method); }
protected TemporarilySuspendTransformPipelineException (QualifiedMemberIdentifier identifier) { Identifier = identifier; }
internal void CreateNull( MethodInfo info, MethodReference method, QualifiedMemberIdentifier identifier ) { var entry = new Entry { Identifier = identifier, Info = info, Reference = method, Expression = null }; Cache.Add(identifier, entry); }
public void InvalidateSecondPass (QualifiedMemberIdentifier method) { Entry entry; if (!Cache.TryGet(method, out entry)) throw new KeyNotFoundException("No cache entry for method '" + method + "'."); entry.StaticAnalysisDataLock.BlockingEnter(recursive: true); entry.SecondPass = null; entry.StaticAnalysisDataLock.Exit(); }
protected TemporarilySuspendTransformPipelineException(QualifiedMemberIdentifier identifier) { Identifier = identifier; }
protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) { { var replacer = new VariableEliminator( variable, JSChangeTypeExpression.New(replaceWith, TypeSystem, variable.GetExpectedType(TypeSystem)) ); replacer.Visit(context); } { var replacer = new VariableEliminator(variable, replaceWith); var assignments = (from a in FirstPass.Assignments where variable.Equals(a.NewValue) || a.NewValue.SelfAndChildrenRecursive.Any((_n) => variable.Equals(_n)) select a).ToArray(); foreach (var a in assignments) { if (variable.Equals(a.NewValue)) { FirstPass.Assignments.Remove(a); FirstPass.Assignments.Add( new FunctionAnalysis1stPass.Assignment( a.StatementIndex, a.NodeIndex, a.Target, replaceWith, a.Operator, a.TargetType, a.SourceType ) ); } else { replacer.Visit(a.NewValue); } } } Variables.Remove(variable.Identifier); FunctionSource.InvalidateFirstPass(method); }
public Entry(QualifiedMemberIdentifier identifier, TrackedLockCollection lockCollection) { Identifier = identifier; StaticAnalysisDataLock = new TrackedLock(lockCollection, () => String.Format("{0}", this.Identifier.ToString())); }
internal void CreateNull ( MethodInfo info, MethodReference method, QualifiedMemberIdentifier identifier ) { var args = new NullCacheEntryArgs { Info = info, Method = method }; Cache.TryCreate(identifier, args, MakeNullCacheEntry); }
internal JSFunctionExpression Create( MethodInfo info, MethodDefinition methodDef, MethodReference method, QualifiedMemberIdentifier identifier, ILBlockTranslator translator, IEnumerable<JSVariable> parameters, JSBlockStatement body ) { var result = new JSFunctionExpression( new JSMethod(method, info), translator.Variables, parameters, body ); var entry = new Entry { Identifier = identifier, Info = info, Reference = method, Expression = result, Variables = translator.Variables, ParameterNames = translator.ParameterNames, SpecialIdentifiers = translator.SpecialIdentifiers }; Cache.Add(identifier, entry); OptimizationQueue.Add(identifier); return result; }