1 // 2 // FunctionsTable.cs 3 // 4 // Authors: 5 // Alexander Chebaturkin (chebaturkin@gmail.com) 6 // 7 // Copyright (C) 2011 Alexander Chebaturkin 8 // 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: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 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. 27 28 using System.Collections.Generic; 29 using Mono.CodeContracts.Static.AST; 30 using Mono.CodeContracts.Static.Providers; 31 32 namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis { 33 class FunctionsTable 34 { 35 public readonly SymFunction BoxOperator; 36 public readonly SymFunction ElementAddress; 37 public readonly SymFunction Length; 38 public readonly SymFunction NeZero; 39 public readonly SymFunction NullValue; 40 public readonly SymFunction ObjectVersion; 41 public readonly SymFunction OldValueOf; 42 public readonly SymFunction ResultOfCall; 43 public readonly SymFunction ResultOfLoadElement; 44 public readonly SymFunction StructId; 45 public readonly SymFunction UnaryNot; 46 public readonly SymFunction ValueOf; 47 public readonly SymFunction VoidAddr; 48 public readonly SymFunction ZeroValue; 49 private readonly Dictionary<BinaryOperator, Wrapper<BinaryOperator>> binary_operators; 50 private readonly Dictionary<Field, Wrapper<Field>> fields; 51 private readonly Dictionary<Local, Wrapper<Local>> locals; 52 private readonly IMetaDataProvider meta_data_provider; 53 private readonly Dictionary<Method, Wrapper<Method>> method_pointers; 54 private readonly Dictionary<Parameter, Wrapper<Parameter>> parameters; 55 private readonly Dictionary<object, Wrapper<object>> program_constants; 56 private readonly Dictionary<Method, Wrapper<Method>> pseudo_fields; 57 private readonly Dictionary<string, Wrapper<string>> strings; 58 private readonly Dictionary<int, Wrapper<int>> temp; 59 private readonly Dictionary<UnaryOperator, Wrapper<UnaryOperator>> unary_operators; 60 61 private int id_gen; 62 FunctionsTable(IMetaDataProvider metaDataProvider)63 public FunctionsTable(IMetaDataProvider metaDataProvider) 64 { 65 this.meta_data_provider = metaDataProvider; 66 this.locals = new Dictionary<Local, Wrapper<Local>> (); 67 this.parameters = new Dictionary<Parameter, Wrapper<Parameter>> (); 68 this.fields = new Dictionary<Field, Wrapper<Field>> (); 69 this.pseudo_fields = new Dictionary<Method, Wrapper<Method>> (); 70 this.temp = new Dictionary<int, Wrapper<int>> (); 71 this.strings = new Dictionary<string, Wrapper<string>> (); 72 this.program_constants = new Dictionary<object, Wrapper<object>> (); 73 this.method_pointers = new Dictionary<Method, Wrapper<Method>> (); 74 this.binary_operators = new Dictionary<BinaryOperator, Wrapper<BinaryOperator>> (); 75 this.unary_operators = new Dictionary<UnaryOperator, Wrapper<UnaryOperator>> (); 76 77 this.ValueOf = For ("$Value"); 78 this.OldValueOf = For ("$OldValue"); 79 this.StructId = For ("$StructId"); 80 this.ObjectVersion = For ("$ObjectVersion"); 81 this.NullValue = For ("$Null"); 82 this.ElementAddress = For ("$ElementAddress"); 83 this.Length = For ("$Length"); 84 this.VoidAddr = For ("$VoidAddr"); 85 this.UnaryNot = For ("$UnaryNot"); 86 this.NeZero = For ("$NeZero"); 87 this.BoxOperator = For ("$Box"); 88 this.ResultOfCall = For ("$ResultOfCall"); 89 this.ResultOfLoadElement = For ("$ResultOfLoadElement"); 90 this.ZeroValue = ForConstant (0, this.meta_data_provider.System_Int32); 91 } 92 For(T key, Dictionary<T, Wrapper<T>> cache)93 private Wrapper<T> For<T>(T key, Dictionary<T, Wrapper<T>> cache) 94 { 95 Wrapper<T> wrapper; 96 if (!cache.TryGetValue (key, out wrapper)) { 97 wrapper = SymFunction.For (key, ref this.id_gen, this.meta_data_provider); 98 cache.Add (key, wrapper); 99 } 100 return wrapper; 101 } 102 For(Local v)103 public SymFunction For(Local v) 104 { 105 return For (v, this.locals); 106 } 107 For(Parameter v)108 public SymFunction For(Parameter v) 109 { 110 return For (v, this.parameters); 111 } 112 For(Field v)113 public SymFunction For(Field v) 114 { 115 v = this.meta_data_provider.Unspecialized (v); 116 return For (v, this.fields); 117 } 118 For(Method v)119 public SymFunction For(Method v) 120 { 121 return For (v, this.pseudo_fields); 122 } 123 For(string v)124 public SymFunction For(string v) 125 { 126 return For (v, this.strings); 127 } 128 For(int v)129 public SymFunction For(int v) 130 { 131 return For (v, this.temp); 132 } 133 For(BinaryOperator v)134 public SymFunction For(BinaryOperator v) 135 { 136 return For (v, this.binary_operators); 137 } 138 For(UnaryOperator v)139 public SymFunction For(UnaryOperator v) 140 { 141 return For (v, this.unary_operators); 142 } 143 ForConstant(object constant, TypeNode type)144 public SymFunction ForConstant(object constant, TypeNode type) 145 { 146 Wrapper<object> wrapper = For (constant, this.program_constants); 147 wrapper.Type = type; 148 return wrapper; 149 } 150 ForMethod(Method method, TypeNode type)151 public SymFunction ForMethod(Method method, TypeNode type) 152 { 153 Wrapper<Method> wrapper = For (method, this.method_pointers); 154 wrapper.Type = type; 155 return wrapper; 156 } 157 IsConstantOrMethod(SymFunction constant)158 public bool IsConstantOrMethod(SymFunction constant) 159 { 160 var wrapper = constant as Wrapper<object>; 161 if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item)) 162 return true; 163 164 var wrapper1 = constant as Wrapper<Method>; 165 if (wrapper1 != null && this.method_pointers.ContainsKey (wrapper1.Item)) 166 return true; 167 168 return false; 169 } 170 IsConstant(SymFunction c, out TypeNode type, out object value)171 public bool IsConstant(SymFunction c, out TypeNode type, out object value) 172 { 173 var wrapper = c as Wrapper<object>; 174 if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item)) { 175 type = wrapper.Type; 176 value = wrapper.Item; 177 return true; 178 } 179 180 type = null; 181 value = null; 182 return false; 183 } 184 } 185 }