// // ExpressionDecoder.cs // // Authors: // Alexander Chebaturkin (chebaturkin@gmail.com) // // Copyright (C) 2011 Alexander Chebaturkin // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Mono.CodeContracts.Static.AST; using Mono.CodeContracts.Static.AST.Visitors; using Mono.CodeContracts.Static.Analysis.ExpressionAnalysis.Expressions; using Mono.CodeContracts.Static.Analysis.HeapAnalysis; using Mono.CodeContracts.Static.ControlFlow; using Mono.CodeContracts.Static.DataStructures; using Mono.CodeContracts.Static.Lattices; using Mono.CodeContracts.Static.Providers; namespace Mono.CodeContracts.Static.Analysis.ExpressionAnalysis { class ExpressionDecoder : IILDecoder, TSymbolicValue, IExpressionContextProvider, TSymbolicValue>, TEdgeData>, IExpressionContextProvider, TSymbolicValue>, IExpressionContext, TSymbolicValue> where TSymbolicValue : IEquatable where TContext : IValueContextProvider where TEdgeData : IImmutableMap> { private readonly IILDecoder, TEdgeData> value_decoder; private readonly ExpressionAnalysisFacade parent; private readonly IValueContextProvider underlying; public ExpressionDecoder (IILDecoder, TEdgeData> valueDecoder, ExpressionAnalysisFacade parent) { this.value_decoder = valueDecoder; this.parent = parent; this.underlying = valueDecoder.ContextProvider; } #region IExpressionContext,SymbolicValue> Members public LabeledSymbol Refine (APC pc, TSymbolicValue variable) { return new LabeledSymbol (pc, variable); } public TSymbolicValue Unrefine (LabeledSymbol expression) { return expression.Symbol; } public Result Decode (LabeledSymbol expr, Visitor visitor, Data data) where Visitor : ISymbolicExpressionVisitor, LabeledSymbol, TSymbolicValue, Data, Result> { ExprDomain ifFound; if (!this.parent.PreStateLookup (expr.ReadAt, out ifFound) || ifFound.IsBottom) return visitor.SymbolicConstant (expr, expr.Symbol, data); FlatDomain> aExpr = ifFound [expr.Symbol]; if (aExpr.IsNormal()) { return aExpr.Value.Decode> (expr.ReadAt, expr.Symbol, new ExpressionDecoderAdapter (visitor), data); } TypeNode type; object constant; if (this.parent.ValueLayer.ILDecoder.ContextProvider.ValueContext.IsConstant (expr.ReadAt, expr.Symbol, out type, out constant)) return visitor.LoadConst (expr, type, constant, expr.Symbol, data); return visitor.SymbolicConstant (expr, expr.Symbol, data); } public FlatDomain GetType (LabeledSymbol expr) { return this.underlying.ValueContext.GetType (expr.ReadAt, expr.Symbol); } public APC GetPC (LabeledSymbol pc) { return pc.ReadAt; } public LabeledSymbol For (TSymbolicValue variable) { return new LabeledSymbol (MethodContext.CFG.Entry, variable); } public bool IsZero (LabeledSymbol expression) { return ValueContext.IsZero (expression.ReadAt, expression.Symbol); } #endregion #region IILDecoder,SymbolicValue,IExpressionContextProvider,SymbolicValue>,EdgeData> Members public IExpressionContextProvider, TSymbolicValue> ContextProvider { get { return this; } } public Result ForwardDecode (APC pc, Visitor visitor, Data state) where Visitor : IILVisitor, TSymbolicValue, Data, Result> { return this.value_decoder.ForwardDecode> (pc, new ILDecoderAdapter (visitor), state); } public bool IsUnreachable (APC pc) { return this.parent.IsUnreachable (pc); } public TEdgeData EdgeData (APC from, APC to) { return this.parent.ValueLayer.ILDecoder.EdgeData (from, to); } #endregion #region Implementation of IMethodContextProvider public IMethodContext MethodContext { get { return this.underlying.MethodContext; } } #endregion #region Implementation of IStackContextProvider public IStackContext StackContext { get { return this.underlying.StackContext; } } #endregion #region Implementation of IValueContextProvider public IValueContext ValueContext { get { return this.underlying.ValueContext; } } #endregion #region Implementation of IExpressionContextProvider,SymbolicValue> public IExpressionContext, TSymbolicValue> ExpressionContext { get { return this; } } #endregion } }