2 // ValueExpressionDecoder.cs
5 // Alexander Chebaturkin (chebaturkin@gmail.com)
7 // Copyright (C) 2012 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.
31 using Mono
.CodeContracts
.Static
.AST
;
32 using Mono
.CodeContracts
.Static
.AST
.Visitors
;
33 using Mono
.CodeContracts
.Static
.Analysis
.ExpressionAnalysis
.Decoding
;
34 using Mono
.CodeContracts
.Static
.DataStructures
;
35 using Mono
.CodeContracts
.Static
.Lattices
;
36 using Mono
.CodeContracts
.Static
.Providers
;
38 namespace Mono
.CodeContracts
.Static
.Analysis
.Numerical
{
39 class ValueExpressionDecoder
<TVar
, TExpr
> : FullExpressionDecoder
<TVar
, TExpr
>, IExpressionDecoder
<TVar
, TExpr
>
40 where TVar
: IEquatable
<TVar
>
41 where TExpr
: IEquatable
<TExpr
> {
42 readonly VisitorForOperatorFor operator_for
;
43 readonly VisitorForTypeOf type_of
;
45 public ValueExpressionDecoder (IMetaDataProvider metaDataProvider
, IExpressionContextProvider
<TExpr
, TVar
> contextProvider
)
46 : base (metaDataProvider
, contextProvider
)
48 operator_for
= new VisitorForOperatorFor ();
49 type_of
= new VisitorForTypeOf ();
52 IExpressionContext
<TExpr
, TVar
> ExpressionContext { get { return ContextProvider.ExpressionContext; }
}
54 #region IExpressionDecoder<TVar,TExpr> Members
56 public ExpressionOperator
OperatorFor (TExpr expr
)
58 return ExpressionContext
.Decode
<TExpr
, ExpressionOperator
, VisitorForOperatorFor
> (expr
, operator_for
, expr
);
61 public TExpr
LeftExpressionFor (TExpr expr
)
68 if (IsUnaryExpression (expr
, out op
, out left
) || IsBinaryExpression (expr
, out bop
, out left
, out right
))
71 throw new InvalidOperationException ();
74 public TExpr
RightExpressionFor (TExpr expr
)
79 if (IsBinaryExpression (expr
, out bop
, out left
, out right
))
82 throw new InvalidOperationException ();
85 public bool IsConstant (TExpr expr
)
87 return OperatorFor (expr
) == ExpressionOperator
.Constant
;
90 public bool IsVariable (TExpr expr
)
93 return base.IsVariable (expr
, out variable
);
96 public bool TryValueOf
<T
> (TExpr e
, ExpressionType expectedType
, out T result
)
100 if (base.IsConstant (e
, out value, out actualType
)) {
102 return true.With ((T
) value, out result
);
103 if (value is int && expectedType
== ExpressionType
.Bool
) {
104 result
= (T
) (object) ((int) value != 0);
108 return false.Without (out result
);
111 public bool TrySizeOf (TExpr expr
, out int size
)
114 if (VisitorForSizeOf
<TVar
, TExpr
>.IsSizeOf (expr
, out type
, this)) {
115 size
= MetaDataProvider
.TypeSize (type
);
119 return false.Without (out size
);
122 public ExpressionType
TypeOf (TExpr expr
)
124 if (IsConstant (expr
))
125 return ExpressionContext
.Decode
<Dummy
, ExpressionType
, VisitorForTypeOf
> (expr
, type_of
, Dummy
.Value
);
127 var abstractType
= ExpressionContext
.GetType (expr
);
129 if (abstractType
.IsNormal ()) {
130 var type
= abstractType
.Value
;
132 if (MetaDataProvider
.IsPrimitive (type
)) {
133 if (MetaDataProvider
.Equal (type
, MetaDataProvider
.System_Int32
))
134 return ExpressionType
.Int32
;
135 if (MetaDataProvider
.Equal (type
, MetaDataProvider
.System_Single
))
136 return ExpressionType
.Float32
;
137 if (MetaDataProvider
.Equal (type
, MetaDataProvider
.System_Double
))
138 return ExpressionType
.Float64
;
139 if (MetaDataProvider
.Equal (type
, MetaDataProvider
.System_Boolean
))
140 return ExpressionType
.Bool
;
144 return ExpressionType
.Unknown
;
147 public bool IsConstantInt (TExpr expr
, out int value)
151 if (IsConstant (expr
, out objValue
, out type
))
152 return true.With ((int) objValue
, out value);
154 return false.Without (out value);
157 public string NameOf (TVar variable
)
159 return variable
.ToString ();
162 public bool IsBinaryExpression (TExpr expr
)
167 return IsBinaryExpression (expr
, out op
, out left
, out right
);
172 #region Nested type: VisitorForOperatorFor
174 class VisitorForOperatorFor
: ISymbolicExpressionVisitor
<TExpr
, TExpr
, TVar
, TExpr
, ExpressionOperator
> {
175 #region ISymbolicExpressionVisitor<TExpr,TExpr,TVar,TExpr,ExpressionOperator> Members
177 public ExpressionOperator
Binary (TExpr pc
, BinaryOperator bop
, TVar dest
, TExpr src1
, TExpr src2
, TExpr data
)
180 case BinaryOperator
.Add
:
181 case BinaryOperator
.Add_Ovf
:
182 case BinaryOperator
.Add_Ovf_Un
:
183 return ExpressionOperator
.Add
;
184 case BinaryOperator
.And
:
185 return ExpressionOperator
.And
;
186 case BinaryOperator
.Ceq
:
187 return ExpressionOperator
.Equal
;
188 case BinaryOperator
.Cobjeq
:
189 return ExpressionOperator
.Equal_Obj
;
190 case BinaryOperator
.Cne_Un
:
191 return ExpressionOperator
.NotEqual
;
192 case BinaryOperator
.Cge
:
193 case BinaryOperator
.Cge_Un
:
194 return ExpressionOperator
.GreaterEqualThan
;
195 case BinaryOperator
.Cgt
:
196 case BinaryOperator
.Cgt_Un
:
197 return ExpressionOperator
.GreaterThan
;
198 case BinaryOperator
.Cle
:
199 case BinaryOperator
.Cle_Un
:
200 return ExpressionOperator
.LessEqualThan
;
201 case BinaryOperator
.Clt
:
202 case BinaryOperator
.Clt_Un
:
203 return ExpressionOperator
.LessThan
;
204 case BinaryOperator
.Div
:
205 case BinaryOperator
.Div_Un
:
206 return ExpressionOperator
.Div
;
207 case BinaryOperator
.LogicalAnd
:
208 return ExpressionOperator
.LogicalAnd
;
209 case BinaryOperator
.LogicalOr
:
210 return ExpressionOperator
.LogicalOr
;
211 case BinaryOperator
.Mul
:
212 case BinaryOperator
.Mul_Ovf
:
213 case BinaryOperator
.Mul_Ovf_Un
:
214 return ExpressionOperator
.Mult
;
215 case BinaryOperator
.Or
:
216 return ExpressionOperator
.Or
;
217 case BinaryOperator
.Rem
:
218 case BinaryOperator
.Rem_Un
:
219 return ExpressionOperator
.Mod
;
220 case BinaryOperator
.Sub
:
221 case BinaryOperator
.Sub_Ovf
:
222 case BinaryOperator
.Sub_Ovf_Un
:
223 return ExpressionOperator
.Sub
;
224 case BinaryOperator
.Xor
:
225 return ExpressionOperator
.Xor
;
227 return ExpressionOperator
.Unknown
;
231 public ExpressionOperator
Unary (TExpr pc
, UnaryOperator uop
, bool unsigned
, TVar dest
, TExpr source
, TExpr data
)
234 case UnaryOperator
.Conv_i
:
235 case UnaryOperator
.Conv_i1
:
236 case UnaryOperator
.Conv_i2
:
237 case UnaryOperator
.Conv_i4
:
238 case UnaryOperator
.Conv_i8
:
239 return ExpressionOperator
.ConvertToInt32
;
240 case UnaryOperator
.Neg
:
241 return ExpressionOperator
.Not
;
242 case UnaryOperator
.Not
:
243 return ExpressionOperator
.Not
;
245 return ExpressionOperator
.Unknown
;
249 public ExpressionOperator
LoadNull (TExpr pc
, TVar dest
, TExpr polarity
)
251 return ExpressionOperator
.Constant
;
254 public ExpressionOperator
LoadConst (TExpr pc
, TypeNode type
, object constant
, TVar dest
, TExpr data
)
256 return ExpressionOperator
.Constant
;
259 public ExpressionOperator
Sizeof (TExpr pc
, TypeNode type
, TVar dest
, TExpr data
)
261 return ExpressionOperator
.SizeOf
;
264 public ExpressionOperator
Isinst (TExpr pc
, TypeNode type
, TVar dest
, TExpr obj
, TExpr data
)
266 return ExpressionOperator
.Unknown
;
269 public ExpressionOperator
SymbolicConstant (TExpr pc
, TVar variable
, TExpr data
)
271 return ExpressionOperator
.Variable
;
279 #region Nested type: VisitorForTypeOf
281 class VisitorForTypeOf
: ISymbolicExpressionVisitor
<TExpr
, TExpr
, TVar
, Dummy
, ExpressionType
> {
282 #region ISymbolicExpressionVisitor<TExpr,TExpr,TVar,Dummy,ExpressionType> Members
284 public ExpressionType
Binary (TExpr pc
, BinaryOperator bop
, TVar dest
, TExpr src1
, TExpr src2
, Dummy data
)
286 return ExpressionType
.Unknown
;
289 public ExpressionType
Unary (TExpr pc
, UnaryOperator uop
, bool unsigned
, TVar dest
, TExpr source
, Dummy data
)
291 return ExpressionType
.Unknown
;
294 public ExpressionType
LoadNull (TExpr pc
, TVar dest
, Dummy polarity
)
296 return ExpressionType
.Unknown
;
299 public ExpressionType
LoadConst (TExpr pc
, TypeNode type
, object constant
, TVar dest
, Dummy data
)
302 return ExpressionType
.Int32
;
303 if (constant
is float)
304 return ExpressionType
.Float32
;
305 if (constant
is double)
306 return ExpressionType
.Float64
;
307 if (constant
is bool)
308 return ExpressionType
.Bool
;
310 return ExpressionType
.Unknown
;
313 public ExpressionType
Sizeof (TExpr pc
, TypeNode type
, TVar dest
, Dummy data
)
315 return ExpressionType
.Int32
;
318 public ExpressionType
Isinst (TExpr pc
, TypeNode type
, TVar dest
, TExpr obj
, Dummy data
)
320 return ExpressionType
.Unknown
;
323 public ExpressionType
SymbolicConstant (TExpr pc
, TVar variable
, Dummy data
)
325 return ExpressionType
.Unknown
;