本文整理汇总了C#中Mono.CSharp.Expression.EmitBranchable方法的典型用法代码示例。如果您正苦于以下问题:C# Expression.EmitBranchable方法的具体用法?C# Expression.EmitBranchable怎么用?C# Expression.EmitBranchable使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mono.CSharp.Expression
的用法示例。
在下文中一共展示了Expression.EmitBranchable方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: TableSwitchEmit
/// <summary>
/// This method emits code for a lookup-based switch statement (non-string)
/// Basically it groups the cases into blocks that are at least half full,
/// and then spits out individual lookup opcodes for each block.
/// It emits the longest blocks first, and short blocks are just
/// handled with direct compares.
/// </summary>
/// <param name="ec"></param>
/// <param name="val"></param>
/// <returns></returns>
void TableSwitchEmit (EmitContext ec, Expression val)
{
int element_count = Elements.Count;
object [] element_keys = new object [element_count];
Elements.Keys.CopyTo (element_keys, 0);
Array.Sort (element_keys);
// initialize the block list with one element per key
var key_blocks = new List<KeyBlock> (element_count);
foreach (object key in element_keys)
key_blocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));
KeyBlock current_kb;
// iteratively merge the blocks while they are at least half full
// there's probably a really cool way to do this with a tree...
while (key_blocks.Count > 1)
{
var key_blocks_new = new List<KeyBlock> ();
current_kb = (KeyBlock) key_blocks [0];
for (int ikb = 1; ikb < key_blocks.Count; ikb++)
{
KeyBlock kb = (KeyBlock) key_blocks [ikb];
if ((current_kb.Size + kb.Size) * 2 >= KeyBlock.TotalLength (current_kb, kb))
{
// merge blocks
current_kb.last = kb.last;
current_kb.Size += kb.Size;
}
else
{
// start a new block
key_blocks_new.Add (current_kb);
current_kb = kb;
}
}
key_blocks_new.Add (current_kb);
if (key_blocks.Count == key_blocks_new.Count)
break;
key_blocks = key_blocks_new;
}
// initialize the key lists
foreach (KeyBlock kb in key_blocks)
kb.element_keys = new List<object> ();
// fill the key lists
int iBlockCurr = 0;
if (key_blocks.Count > 0) {
current_kb = (KeyBlock) key_blocks [0];
foreach (object key in element_keys)
{
bool next_block = (key is UInt64) ? (ulong) key > (ulong) current_kb.last :
System.Convert.ToInt64 (key) > current_kb.last;
if (next_block)
current_kb = (KeyBlock) key_blocks [++iBlockCurr];
current_kb.element_keys.Add (key);
}
}
// sort the blocks so we can tackle the largest ones first
key_blocks.Sort ();
// okay now we can start...
Label lbl_end = ec.DefineLabel (); // at the end ;-)
Label lbl_default = default_target;
Type type_keys = null;
if (element_keys.Length > 0)
type_keys = element_keys [0].GetType (); // used for conversions
TypeSpec compare_type;
if (TypeManager.IsEnumType (SwitchType))
compare_type = EnumSpec.GetUnderlyingType (SwitchType);
else
compare_type = SwitchType;
for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
{
KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
lbl_default = (iBlock == 0) ? default_target : ec.DefineLabel ();
if (kb.Length <= 2)
{
foreach (object key in kb.element_keys) {
SwitchLabel sl = (SwitchLabel) Elements [key];
if (key is int && (int) key == 0) {
val.EmitBranchable (ec, sl.GetILLabel (ec), false);
} else {
val.Emit (ec);
EmitObjectInteger (ec, key);
//.........这里部分代码省略.........