Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/bearssl/T0/SType.cs
using System; | |||||
/* | |||||
* This structure contains the stack effect of a word: number of stack | |||||
* element consumed on input, and number of stack element produced on | |||||
* output. | |||||
*/ | |||||
struct SType { | |||||
/* | |||||
* Get number of stack elements consumed on input; this is -1 if | |||||
* the stack effect is not known. | |||||
*/ | |||||
internal int DataIn { | |||||
get { | |||||
return din; | |||||
} | |||||
} | |||||
/* | |||||
* Get number of stack elements produced on output; this is -1 if | |||||
* either the stack effect is not known, or if the word never | |||||
* exits. | |||||
*/ | |||||
internal int DataOut { | |||||
get { | |||||
return dout; | |||||
} | |||||
} | |||||
/* | |||||
* Tell whether the stack effect is known. | |||||
*/ | |||||
internal bool IsKnown { | |||||
get { | |||||
return din >= 0; | |||||
} | |||||
} | |||||
/* | |||||
* Tell whether the stack effect is known and the word never exits. | |||||
*/ | |||||
internal bool NoExit { | |||||
get { | |||||
return din >= 0 && dout < 0; | |||||
} | |||||
} | |||||
int din, dout; | |||||
internal SType(int din, int dout) | |||||
{ | |||||
if (din < 0) { | |||||
din = -1; | |||||
} | |||||
if (dout < 0) { | |||||
dout = -1; | |||||
} | |||||
this.din = din; | |||||
this.dout = dout; | |||||
} | |||||
/* | |||||
* Special value for the unknown stack effect. | |||||
*/ | |||||
internal static SType UNKNOWN = new SType(-1, -1); | |||||
/* | |||||
* Constant for the "blank stack effect". | |||||
*/ | |||||
internal static SType BLANK = new SType(0, 0); | |||||
public static bool operator ==(SType s1, SType s2) | |||||
{ | |||||
return s1.din == s2.din && s1.dout == s2.dout; | |||||
} | |||||
public static bool operator !=(SType s1, SType s2) | |||||
{ | |||||
return s1.din != s2.din || s1.dout != s2.dout; | |||||
} | |||||
public override bool Equals(Object obj) | |||||
{ | |||||
return (obj is SType) && ((SType)obj == this); | |||||
} | |||||
public override int GetHashCode() | |||||
{ | |||||
return din * 31 + dout * 17; | |||||
} | |||||
public override string ToString() | |||||
{ | |||||
if (!IsKnown) { | |||||
return "UNKNOWN"; | |||||
} else if (NoExit) { | |||||
return string.Format("in:{0},noexit", din); | |||||
} else { | |||||
return string.Format("in:{0},out:{1}", din, dout); | |||||
} | |||||
} | |||||
/* | |||||
* Test whether this stack effect is a sub-effect of the provided | |||||
* stack effect s. Stack effect s1 is a sub-effect of stack-effect | |||||
* s2 if any of the following holds: | |||||
* -- s1 and s2 are known, s1.din <= s2.din and s1 does not exit. | |||||
* -- s1 and s2 are known, s1.din <= s2.din, s1 and s2 exit, | |||||
* and s1.din - s1.dout == s2.din - s2.dout. | |||||
*/ | |||||
internal bool IsSubOf(SType s) | |||||
{ | |||||
if (!IsKnown || !s.IsKnown) { | |||||
return false; | |||||
} | |||||
if (din > s.din) { | |||||
return false; | |||||
} | |||||
if (NoExit) { | |||||
return true; | |||||
} | |||||
if (s.NoExit) { | |||||
return false; | |||||
} | |||||
return (din - dout) == (s.din - s.dout); | |||||
} | |||||
} |