Skip to content

Commit

Permalink
Merge pull request #89 from hunkydoryrepair/master
Browse files Browse the repository at this point in the history
Multiple critical bug fixes
  • Loading branch information
mparlak authored Mar 8, 2022
2 parents 97b5b72 + 667648b commit 5a923c3
Show file tree
Hide file tree
Showing 35 changed files with 2,154 additions and 666 deletions.
5 changes: 0 additions & 5 deletions src/Flee.Net45/ExpressionElements/Base/ExpressionElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
58 changes: 6 additions & 52 deletions src/Flee.Net45/ExpressionElements/Conditional.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
41 changes: 7 additions & 34 deletions src/Flee.Net45/ExpressionElements/In.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
112 changes: 18 additions & 94 deletions src/Flee.Net45/ExpressionElements/LogicalBitwise/AndOr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

/// <summary>
/// Emit a short/long branch for an And/Or element
/// </summary>
/// <param name="op"></param>
/// <param name="longBranch"></param>
/// <returns></returns>
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);
}


/// <summary>
/// Get the label for a short-circuit
/// </summary>
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}

/// <summary>
/// Note a label's position if we are in mark mode
/// </summary>
/// <param name="info"></param>
/// <param name="target"></param>
/// <param name="ilg"></param>
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());
}

/// <summary>
Expand Down
Loading

0 comments on commit 5a923c3

Please sign in to comment.