1+ using System ;
2+ using System . Reflection . Emit ;
3+
4+ #if LIGHT_EXPRESSION
5+ using FastExpressionCompiler . LightExpression . ImTools ;
6+ using static FastExpressionCompiler . LightExpression . Expression ;
7+ namespace FastExpressionCompiler . LightExpression . IssueTests ;
8+ #else
9+ using System . Linq . Expressions ;
10+ using static System . Linq . Expressions . Expression ;
11+ namespace FastExpressionCompiler . IssueTests ;
12+ #endif
13+
14+ public struct Issue498_InvalidProgramException_when_using_loop : ITestX
15+ {
16+ public void Run ( TestRun t )
17+ {
18+ Original_test ( t ) ;
19+ }
20+
21+ public void Original_test ( TestContext t )
22+ {
23+ // Creating a label that represents the return value
24+ var result = Variable ( typeof ( int ) , "result" ) ;
25+ var x = Variable ( typeof ( int ) , "x" ) ;
26+
27+ var endMain = Label ( typeof ( int ) , "endMain" ) ;
28+ var endSub1 = Label ( typeof ( void ) , "endSub1" ) ;
29+ var continue1 = Label ( typeof ( void ) , "continue1" ) ;
30+
31+ var loopExpression = Loop (
32+ Block (
33+ Loop (
34+ Block (
35+ IfThen ( GreaterThanOrEqual ( x , Constant ( 10 ) ) ,
36+ Break ( endMain , result ) ) ,
37+ AddAssign ( result , Constant ( 1 ) ) ,
38+ AddAssign ( x , Constant ( 1 ) )
39+ ) ,
40+ endSub1 ,
41+ continue1
42+ )
43+ ) ,
44+ endMain
45+ ) ;
46+
47+ var body = Block ( [ result , x ] , loopExpression ) ;
48+ var expr = Lambda < Func < int > > ( body ) ;
49+ expr . PrintCSharp ( ) ;
50+
51+ var _ = ( Func < int > ) ( ( ) => //int
52+ {
53+ int result = default ;
54+ int x = default ;
55+ while ( true )
56+ {
57+ while ( true )
58+ {
59+ continue1 : ;
60+ if ( x >= 10 )
61+ {
62+ return result ;
63+ }
64+ result += 1 ;
65+ x += 1 ;
66+ }
67+ endSub1 : ;
68+ }
69+ endMain : ;
70+ } ) ;
71+
72+ var fs = expr . CompileSys ( ) ;
73+ fs . PrintIL ( format : ILDecoder . ILFormat . AssertOpCodes ) ;
74+ var calResult = fs ( ) ;
75+ t . AreEqual ( 10 , calResult ) ;
76+
77+ // Act: CompileFast should throw NotSupportedExpressionException or return null
78+ var ff = expr . CompileFast ( ifFastFailedReturnNull : true ) ;
79+ t . IsNotNull ( ff ) ;
80+ ff . PrintIL ( format : ILDecoder . ILFormat . AssertOpCodes ) ;
81+
82+ ff . AssertOpCodes (
83+ OpCodes . Ldloc_1 , // at IL_0000
84+ OpCodes . Ldc_I4_S , // 10 at IL_0001
85+ OpCodes . Clt , // at IL_0003
86+ OpCodes . Ldc_I4_0 , // at IL_0005
87+ OpCodes . Ceq , // at IL_0006
88+ OpCodes . Brfalse , // IL_0019at IL_0008
89+ OpCodes . Ldloc_0 , // at IL_0013
90+ OpCodes . Br , // IL_0037 at IL_0014
91+ OpCodes . Ldloc_0 , // at IL_0019
92+ OpCodes . Ldc_I4_1 , // at IL_0020
93+ OpCodes . Add , // at IL_0021
94+ OpCodes . Stloc_0 , // at IL_0022
95+ OpCodes . Ldloc_1 , // at IL_0023
96+ OpCodes . Ldc_I4_1 , // at IL_0024
97+ OpCodes . Add , // at IL_0025
98+ OpCodes . Stloc_1 , // at IL_0026
99+ OpCodes . Br , // IL_0000 at IL_0027
100+ OpCodes . Br , // IL_0000 at IL_0032
101+ OpCodes . Ret // at IL_0037
102+ ) ;
103+
104+ calResult = ff ( ) ;
105+ t . AreEqual ( 10 , calResult ) ;
106+ }
107+ }
0 commit comments