Skip to content

Commit 713ae71

Browse files
committed
more configs to the god of configs
1 parent 2e8f948 commit 713ae71

7 files changed

Lines changed: 113 additions & 32 deletions

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8218,25 +8218,33 @@ public static T GetFirst<T>(this IEnumerable<T> source)
82188218
[RequiresUnreferencedCode(Trimming.Message)]
82198219
public static class ILGeneratorTools
82208220
{
8221+
/// <summary>Configuration option to disable the pooling</summary>
8222+
public static bool DisableILGeneratorPooling;
8223+
/// <summary>Configuration option to disable the ILGenerator Emit debug output</summary>
8224+
public static bool DisableDemit;
8225+
82218226
#if DEMIT
82228227
[MethodImpl((MethodImplOptions)256)]
82238228
public static void Demit(this ILGenerator il, OpCode opcode, [CallerMemberName] string emitterName = "", [CallerLineNumber] int emitterLine = 0)
82248229
{
82258230
il.Emit(opcode);
8231+
if (DisableDemit) return;
82268232
Debug.WriteLine($"{opcode} -- {emitterName}:{emitterLine}");
82278233
}
82288234

82298235
[MethodImpl((MethodImplOptions)256)]
82308236
public static void Demit(this ILGenerator il, OpCode opcode, Type type, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82318237
{
82328238
il.Emit(opcode, type);
8239+
if (DisableDemit) return;
82338240
Debug.WriteLine($"{opcode} {type.ToCode(stripNamespace: true)} -- {emitterName}:{emitterLine}");
82348241
}
82358242

82368243
[MethodImpl((MethodImplOptions)256)]
82378244
public static void Demit(this ILGenerator il, OpCode opcode, FieldInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82388245
{
82398246
il.Emit(opcode, value);
8247+
if (DisableDemit) return;
82408248

82418249
var declType = value.DeclaringType?.ToCode(stripNamespace: true) ?? "";
82428250
var fieldType = value.FieldType.ToCode(stripNamespace: true);
@@ -8247,6 +8255,7 @@ public static void Demit(this ILGenerator il, OpCode opcode, FieldInfo value, [C
82478255
public static void Demit(this ILGenerator il, OpCode opcode, MethodInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82488256
{
82498257
il.Emit(opcode, value);
8258+
if (DisableDemit) return;
82508259

82518260
var declType = value.DeclaringType?.ToCode(stripNamespace: true) ?? "";
82528261
var retType = value.ReturnType.ToCode(stripNamespace: true);
@@ -8260,6 +8269,7 @@ public static void Demit(this ILGenerator il, OpCode opcode, MethodInfo value, [
82608269
public static void Demit(this ILGenerator il, OpCode opcode, ConstructorInfo value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82618270
{
82628271
il.Emit(opcode, value);
8272+
if (DisableDemit) return;
82638273

82648274
var declType = value.DeclaringType?.ToCode(stripNamespace: true) ?? "";
82658275
var signature = value.ToString();
@@ -8273,6 +8283,7 @@ public static void Demit(this ILGenerator il, OpCode opcode, Label value,
82738283
[CallerArgumentExpression("value")] string valueName = null, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82748284
{
82758285
il.Emit(opcode, value);
8286+
if (DisableDemit) return;
82768287
Debug.WriteLine($"{opcode} {valueName ?? value.ToString()} -- {emitterName}:{emitterLine}");
82778288
}
82788289

@@ -8281,62 +8292,71 @@ public static void DmarkLabel(this ILGenerator il, Label value,
82818292
[CallerArgumentExpression("value")] string valueName = null, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82828293
{
82838294
il.MarkLabel(value);
8295+
if (DisableDemit) return;
82848296
Debug.WriteLine($"{valueName ?? value.ToString()} -- {emitterName}:{emitterLine}: ");
82858297
}
82868298

82878299
[MethodImpl((MethodImplOptions)256)]
82888300
public static void Demit(this ILGenerator il, OpCode opcode, byte value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82898301
{
82908302
il.Emit(opcode, value);
8303+
if (DisableDemit) return;
82918304
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
82928305
}
82938306

82948307
[MethodImpl((MethodImplOptions)256)]
82958308
public static void Demit(this ILGenerator il, OpCode opcode, sbyte value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
82968309
{
82978310
il.Emit(opcode, value);
8311+
if (DisableDemit) return;
82988312
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
82998313
}
83008314

83018315
[MethodImpl((MethodImplOptions)256)]
83028316
public static void Demit(this ILGenerator il, OpCode opcode, short value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83038317
{
83048318
il.Emit(opcode, value);
8319+
if (DisableDemit) return;
83058320
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83068321
}
83078322

83088323
[MethodImpl((MethodImplOptions)256)]
83098324
public static void Demit(this ILGenerator il, OpCode opcode, int value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83108325
{
83118326
il.Emit(opcode, value);
8327+
if (DisableDemit) return;
83128328
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83138329
}
83148330

83158331
[MethodImpl((MethodImplOptions)256)]
83168332
public static void Demit(this ILGenerator il, OpCode opcode, long value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83178333
{
83188334
il.Emit(opcode, value);
8335+
if (DisableDemit) return;
83198336
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83208337
}
83218338

83228339
[MethodImpl((MethodImplOptions)256)]
83238340
public static void Demit(this ILGenerator il, OpCode opcode, float value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83248341
{
83258342
il.Emit(opcode, value);
8343+
if (DisableDemit) return;
83268344
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83278345
}
83288346

83298347
[MethodImpl((MethodImplOptions)256)]
83308348
public static void Demit(this ILGenerator il, OpCode opcode, double value, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83318349
{
83328350
il.Emit(opcode, value);
8351+
if (DisableDemit) return;
83338352
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83348353
}
83358354

83368355
[MethodImpl((MethodImplOptions)256)]
83378356
public static void Demit(this ILGenerator il, string value, OpCode opcode, [CallerMemberName] string emitterName = null, [CallerLineNumber] int emitterLine = 0)
83388357
{
83398358
il.Emit(opcode, value);
8359+
if (DisableDemit) return;
83408360
Debug.WriteLine($"{opcode} {value} -- {emitterName}:{emitterLine}");
83418361
}
83428362

@@ -8422,10 +8442,10 @@ public static ILGenerator RentPooledOrNewILGenerator(DynamicMethod dynMethod, Ty
84228442

84238443
/// <summary>Should be called only after call to DynamicMethod.CreateDelegate</summary>
84248444
[MethodImpl((MethodImplOptions)256)]
8425-
public static void FreePooledILGenerator(DynamicMethod _, ILGenerator il)
8445+
public static void FreePooledILGenerator(DynamicMethod dynMethod, ILGenerator il)
84268446
{
84278447
// todo: @wip #475 might be required to avoid the undefined behavior when the previous DynamicMethod is still linked to the wrong ILGenerator
8428-
// IlGeneratorField.SetValue(dynMethod, null);
8448+
// ILGeneratorField.SetValue(dynMethod, null);
84298449

84308450
if (DynamicMethodHacks.ReuseDynamicILGenerator != null)
84318451
_pooledILGenerator = il;
@@ -8453,18 +8473,27 @@ public static ILGenerator RentPooledOrNewILGenerator(DynamicMethod dynMethod, Ty
84538473
internal static SignatureHelper _pooledSignatureHelper;
84548474
#pragma warning restore CS0649
84558475

8476+
internal static FieldInfo ILGeneratorField;
8477+
internal static Type DynamicILGeneratorType;
8478+
84568479
static DynamicMethodHacks()
84578480
{
84588481
const BindingFlags instanceNonPublic = BindingFlags.Instance | BindingFlags.NonPublic;
84598482
const BindingFlags instancePublic = BindingFlags.Instance | BindingFlags.Public;
84608483
const BindingFlags staticNonPublic = BindingFlags.Static | BindingFlags.NonPublic;
84618484
const BindingFlags staticPublic = BindingFlags.Static | BindingFlags.Public;
84628485

8463-
var _iLGeneratorField = typeof(DynamicMethod).GetField("_ilGenerator", instanceNonPublic);
8464-
if (_iLGeneratorField == null)
8465-
return; // nothing to look here
8486+
ILGeneratorField = typeof(DynamicMethod).GetField("_ilGenerator", instanceNonPublic);
8487+
if (ILGeneratorField == null)
8488+
return; // nothing to do here
8489+
8490+
DynamicILGeneratorType = ILGeneratorField.FieldType;
84668491

8467-
var DynamicILGeneratorType = _iLGeneratorField.FieldType;
8492+
// Avoid demit polluting the output of the the initialization phase
8493+
var prevDemitValue = ILGeneratorTools.DisableDemit;
8494+
ILGeneratorTools.DisableDemit = true;
8495+
8496+
if (!ILGeneratorTools.DisableILGeneratorPooling)
84688497
{
84698498
// ## 1. Reuse the DynamicILGenerator
84708499
//
@@ -8756,7 +8785,7 @@ internal static SignatureHelper GetMethodSigHelper(
87568785
il.Emit(OpCodes.Call, SignatureHelper_GetSignatureMethod);
87578786
ExpressionCompiler.EmittingVisitor.EmitStoreLocalVariable(il, sigBytesVar);
87588787

8759-
// return the signature helper to the pool
8788+
// free the signature helper to the pool
87608789
ExpressionCompiler.EmittingVisitor.EmitLoadLocalVariable(il, sigHelperVar);
87618790
il.Emit(OpCodes.Stsfld, pooledSignatureHelperField);
87628791

@@ -8821,7 +8850,7 @@ internal byte[] GetSignature(bool appendEndOfSig)
88218850
// store the reused ILGenerator to
88228851
il.Emit(OpCodes.Ldarg_1);
88238852
il.Emit(OpCodes.Ldarg_2);
8824-
il.Emit(OpCodes.Stfld, _iLGeneratorField);
8853+
il.Emit(OpCodes.Stfld, ILGeneratorField);
88258854

88268855
il.Emit(OpCodes.Ret);
88278856

@@ -8872,9 +8901,9 @@ public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
88728901

88738902
// looking for the `SignatureHelper.AddArgument(Type argument, bool pinned)`
88748903
var typeAndBoolParamTypes = ExpressionCompiler.RentPooledOrNewParamTypes(typeof(Type), typeof(bool));
8875-
var SignaturHelper_AddArgumentMethod = typeof(SignatureHelper).GetMethod("AddArgument", typeAndBoolParamTypes);
8904+
var SignatureHelper_AddArgumentMethod = typeof(SignatureHelper).GetMethod("AddArgument", typeAndBoolParamTypes);
88768905
ExpressionCompiler.FreePooledParamTypes(typeAndBoolParamTypes);
8877-
if (SignaturHelper_AddArgumentMethod == null)
8906+
if (SignatureHelper_AddArgumentMethod == null)
88788907
goto endOfGetNextVar;
88798908

88808909
// our own helper - always available
@@ -8884,14 +8913,15 @@ public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
88848913
var paramTypes = ExpressionCompiler.RentPooledOrNewParamTypes(typeof(ExpressionCompiler.ArrayClosure), typeof(ILGenerator), typeof(Type));
88858914
var dynMethod = new DynamicMethod(string.Empty, typeof(int), paramTypes, typeof(ExpressionCompiler.ArrayClosure), true);
88868915

8887-
var il = RentPooledOrNewILGenerator(dynMethod, typeof(int), paramTypes);
8916+
// it does not use the pooled il generator here, to isolate this variable hack from the il generator pooling hack and for the better problem diagnostics
8917+
var il = dynMethod.GetILGenerator(); // todo: @wip set the stream size
88888918

88898919
// emitting `il.m_localSignature.AddArgument(type);`
88908920
il.Emit(OpCodes.Ldarg_1); // load `il` argument (arg_0 is the empty closure object)
88918921
il.Emit(OpCodes.Ldfld, m_localSignatureField);
88928922
il.Emit(OpCodes.Ldarg_2); // load `type` argument
88938923
il.Emit(OpCodes.Ldc_I4_0); // load `pinned: false` argument
8894-
il.Emit(OpCodes.Call, SignaturHelper_AddArgumentMethod);
8924+
il.Emit(OpCodes.Call, SignatureHelper_AddArgumentMethod);
88958925

88968926
// emitting `return PostInc(ref il.LocalCount);`
88978927
il.Emit(OpCodes.Ldarg_1); // load `il` argument
@@ -8903,11 +8933,13 @@ public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
89038933
GetNextLocalVarLocation = (Func<ILGenerator, Type, int>)
89048934
dynMethod.CreateDelegate(typeof(Func<ILGenerator, Type, int>), ExpressionCompiler.EmptyArrayClosure);
89058935

8906-
FreePooledILGenerator(dynMethod, il);
89078936
ExpressionCompiler.FreePooledParamTypes(paramTypes);
89088937
endOfGetNextVar:;
89098938
}
89108939

8940+
// Restore the demit
8941+
ILGeneratorTools.DisableDemit = prevDemitValue;
8942+
89118943
// ## 3 TBD
89128944
//
89138945
// todo: @perf do batch Emit by manually calling `EnsureCapacity` once then `InternalEmit` multiple times

src/FastExpressionCompiler/ILReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static ILReader Create(object source)
4343
#endif
4444

4545
#if !NET8_0_OR_GREATER
46-
if (dynamicMethod == null && sourceType == _rtDynamicMethodType)
46+
if (dynamicMethod == null & sourceType == _rtDynamicMethodType)
4747
dynamicMethod = (DynamicMethod)_fiOwner.GetValue(source);
4848
#if DEBUG_INTERNALS
4949
Console.WriteLine($"m_rtDynamicMethodType: {_rtDynamicMethodType}, _fiOwner: {_fiOwner}");

src/FastExpressionCompiler/TestTools.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#if LIGHT_EXPRESSION
1414
namespace FastExpressionCompiler.LightExpression;
15+
1516
using FastExpressionCompiler.LightExpression.ILDecoder;
1617
using FastExpressionCompiler.LightExpression.ImTools;
1718
#else
@@ -551,10 +552,13 @@ public record struct TestStats(
551552
int FirstFailureIndex,
552553
int FailureCount);
553554

554-
public enum TestTracking
555+
[Flags]
556+
public enum TestFlags : byte
555557
{
556-
TrackFailedTestsOnly = 0,
557-
TrackAllTests,
558+
Default = 0,
559+
TrackAllInsteadOfFailedOnlyTests = 1 << 0,
560+
RethrowException = 1 << 1,
561+
558562
}
559563

560564
#if !NETCOREAPP3_0_OR_GREATER
@@ -946,9 +950,8 @@ public sealed class TestRun
946950
public SmallList<TestStats> Stats;
947951
public SmallList<TestFailure> Failures;
948952

949-
// todo: @wip put the output under the feature flag
950953
/// <summary>Will output the failures while running</summary>
951-
public void Run<T>(T test, TestTracking tracking = TestTracking.TrackFailedTestsOnly) where T : ITestX
954+
public void Run<T>(T test, TestFlags tracking = TestFlags.Default) where T : ITestX
952955
{
953956
var totalTestCount = TotalTestCount;
954957
var failureCount = Failures.Count;
@@ -959,13 +962,13 @@ public void Run<T>(T test, TestTracking tracking = TestTracking.TrackFailedTests
959962
}
960963
catch (Exception ex)
961964
{
965+
if ((tracking & TestFlags.RethrowException) != 0)
966+
throw;
962967
testStopException = ex;
963968
}
964969

965970
var testFailureCount = Failures.Count - failureCount;
966-
if (testStopException != null ||
967-
tracking == TestTracking.TrackAllTests ||
968-
tracking == TestTracking.TrackFailedTestsOnly & testFailureCount > 0)
971+
if (testStopException != null | testFailureCount > 0 | (tracking & TestFlags.TrackAllInsteadOfFailedOnlyTests) != 0)
969972
{
970973
// todo: @perf Or may be we can put it under the debug only?
971974
var testsType = test.GetType();

test/FastExpressionCompiler.IssueTests/Issue14_String_constant_comparisons_fail.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public int Run()
2828
return 6;
2929
}
3030

31-
3231
public void String_equality_should_work()
3332
{
3433
System.Linq.Expressions.Expression<Func<string, bool>> se = str => str == "Hello";
@@ -43,7 +42,6 @@ public void String_equality_should_work()
4342
Asserts.IsTrue(isHello(new StringBuilder("Hello").ToString()));
4443
}
4544

46-
4745
public void String_not_equality_should_work()
4846
{
4947
System.Linq.Expressions.Expression<Func<string, bool>> se = str => str != "Hello";
@@ -58,7 +56,6 @@ public void String_not_equality_should_work()
5856
Asserts.IsFalse(isHello(new StringBuilder("Hello").ToString()));
5957
}
6058

61-
6259
public void Guid_equality_should_work()
6360
{
6461
var expectedId = Guid.NewGuid();
@@ -72,7 +69,6 @@ public void Guid_equality_should_work()
7269
Asserts.IsTrue(isExpectedId(expectedId));
7370
}
7471

75-
7672
public void Guid_not_equality_should_work()
7773
{
7874
var expectedId = Guid.NewGuid();
@@ -86,7 +82,6 @@ public void Guid_not_equality_should_work()
8682
Asserts.IsFalse(isExpectedId(expectedId));
8783
}
8884

89-
9085
public void Enum_equality_should_work()
9186
{
9287
var expectedExpr = Constant(Blah.Bar, typeof(Blah));
@@ -102,7 +97,6 @@ public void Enum_equality_should_work()
10297

10398
enum Blah { Foo, Bar }
10499

105-
106100
public void Class_Equals_equality_should_work()
107101
{
108102
var expected = new Pooh(42);

test/FastExpressionCompiler.IssueTests/Issue473_InvalidProgramException_when_using_Expression_Condition_with_converted_decimal_expression.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22

33
#if LIGHT_EXPRESSION
4-
using ExpressionType = System.Linq.Expressions.ExpressionType;
54
using static FastExpressionCompiler.LightExpression.Expression;
65
namespace FastExpressionCompiler.LightExpression.IssueTests;
76
#else

0 commit comments

Comments
 (0)