Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

185 lines
6.1 KiB
C#

//
// FunctionsTable.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.Collections.Generic;
using Mono.CodeContracts.Static.AST;
using Mono.CodeContracts.Static.Providers;
namespace Mono.CodeContracts.Static.Analysis.HeapAnalysis {
class FunctionsTable
{
public readonly SymFunction BoxOperator;
public readonly SymFunction ElementAddress;
public readonly SymFunction Length;
public readonly SymFunction NeZero;
public readonly SymFunction NullValue;
public readonly SymFunction ObjectVersion;
public readonly SymFunction OldValueOf;
public readonly SymFunction ResultOfCall;
public readonly SymFunction ResultOfLoadElement;
public readonly SymFunction StructId;
public readonly SymFunction UnaryNot;
public readonly SymFunction ValueOf;
public readonly SymFunction VoidAddr;
public readonly SymFunction ZeroValue;
private readonly Dictionary<BinaryOperator, Wrapper<BinaryOperator>> binary_operators;
private readonly Dictionary<Field, Wrapper<Field>> fields;
private readonly Dictionary<Local, Wrapper<Local>> locals;
private readonly IMetaDataProvider meta_data_provider;
private readonly Dictionary<Method, Wrapper<Method>> method_pointers;
private readonly Dictionary<Parameter, Wrapper<Parameter>> parameters;
private readonly Dictionary<object, Wrapper<object>> program_constants;
private readonly Dictionary<Method, Wrapper<Method>> pseudo_fields;
private readonly Dictionary<string, Wrapper<string>> strings;
private readonly Dictionary<int, Wrapper<int>> temp;
private readonly Dictionary<UnaryOperator, Wrapper<UnaryOperator>> unary_operators;
private int id_gen;
public FunctionsTable(IMetaDataProvider metaDataProvider)
{
this.meta_data_provider = metaDataProvider;
this.locals = new Dictionary<Local, Wrapper<Local>> ();
this.parameters = new Dictionary<Parameter, Wrapper<Parameter>> ();
this.fields = new Dictionary<Field, Wrapper<Field>> ();
this.pseudo_fields = new Dictionary<Method, Wrapper<Method>> ();
this.temp = new Dictionary<int, Wrapper<int>> ();
this.strings = new Dictionary<string, Wrapper<string>> ();
this.program_constants = new Dictionary<object, Wrapper<object>> ();
this.method_pointers = new Dictionary<Method, Wrapper<Method>> ();
this.binary_operators = new Dictionary<BinaryOperator, Wrapper<BinaryOperator>> ();
this.unary_operators = new Dictionary<UnaryOperator, Wrapper<UnaryOperator>> ();
this.ValueOf = For ("$Value");
this.OldValueOf = For ("$OldValue");
this.StructId = For ("$StructId");
this.ObjectVersion = For ("$ObjectVersion");
this.NullValue = For ("$Null");
this.ElementAddress = For ("$ElementAddress");
this.Length = For ("$Length");
this.VoidAddr = For ("$VoidAddr");
this.UnaryNot = For ("$UnaryNot");
this.NeZero = For ("$NeZero");
this.BoxOperator = For ("$Box");
this.ResultOfCall = For ("$ResultOfCall");
this.ResultOfLoadElement = For ("$ResultOfLoadElement");
this.ZeroValue = ForConstant (0, this.meta_data_provider.System_Int32);
}
private Wrapper<T> For<T>(T key, Dictionary<T, Wrapper<T>> cache)
{
Wrapper<T> wrapper;
if (!cache.TryGetValue (key, out wrapper)) {
wrapper = SymFunction.For (key, ref this.id_gen, this.meta_data_provider);
cache.Add (key, wrapper);
}
return wrapper;
}
public SymFunction For(Local v)
{
return For (v, this.locals);
}
public SymFunction For(Parameter v)
{
return For (v, this.parameters);
}
public SymFunction For(Field v)
{
v = this.meta_data_provider.Unspecialized (v);
return For (v, this.fields);
}
public SymFunction For(Method v)
{
return For (v, this.pseudo_fields);
}
public SymFunction For(string v)
{
return For (v, this.strings);
}
public SymFunction For(int v)
{
return For (v, this.temp);
}
public SymFunction For(BinaryOperator v)
{
return For (v, this.binary_operators);
}
public SymFunction For(UnaryOperator v)
{
return For (v, this.unary_operators);
}
public SymFunction ForConstant(object constant, TypeNode type)
{
Wrapper<object> wrapper = For (constant, this.program_constants);
wrapper.Type = type;
return wrapper;
}
public SymFunction ForMethod(Method method, TypeNode type)
{
Wrapper<Method> wrapper = For (method, this.method_pointers);
wrapper.Type = type;
return wrapper;
}
public bool IsConstantOrMethod(SymFunction constant)
{
var wrapper = constant as Wrapper<object>;
if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item))
return true;
var wrapper1 = constant as Wrapper<Method>;
if (wrapper1 != null && this.method_pointers.ContainsKey (wrapper1.Item))
return true;
return false;
}
public bool IsConstant(SymFunction c, out TypeNode type, out object value)
{
var wrapper = c as Wrapper<object>;
if (wrapper != null && this.program_constants.ContainsKey (wrapper.Item)) {
type = wrapper.Type;
value = wrapper.Item;
return true;
}
type = null;
value = null;
return false;
}
}
}