5 // Alexander Chebaturkin (chebaturkin@gmail.com)
7 // Copyright (C) 2011 Alexander Chebaturkin
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using Mono.CodeContracts.Static.AST.Visitors;
31 using Mono.CodeContracts.Static.ControlFlow;
32 using Mono.CodeContracts.Static.DataStructures;
33 using Mono.CodeContracts.Static.Providers;
35 namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
36 class ValueDecoder<TContext> :
37 IILDecoder<APC, SymbolicValue, SymbolicValue, IValueContextProvider<SymbolicValue>, IImmutableMap<SymbolicValue, LispList<SymbolicValue>>>
38 where TContext : IStackContextProvider
40 private readonly HeapAnalysis parent;
41 private readonly IILDecoder<APC, int, int, TContext, Dummy> stack_decoder;
42 private readonly Lazy<IValueContextProvider<SymbolicValue>> context;
44 public ValueDecoder(HeapAnalysis parent, IILDecoder<APC, int, int, TContext, Dummy> stackDecoder)
46 this.context = new Lazy<IValueContextProvider<SymbolicValue>> (()=> new ValueContextProvider<TContext>(this.parent, this.stack_decoder.ContextProvider));
48 this.stack_decoder = stackDecoder;
51 #region Implementation of IILDecoder<APC,SymbolicValue,SymbolicValue,IValueContext<SymbolicValue>,IImmutableMap<SymbolicValue,LispList<SymbolicValue>>>
52 public IValueContextProvider<SymbolicValue> ContextProvider { get { return context.Value; } }
54 public Result ForwardDecode<Data, Result, Visitor>(APC pc, Visitor visitor, Data state)
55 where Visitor : IILVisitor<APC, SymbolicValue, SymbolicValue, Data, Result>
57 return this.stack_decoder.ForwardDecode<Data, Result, StackToSymbolicAdapter<Data, Result, Visitor>>
58 (pc, new StackToSymbolicAdapter<Data, Result, Visitor> (this.parent, visitor), state);
61 public bool IsUnreachable(APC pc)
63 return this.parent.IsUnreachable (pc);
66 public IImmutableMap<SymbolicValue, LispList<SymbolicValue>> EdgeData(APC from, APC to)
68 if (!this.parent.RenamePoints.ContainsKey(from, to))
70 if (this.parent.MergeInfoCache.ContainsKey(to) && this.parent.MergeInfoCache[to] == null)
73 return this.parent.EdgeRenaming (new Pair<APC, APC> (from, to), this.ContextProvider.MethodContext.CFG.IsJoinPoint (to));
76 public void Dump(TextWriter tw, string prefix, IImmutableMap<SymValue, LispList<SymValue>> edgeData )
80 edgeData.Visit ((key, targets) => {
81 tw.Write (" {0} -> ", key);
82 foreach (var target in targets.AsEnumerable ())
83 tw.Write ("{0} ", target);
85 return VisitStatus.ContinueVisit;