Skip to content

Commit

Permalink
Add support for named locals (indexer on Codegen), and Label(string l…
Browse files Browse the repository at this point in the history
…abelName) and Goto(string labelName) methods on Codegen; examples to follow
  • Loading branch information
diakopter committed Dec 22, 2009
1 parent d124576 commit 609e670
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions RunSharp/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public partial class CodeGen
LocalBuilder retVar = null;
Label retLabel;
Stack<Block> blocks = new Stack<Block>();
Dictionary<string, Label> Labels = new Dictionary<string, Label>();
Dictionary<string, Operand> NamedLocals = new Dictionary<string, Operand>();

internal ILGenerator IL { get { return il; } }
internal ICodeGenContext Context { get { return context; } }
Expand Down Expand Up @@ -396,5 +398,62 @@ internal override bool IsStaticTarget
}
}
}

public Operand this[string localName] // Named locals support.
{
get
{
Operand target;
if (!NamedLocals.TryGetValue(localName, out target))
throw new InvalidOperationException(Properties.Messages.ErrUninitializedVarAccess);
return target;
}
set
{
Operand target;
if (NamedLocals.TryGetValue(localName, out target))
// run in statement form; C# left-to-right evaluation semantics "just work"
Assign(target, value);
else
NamedLocals.Add(localName, Local(value));
}
}

/// <summary>
/// DO NOT USE THIS. Declare a label with a compile-time value, not a run-time value.
/// </summary>
/// <param name="operand"></param>
public void Label(Operand operand, bool soValuesDontCoerceToOperand)
{
throw new InvalidOperationException("we use computed gotos only!");
}

/// <summary>
/// DO NOT USE THIS. Declare a label with a compile-time value, not a run-time value.
/// </summary>
/// <param name="operand"></param>
public void Goto(Operand operand, bool soValuesDontCoerceToOperand)
{
throw new InvalidOperationException("we use computed gotos only!");
}

// stringified object for convenience when generating label names from integral types
public void Label(object labelNameObject)
{
var labelName = labelNameObject.ToString();
Label label;
if (!Labels.TryGetValue(labelName, out label))
Labels.Add(labelName, label = IL.DefineLabel());
IL.MarkLabel(label);
}

public void Goto(object labelNameObject)
{
var labelName = labelNameObject.ToString();
Label label;
if (!Labels.TryGetValue(labelName, out label))
Labels.Add(labelName, label = IL.DefineLabel());
IL.Emit(OpCodes.Br, label);
}
}
}

0 comments on commit 609e670

Please sign in to comment.