diff --git a/src/Flee.Net45/ExpressionElements/Base/ExpressionElement.cs b/src/Flee.Net45/ExpressionElements/Base/ExpressionElement.cs
index d0b99e2..58e8bc3 100644
--- a/src/Flee.Net45/ExpressionElements/Base/ExpressionElement.cs
+++ b/src/Flee.Net45/ExpressionElements/Base/ExpressionElement.cs
@@ -44,11 +44,6 @@ protected void ThrowAmbiguousCallException(Type leftType, Type rightType, object
this.ThrowCompileException(CompileErrorResourceKeys.AmbiguousOverloadedOperator, CompileExceptionReason.AmbiguousMatch, leftType.Name, rightType.Name, operation);
}
- protected FleeILGenerator CreateTempFleeILGenerator(FleeILGenerator ilgCurrent)
- {
- DynamicMethod dm = new DynamicMethod("temp", typeof(Int32), null, this.GetType());
- return new FleeILGenerator(dm.GetILGenerator(), ilgCurrent.Length, true);
- }
protected string Name
{
diff --git a/src/Flee.Net45/ExpressionElements/Base/Literals/LiteralElement.cs b/src/Flee.Net45/ExpressionElements/Base/Literals/LiteralElement.cs
index e6260ee..fe17db2 100644
--- a/src/Flee.Net45/ExpressionElements/Base/Literals/LiteralElement.cs
+++ b/src/Flee.Net45/ExpressionElements/Base/Literals/LiteralElement.cs
@@ -42,7 +42,7 @@ protected static void EmitLoad(Int64 value, FleeILGenerator ilg)
}
else if (value >= 0 & value <= UInt32.MaxValue)
{
- EmitLoad(Convert.ToInt32(value), ilg);
+ ilg.Emit(OpCodes.Ldc_I4, unchecked((int)Convert.ToUInt32(value)));
ilg.Emit(OpCodes.Conv_U8);
}
else
diff --git a/src/Flee.Net45/ExpressionElements/Conditional.cs b/src/Flee.Net45/ExpressionElements/Conditional.cs
index c3ef069..a09225c 100644
--- a/src/Flee.Net45/ExpressionElements/Conditional.cs
+++ b/src/Flee.Net45/ExpressionElements/Conditional.cs
@@ -45,79 +45,33 @@ public ConditionalElement(ExpressionElement condition, ExpressionElement whenTru
public override void Emit(FleeILGenerator ilg, IServiceProvider services)
{
- BranchManager bm = new BranchManager();
- bm.GetLabel("falseLabel", ilg);
- bm.GetLabel("endLabel", ilg);
-
- if (ilg.IsTemp == true)
- {
- // If this is a fake emit, then do a fake emit and return
- this.EmitConditional(ilg, services, bm);
- return;
- }
-
- FleeILGenerator ilgTemp = this.CreateTempFleeILGenerator(ilg);
- Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);
-
- // Emit fake conditional to get branch target positions
- this.EmitConditional(ilgTemp, services, bm);
-
- bm.ComputeBranches();
-
- // Emit real conditional now that we have the branch target locations
- this.EmitConditional(ilg, services, bm);
+ this.EmitConditional(ilg, services);
}
- private void EmitConditional(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
+ private void EmitConditional(FleeILGenerator ilg, IServiceProvider services)
{
- Label falseLabel = bm.FindLabel("falseLabel");
- Label endLabel = bm.FindLabel("endLabel");
+ Label falseLabel = ilg.DefineLabel();
+ Label endLabel = ilg.DefineLabel();
// Emit the condition
_myCondition.Emit(ilg, services);
// On false go to the false operand
- if (ilg.IsTemp == true)
- {
- bm.AddBranch(ilg, falseLabel);
- ilg.Emit(OpCodes.Brfalse_S, falseLabel);
- }
- else if (bm.IsLongBranch(ilg, falseLabel) == false)
- {
- ilg.Emit(OpCodes.Brfalse_S, falseLabel);
- }
- else
- {
- ilg.Emit(OpCodes.Brfalse, falseLabel);
- }
+ ilg.EmitBranchFalse(falseLabel);
// Emit the true operand
_myWhenTrue.Emit(ilg, services);
ImplicitConverter.EmitImplicitConvert(_myWhenTrue.ResultType, _myResultType, ilg);
// Jump to end
- if (ilg.IsTemp == true)
- {
- bm.AddBranch(ilg, endLabel);
- ilg.Emit(OpCodes.Br_S, endLabel);
- }
- else if (bm.IsLongBranch(ilg, endLabel) == false)
- {
- ilg.Emit(OpCodes.Br_S, endLabel);
- }
- else
- {
- ilg.Emit(OpCodes.Br, endLabel);
- }
+ ilg.EmitBranch(endLabel);
- bm.MarkLabel(ilg, falseLabel);
ilg.MarkLabel(falseLabel);
// Emit the false operand
_myWhenFalse.Emit(ilg, services);
ImplicitConverter.EmitImplicitConvert(_myWhenFalse.ResultType, _myResultType, ilg);
// Fall through to end
- bm.MarkLabel(ilg, endLabel);
ilg.MarkLabel(endLabel);
}
diff --git a/src/Flee.Net45/ExpressionElements/In.cs b/src/Flee.Net45/ExpressionElements/In.cs
index 2a7c8ef..b844e10 100644
--- a/src/Flee.Net45/ExpressionElements/In.cs
+++ b/src/Flee.Net45/ExpressionElements/In.cs
@@ -118,24 +118,11 @@ public override void Emit(FleeILGenerator ilg, IServiceProvider services)
if ((MyTargetCollectionType != null))
{
this.EmitCollectionIn(ilg, services);
-
}
else
{
- BranchManager bm = new BranchManager();
- bm.GetLabel("endLabel", ilg);
- bm.GetLabel("trueTerminal", ilg);
-
- // Do a fake emit to get branch positions
- FleeILGenerator ilgTemp = this.CreateTempFleeILGenerator(ilg);
- Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);
-
- this.EmitListIn(ilgTemp, services, bm);
-
- bm.ComputeBranches();
-
// Do the real emit
- this.EmitListIn(ilg, services, bm);
+ this.EmitListIn(ilg, services);
}
}
@@ -167,11 +154,11 @@ private MethodInfo GetCollectionContainsMethod()
return MyTargetCollectionType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
}
- private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchManager bm)
+ private void EmitListIn(FleeILGenerator ilg, IServiceProvider services)
{
CompareElement ce = new CompareElement();
- Label endLabel = bm.FindLabel("endLabel");
- Label trueTerminal = bm.FindLabel("trueTerminal");
+ Label endLabel = ilg.DefineLabel();
+ Label trueTerminal = ilg.DefineLabel();
// Cache the operand since we will be comparing against it a lot
LocalBuilder lb = ilg.DeclareLocal(MyOperand.ResultType);
@@ -189,36 +176,22 @@ private void EmitListIn(FleeILGenerator ilg, IServiceProvider services, BranchMa
ce.Initialize(targetShim, argumentElement, LogicalCompareOperation.Equal);
ce.Emit(ilg, services);
- EmitBranchToTrueTerminal(ilg, trueTerminal, bm);
+ EmitBranchToTrueTerminal(ilg, trueTerminal);
}
ilg.Emit(OpCodes.Ldc_I4_0);
ilg.Emit(OpCodes.Br_S, endLabel);
- bm.MarkLabel(ilg, trueTerminal);
ilg.MarkLabel(trueTerminal);
ilg.Emit(OpCodes.Ldc_I4_1);
- bm.MarkLabel(ilg, endLabel);
ilg.MarkLabel(endLabel);
}
- private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal, BranchManager bm)
+ private static void EmitBranchToTrueTerminal(FleeILGenerator ilg, Label trueTerminal)
{
- if (ilg.IsTemp == true)
- {
- bm.AddBranch(ilg, trueTerminal);
- ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
- }
- else if (bm.IsLongBranch(ilg, trueTerminal) == false)
- {
- ilg.Emit(OpCodes.Brtrue_S, trueTerminal);
- }
- else
- {
- ilg.Emit(OpCodes.Brtrue, trueTerminal);
- }
+ ilg.EmitBranchTrue(trueTerminal);
}
public override System.Type ResultType => typeof(bool);
diff --git a/src/Flee.Net45/ExpressionElements/LogicalBitwise/AndOr.cs b/src/Flee.Net45/ExpressionElements/LogicalBitwise/AndOr.cs
index 9ae9ceb..fe70a3b 100644
--- a/src/Flee.Net45/ExpressionElements/LogicalBitwise/AndOr.cs
+++ b/src/Flee.Net45/ExpressionElements/LogicalBitwise/AndOr.cs
@@ -79,20 +79,6 @@ private void DoEmitLogical(FleeILGenerator ilg, IServiceProvider services)
{
// We have to do a 'fake' emit so we can get the positions of the labels
ShortCircuitInfo info = new ShortCircuitInfo();
- // Create a temporary IL generator
- FleeILGenerator ilgTemp = this.CreateTempFleeILGenerator(ilg);
-
- // We have to make sure that the label count for the temp FleeILGenerator matches our real FleeILGenerator
- Utility.SyncFleeILGeneratorLabels(ilg, ilgTemp);
- // Do the fake emit
- this.EmitLogical(ilgTemp, info, services);
-
- // Clear everything except the label positions
- info.ClearTempState();
-
- info.Branches.ComputeBranches();
-
- Utility.SyncFleeILGeneratorLabels(ilgTemp, ilg);
// Do the real emit
this.EmitLogical(ilg, info, services);
@@ -112,7 +98,7 @@ private void DoEmitLogical(FleeILGenerator ilg, IServiceProvider services)
private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services)
{
// We always have an end label
- info.Branches.GetLabel(OurEndLabelKey, ilg);
+ Label endLabel = ilg.DefineLabel();
// Populate our data structures
this.PopulateData(info);
@@ -124,9 +110,9 @@ private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServicePro
ExpressionElement terminalOperand = (ExpressionElement)info.Operands.Pop();
// Emit it
EmitOperand(terminalOperand, info, ilg, services);
- // And jump to the end
- Label endLabel = info.Branches.FindLabel(OurEndLabelKey);
- ilg.Emit(OpCodes.Br_S, endLabel);
+
+ // only 1-3 opcodes, always a short branch
+ ilg.EmitBranch(endLabel);
// Emit our true/false terminals
EmitTerminals(info, ilg, endLabel);
@@ -163,61 +149,14 @@ private static void EmitLogicalShortCircuit(FleeILGenerator ilg, ShortCircuitInf
private static void EmitBranch(AndOrElement op, FleeILGenerator ilg, Label target, ShortCircuitInfo info)
{
- if (ilg.IsTemp == true)
- {
- info.Branches.AddBranch(ilg, target);
-
- // Temp mode; just emit a short branch and return
- OpCode shortBranch = GetBranchOpcode(op, false);
- ilg.Emit(shortBranch, target);
-
- return;
- }
-
- // Emit the proper branch opcode
-
- // Determine if it is a long branch
- bool longBranch = info.Branches.IsLongBranch(ilg, target);
-
// Get the branch opcode
- OpCode brOpcode = GetBranchOpcode(op, longBranch);
-
- // Emit the branch
- ilg.Emit(brOpcode, target);
- }
-
- ///
- /// Emit a short/long branch for an And/Or element
- ///
- ///
- ///
- ///
- private static OpCode GetBranchOpcode(AndOrElement op, bool longBranch)
- {
if (op._myOperation == AndOrOperation.And)
- {
- if (longBranch == true)
- {
- return OpCodes.Brfalse;
- }
- else
- {
- return OpCodes.Brfalse_S;
- }
- }
+ ilg.EmitBranchFalse(target);
else
- {
- if (longBranch == true)
- {
- return OpCodes.Brtrue;
- }
- else
- {
- return OpCodes.Brtrue_S;
- }
- }
+ ilg.EmitBranchTrue(target);
}
+
///
/// Get the label for a short-circuit
///
@@ -316,14 +255,11 @@ private void Pop(Stack operands, Stack operators)
private static void EmitOperand(ExpressionElement operand, ShortCircuitInfo info, FleeILGenerator ilg, IServiceProvider services)
{
// Is this operand the target of a label?
- if (info.Branches.HasLabel(operand) == true)
+ if (info.HasLabel(operand) == true)
{
// Yes, so mark it
- Label leftLabel = info.Branches.FindLabel(operand);
+ Label leftLabel = info.FindLabel(operand);
ilg.MarkLabel(leftLabel);
-
- // Note the label's position
- MarkBranchTarget(info, leftLabel, ilg);
}
// Emit the operand
@@ -339,53 +275,41 @@ private static void EmitOperand(ExpressionElement operand, ShortCircuitInfo info
private static void EmitTerminals(ShortCircuitInfo info, FleeILGenerator ilg, Label endLabel)
{
// Emit the false case if it was used
- if (info.Branches.HasLabel(OurFalseTerminalKey) == true)
+ if (info.HasLabel(OurFalseTerminalKey) == true)
{
- Label falseLabel = info.Branches.FindLabel(OurFalseTerminalKey);
+ Label falseLabel = info.FindLabel(OurFalseTerminalKey);
// Mark the label and note its position
ilg.MarkLabel(falseLabel);
- MarkBranchTarget(info, falseLabel, ilg);
ilg.Emit(OpCodes.Ldc_I4_0);
// If we also have a true terminal, then skip over it
- if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
+ if (info.HasLabel(OurTrueTerminalKey) == true)
{
+ // only 1-3 opcodes, always a short branch
ilg.Emit(OpCodes.Br_S, endLabel);
}
}
// Emit the true case if it was used
- if (info.Branches.HasLabel(OurTrueTerminalKey) == true)
+ if (info.HasLabel(OurTrueTerminalKey) == true)
{
- Label trueLabel = info.Branches.FindLabel(OurTrueTerminalKey);
+ Label trueLabel = info.FindLabel(OurTrueTerminalKey);
// Mark the label and note its position
ilg.MarkLabel(trueLabel);
- MarkBranchTarget(info, trueLabel, ilg);
ilg.Emit(OpCodes.Ldc_I4_1);
}
}
- ///
- /// Note a label's position if we are in mark mode
- ///
- ///
- ///
- ///
- private static void MarkBranchTarget(ShortCircuitInfo info, Label target, FleeILGenerator ilg)
- {
- if (ilg.IsTemp == true)
- {
- info.Branches.MarkLabel(ilg, target);
- }
- }
private static Label GetLabel(object key, FleeILGenerator ilg, ShortCircuitInfo info)
{
- return info.Branches.GetLabel(key, ilg);
+ if (info.HasLabel(key))
+ return info.FindLabel(key);
+ return info.AddLabel(key, ilg.DefineLabel());
}
///
diff --git a/src/Flee.Net45/InternalTypes/BranchManager.cs b/src/Flee.Net45/InternalTypes/BranchManager.cs
index c1729d3..1e01d2a 100644
--- a/src/Flee.Net45/InternalTypes/BranchManager.cs
+++ b/src/Flee.Net45/InternalTypes/BranchManager.cs
@@ -9,32 +9,51 @@ namespace Flee.InternalTypes
[Obsolete("Manages branch information and allows us to determine if we should emit a short or long branch")]
internal class BranchManager
{
- private IList MyBranchInfos;
+ private readonly IList MyBranchInfos;
- private IDictionary