рдбреЗрд▓реНрдлреА + рдЕрд╕реЗрдВрдмрд▓рд░ рдореЗрдВ рдЕрдирдВрдд рдореВрд▓реНрдп рдЬрдирд░реЗрдЯрд░

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ, рдореВрд▓реНрдпреЛрдВ рдХреЗ рдЕрдирдВрдд рдЕрдиреБрдХреНрд░рдо (рдЖрдорддреМрд░ рдкрд░ рд╕рдВрдЦреНрдпрд╛) рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдФрд░ рдЗрди рджреГрд╢реНрдпреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдпрд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдмрд╛рдзрд┐рдд рдХрд┐рдП рдмрд┐рдирд╛, рдЕрдкрдиреА рдЖрдВрддрд░рд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ-рдПрдХ рдХрд░рдХреЗ рдорд╛рди рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╕рд╛рдорд╛рдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдХреЙрд▓ рдХреЗ рд╕реНрдерд╛рди рдкрд░ "рд╡рд╛рдкрд╕реА" рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдХреЛрдИ рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВ рд╣реИред рдПрдХ рдЪреБрдиреМрддреА - рдПрдХ рдкрд░рд┐рдгрд╛рдоред
рдбреЗрд▓реНрдлреА рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ (GetEnumerator / MoveNext / GetCurrent) рдХреЗ рд╕рд╛рде рдЬрдирд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдПрдХ рдЬрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди (рд╢рд╛рдпрдж рдЕрдирдВрдд) рднреА рдмрдирд╛рдПрдВрдЧреЗ рдФрд░ рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рддрд░рд╣ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдиреНрдпреВрдорд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рд╕рдм рдХреБрдЫ рдкрд╛рд░рджрд░реНрд╢реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рджреЗрд░реА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░реЗред

рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрд╛рд╣рд░ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА рдорд╛рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрдерддрд╛ рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдХреЙрд▓рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╣реА рд╕реНрдЯреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рдЕрдЧрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдЕрдЧрд▓рд╛ рдорд╛рди рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд░рдо рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХреЙрд▓ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛ рдХреНрд╖рддрд┐рдЧреНрд░рд╕реНрдд рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЬрдм рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЙрд╕реА рд╕реНрдерд╛рди рд╕реЗ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИред рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╕реНрдЯреИрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рди рддреЛ рд╡рд┐рдВрдбреЛрдЬ рдФрд░ рди рд╣реА рдкреНрд░реЛрд╕реЗрд╕рд░ рд╣рдореЗрдВ рдХрдИ рд╕реНрдЯреИрдХ рдмрдирд╛рдиреЗ рд╕реЗ рд░реЛрдХ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рдордп-рд╕рдордп рдкрд░ рдЙрдирдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рд╣рдо рдЦреЛрддреЗ рд╣реИрдВ рд╡рд╣ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдЕрдкрд╡рд╛рдж рд╣реИ (рдХреЗрд╡рд▓, рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдЯреИрдХ рд╕реЗ рдкрд░реЗ рдЬрд╛рддрд╛ рд╣реИ)ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдПрдХ рдорд╛рдирдХ рдПрдХреНрд╕реЗрд╕ рдЙрд▓реНрд▓рдВрдШрди рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЖрдк рдЬрдирд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдХреБрдЫ рдкрд░рд┐рдЪрд┐рдд рдФрд░ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рдЬрдирд░реЗрдЯрд░ред
рд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЪреБрдирдиреЗ рдореЗрдВ рд╕реАрдорд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ (рдЙрддреНрдкрдиреНрди) рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, "рдЕрд╕реАрдо" рд╣реЛред рдПрдХ "рдЕрдирдВрдд" рдлрд╝рдВрдХреНрд╢рди рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЧрдгрдирд╛ рдореЗрдВ рдлреЙрд░-рдЗрди рд▓реВрдк рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдмреНрд░реЗрдХ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рджреНрд╡рд╛рд░рд╛ рдмрд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдбрд┐рд╕реНрдХ рдкрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЦреЛрдЬ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рд╕рд╣реА рдПрдХ рдорд┐рд▓ рдЬрд╛рддрд╛ рд╣реИред рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рд▓рд┐рдЦрдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдлрд╛рдпрджреЗ рд╣реИрдВ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рд╕реНрдерд╛рдиреАрдп рдЪрд░ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, TSearchRec FindFirst / FindNext / FindClose рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдПрдХ рдЕрд╕реНрдерд╛рдпреА рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, рдЬрдирд░реЗрдЯрд░ рдХрдо рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреА рдЦреЛрдЬ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдФрд╕рдд рд╕рдордп рдЖрдзрд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╣ рдкрд╛рдпрд╛ рдЧрдпрд╛ рддрддреНрд╡ рдХреЗ рдмрд╛рдж рд╕рд░рдгреА рдХреЗ рд╢реЗрд╖ рднрд╛рдЧ рдХреЗ рдЧрдарди рдкрд░ рдЦрд░реНрдЪ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред
рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рд╣реИ:

procedure Fibonacci( Generator: TGeneratorWithParam<UInt64, UInt64> ); var V1, V2, V: UInt64; begin V1 := 1; V2 := 1; V := V1 + V2; while Generator.Yield( V ) and ( V >= V2 ) do begin V1 := V2; V2 := V; V := V1 + V2; end; end; 


рдлрд╝рдВрдХреНрд╢рди рдЬрдирд░реЗрдЯрд░ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬреЗрдирд░реЗрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ "рдПрдиреНрдпреВрдорд░реЗрдЯрд░" рдХреЛ "рджреЗрддрд╛ рд╣реИ"ред
рдЬрдм рдорд╛рди рдмрд┐рдЯ рдЧреНрд░рд┐рдб ("рдФрд░" рдХреЗ рдмрд╛рдж рджреВрд╕рд░реА рд╕реНрдерд┐рддрд┐) рд╕реЗ рдкрд░реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдЕрдкрдирд╛ рдХрд╛рдо рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрддрд╛ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЬреЗрдирд░реЗрдЯрд░.Yield рдЧрд▓рдд рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рднреА рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЬрд╛рдПрдЧрд╛ред рдРрд╕рд╛ рддрдм рд╣реЛрдЧрд╛ рдЬрдм рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рдХреЛ 2 ^ 64 рддрдХ рдХреЗ рд╕рднреА рдирдВрдмрд░реЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирд╖реНрдЯ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЕрд░реНрдерд╛рддреН, рдЗрди-рд▓реВрдк рдХреЛ рдмреНрд░реЗрдХ, рдирд┐рдХрд╛рд╕ рдмрдпрд╛рди, рдпрд╛ рдЕрдкрд╡рд╛рдж рджреНрд╡рд╛рд░рд╛ рд╕рдорд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЖрдЙрдЯрдкреБрдЯ рдирдВрдмрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:

  for X in TGenerator<UInt64>.Create( Fibonacci ) do begin WriteLn( X ); end; 


рдЕрдм рд╣рдореЗрдВ рдРрд╕реЗ рд╡рд░реНрдЧ TGeneratorWithParam <T1, T2> рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдЗрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХреЗрдВред

рдХреЛрдб рдирд╡реАрдирддрдо рдбреЗрд▓реНрдлреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ (XE2, XE3) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ рдФрд░ 32-рдмрд┐рдЯ рдФрд░ 64-рдмрд┐рдЯ рдХрдВрдкрд╛рдЗрд▓рд░ (рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рдкреВрд░реНрдг рдХреЛрдб рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд) рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдЧрд╛ред

рддрд╛рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ "рд╡рд╛рдкрд╕" рдХрд░ рд╕рдХреЗ, рд╣рдо TGenerator рд╡рд░реНрдЧ рдХреЛ рдорд╛рдирдХреАрдХреГрдд рдХрд░ рджреЗрдВрдЧреЗред
рдлрд┐рд░ рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

  TGeneratorContext = record SP: NativeUInt; //  . //   -    //     , //    -     //  . Stack: PNativeUIntArray; //   . //     VirtualAlloc StackLen: NativeUInt; //   Generator: TObject; //     Active: Boolean; //    end; TGeneratorBase = class protected Context: TGeneratorContext; //  ( ..  ) FFinished: Boolean; //    end; TGeneratorWithParam<ParamT, ResultT> = class( TGeneratorBase ) protected FFunc: TGeneratorFunction<ParamT, ResultT>; FValue: ResultT; FParam: ParamT; public procedure Stop; function Yield( const Value: ResultT ): Boolean; public function GetCurrent: ResultT; function MoveNext: Boolean; property Current: ResultT read GetCurrent; function GetEnumerator: TGeneratorWithParam<ParamT, ResultT>; constructor Create( Func: TGeneratorFunction<ParamT, ResultT>; const Param: ParamT ); overload; constructor Create( Func: TGeneratorFunction<ParamT, ResultT> ); overload; destructor Destroy; override; property Param: ParamT read FParam; property Value: ResultT read FValue; end; TGenerator<T> = class( TGeneratorWithParam<T, T> ); //       : //TGenerator<T> = TGeneratorWithParam<T, T>; //   Delphi    


рдЖрдкрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрдХреНрд╖ (рджреЛрдиреЛрдВ рд╕реЗ-рдЪрдХреНрд░ рд╕реЗ рдмрд╛рд╣рд░) рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдкрдХреНрд╖ (рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ) рд╕реЗ рдЧрдгрдирд╛ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЬреИрд╕реЗ рд╣реА рдореБрдЦреНрдп рдХрд╛рд░реНрдпрдХреНрд░рдо рдлреЙрд░-рдЗрди рд▓реВрдк рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, TGenerator рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╡рд┐рдирд╛рд╢рдХрд░реНрддрд╛ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ:
1. рдлрд┐рд░, рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░ рд╕рдВрджрд░реНрдн рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред
2. рдЬрдирд░реЗрдЯрд░ рд╕рдорд╛рд░реЛрд╣ рдкрдХреНрд╖ рдкрд░ рдпреАрд▓реНрдб рд╡рд┐рдзрд┐ рдЧрд▓рдд рд░рд┐рдЯрд░реНрди рдХрд░рддреА рд╣реИ
3. рдЬрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдЪрдХреНрд░ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЕрдкрдирд╛ рдХрд╛рдо рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЕрдкрдиреЗ рдЪрд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЕрдВрддрд┐рдо рд░реВрдк рджреЗ рд╕рдХрддрд╛ рд╣реИ, рд╕рдВрд╕рд╛рдзрди рдореБрдХреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЖрджрд┐

рдЖрдЗрдП TGenerator рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдЯреНрд░рд┐рдХ рдХрд░реЗрдВред рд╣рдо GetEnumerator рд╡рд┐рдзрд┐ рдФрд░ рд╕рд╛рде рд╣реА MoveNext рдФрд░ GetCurrent рддрд░реАрдХреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВрдЧреЗ (рд╣рдо рд╡рд░реНрддрдорд╛рди рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рднреВрд▓реЗрдВрдЧреЗ)ред
GetEnumerator рд╡рд┐рдзрд┐ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

 function TGeneratorWithParam<ParamT, ResultT>.GetEnumerator: TGeneratorWithParam<ParamT, ResultT>; begin Result := Self; end; 


рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ? рдлрд╝рдВрдХреНрд╢рди рдЬрдирд░реЗрдЯрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рд╡рд░реНрдЧ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднреА: рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдиреЗ рдлрд╝реЙрд░-рдЗрди рд▓реВрдк рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд╛рдж рдЕрдкрдирд╛ рдирд┐рд╖реНрдкрд╛рджрди рдкреВрд░рд╛ рдХрд┐рдпрд╛, рддреЛ рдЕрдЧрд▓реЗ рдЪрдХреНрд░ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдмрд╛рд░-рдмрд╛рд░ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рджреНрдж рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╡рд╣ рд╣реИ:
1. рдПрдХ рдЬрдирд░реЗрдЯрд░ рдмрдирд╛рдпрд╛
2. рдПрдХ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ (рдЙрд░реНрдл рдЬрдирд░реЗрдЯрд░) рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛
3. рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛
4. рдирд╖реНрдЯ рдХрд░ рджрд┐рдпрд╛ рдкреНрд░рдЧрдгрдХ (рдЙрд░реНрдл рдЬрдирд░реЗрдЯрд░)

рдпрджрд┐ рдЖрдкрдХреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдФрд░ рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЬрдирд░реЗрдЯрд░ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ GetEnumerator рд╡рд┐рдзрд┐ рдореЗрдВ рдХреЛрдИ рдСрдмреНрдЬреЗрдХреНрдЯ (рдпрд╛ рд░рд┐рдХреЙрд░реНрдб рднреА) рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд▓реВрдк рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдореБрдХреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣реА рдмрд╛рдд рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рд░рд┐рдХреЙрд░реНрдб рдкрд░ рднреА рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╡реЗ рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рддрдереНрдп рдХрд┐ рдпрд╣ рдирд┐рдпрдо рд╡рд╕реНрддреБрдУрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ, рдбреЗрд▓реНрдлреА рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕рд╛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЕрднреА рддрдХ рдмрдирд╛рдИ рдЧрдИ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдХреЛрдИ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╡рд┐рд▓реЛрдкрди рдирд╣реАрдВ рд╣реИ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрднреА рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЕрднреА рдХрд╛рдо рдЪрд▓ рд░рд╣рд╛ рд╣реИ рдкреВрд░реНрдг рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рдкрд░, рдЗрд╕реЗ рд╕реЛрд░реНрд╕ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред XE3 рд╕реЗрдкрд╛рд╕)ред

рдЬрдирд░реЗрдЯрд░ рдмрдирд╛рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдирд┐рдореНрди рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

1. рд╕реНрдЯреИрдХ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░реЗрдВред

  Context.Stack := VirtualAlloc( nil, MinStackSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE ); Context.StackLen := MinStackSize div SizeOf( NativeUInt ); 


2. рд╕реВрдЪрдХ рд╕рдкрд╛ рд╕реЗрдЯ рдХрд░реЗрдВред

  Context.SP := NativeUInt( @Context.Stack^[Context.StackLen - 8 {$IFDEF CPUX64} - 6 {$ENDIF}] ); 


2. рд╕реНрдЯреИрдХ рдкрд░ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдорд╛рди рд▓рд┐рдЦреЗрдВред

  Context.Stack^[Context.StackLen - 4] := GetFlags; //    (EFLAGS/RFLAGS) Pointer( Context.Stack^[Context.StackLen - 3] ) := @Func; //    (EIP/RIP) Pointer( Context.Stack^[Context.StackLen - 2] ) := @TGeneratorContext.Return; //     ,   - Pointer( Context.Stack^[Context.StackLen - 1] ) := Self; // Self   TGeneratorContext.Return 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдбрд┐рдмрдЧрд┐рдВрдЧ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреИрдХ рдмрдирд╛рдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж, рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рджрд░реНрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

  FillChar( Context.Stack^, Context.StackLen * SizeOf( NativeUInt ), $DD ); 


рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ, рдЖрдкрдХреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд░реЛрдХрдиреЗ рдФрд░ рд╕реНрдЯреИрдХ рдХреЗ рд▓рд┐рдП рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

  if not FFinished then Stop; VirtualFree( Context.Stack, 0, MEM_RELEASE ); 


MoveNext рд╡рд┐рдзрд┐ рдЬрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧреА, рдЗрд╕рд╕реЗ рдПрдХ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЧрдгрдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рд╣реИ (рдЕрд░реНрдерд╛рдд, рдлрд╝рдВрдХреНрд╢рди рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ)ред рд╡рд┐рдзрд┐ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рдЖрдк рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХрд┐рддрдирд╛ рдХрд░рддрд╛ рд╣реИред

 function TGeneratorWithParam<ParamT, ResultT>.MoveNext: Boolean; begin if not Context.Active then //     ... begin Context.Active := True; Context.Enter( NativeUInt( Self ) ); //  :   ->   //    Enter    //    (Self),   EAX ( RCX  x64) //   .     //     . end else begin Context.Enter( Ord( True ) ); //  ,    ,   //   EAX  True.     //   Yield    //    . end; Result := not FFinished; //         FValue, //      True,    // ,  False,  - //   (   ). end; 


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХрд╛рдлреА рд╕рд░рд▓ рд▓рдЧрддреА рд╣реИред рдХреЗрд╡рд▓ рддреАрди рд▓рд╛рдЗрдиреЗрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдХрднреА рднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдпреАрд▓реНрдб рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕реЗ рдЕрдЧрд▓реЗ рдорд╛рди рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рдкрд░ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

 function TGeneratorWithParam<ParamT, ResultT>.Yield( const Value: ResultT ): Boolean; begin FValue := Value; //      Context.Leave; //  :   ->   Result := not FFinished; //     ,   , //   Yield,     //     (    ), //         // Delphi     // . end; 


рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдЬреЗрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЙрддреНрдкрдиреНрди рдореВрд▓реНрдп рдХреЛ рдмрдЪрд╛рдиреЗ рдФрд░ рдореБрдЦреНрдп рд╕рдВрджрд░реНрдн рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯрдирд╛ рд╣реИ, рддрд╛рдХрд┐ рдпрд╣ рдорд╛рди рдлреЙрд░-рдЗрди рд▓реВрдк рдХреЗ рдЕрдВрджрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рддред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, Context.Leave рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕реНрдЯреИрдХ рдХреЛ рдмрджрд▓ рджрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдХрдВрдЯреНрд░реЛрд▓ рдХреЛ рдХреЙрд▓ рдХреЛ Context.Enter рдкреНрд░рдХреНрд░рд┐рдпрд╛ (MoveNext рд╡рд┐рдзрд┐ рдореЗрдВ) рдХреЗ рдмрд╛рдж рддреБрд░рдВрдд рд▓рд╛рдЗрди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╕реНрдЯреЙрдк рд╡рд┐рдзрд┐ рдХреЛ рдПрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдпрджрд┐, рддрдм рддрдХ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдиреЗ рдЕрднреА рддрдХ рдореВрд▓реНрдпреЛрдВ рдХреА рдкреАрдврд╝реА рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдЪрд░ рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк рджреЗрдиреЗ, рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдФрд░ рдЖрдо рддреМрд░ рдкрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдЦрддреНрдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рддрд╛рдХрд┐ рдпреАрд▓реНрдб рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЧрд▓рдд рд╣реЛред

 procedure TGeneratorWithParam<ParamT, ResultT>.Stop; begin FFinished := True; if Context.Active then //      ... Context.Enter( Ord( False ) ); //  :   ->   //     EAX  False, //     ,    Yield. end; 


рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реЛрдЧреАред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рджреЛрдиреЛрдВ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЙрдирдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд░рд╛рдЬреНрдп рдХреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдЯреИрдХ рдореЗрдВ рд╕рд╣реЗрдЬрдирд╛ рдФрд░ рдирдП рд╕реНрдЯреИрдХ рд╕реЗ рдирдП рд░рд╛рдЬреНрдп рдХреЛ рд▓реЛрдб рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред

 procedure SwitchContext; asm //   SwitchContext   ECX   //     TGeneratorContext pushfd //  EFLAGS push EBX //    push EBP //  EAX,ECX,EDX  //  ,     //  push ESI //     . push EDI // //    : //      SP   xchg ESP, dword ptr [ECX].TGeneratorContext.&SP //      pop EDI pop ESI pop EBP pop EBX popfd //  EFLAGS // ret end; 


рдЖрдкрдХреЛ рдИрдЖрдИрдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд░рд┐рдЯ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж (рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рдбреЗрд▓реНрдлреА рдЕрд╕реЗрдВрдмрд▓рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдореМрдЬреВрдж рд╣реИ), рдкреНрд░реЛрд╕реЗрд╕рд░ рдЙрд╕ рдкрддреЗ рдкрд░ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ рдЬреЛ рдПрдВрдЯрд░ рдФрд░ рд▓реАрд╡ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди рд╕реНрдЯреИрдХ рдкрд░ рд╕рд╣реЗрдЬрд╛ рдЧрдпрд╛ рдерд╛ред

рдпрд╣ Enter рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 procedure TGeneratorContext.Enter( Input: NativeUInt ); asm mov ECX, EAX // Self,   TGeneratorContext mov EAX, EDX // Input,  EAX     jmp SwitchContext //   end; 


рдФрд░ рдЗрд╕рд▓рд┐рдП рдЫреБрдЯреНрдЯреА:

 procedure TGeneratorContext.Leave; asm mov ECX, EAX // Self,   TGeneratorContext jmp SwitchContext end; 


рдЬрдирд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдкрддрд╛ рд╕рдм рдХреБрдЫ рдХреЗ рдиреАрдЪреЗ рд╕реНрдЯреИрдХ рдкрд░ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдордЬрдмреВрд░ рдХрд░рддреЗ рд╣реБрдП, рд░рд┐рдЯ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдкрд░, рдкреАрдврд╝реА рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рд╡рд╛рдкрд╕ рдЖрдиреЗ рдХреЗ рд▓рд┐рдПред

 procedure TGeneratorContext.Return; asm pop ECX //    Self,   TGeneratorContext mov [ECX].TGeneratorBase.FFinished, 1 //  Finished := True lea ECX, [ECX].TGeneratorBase.Context //    Context. jmp SwitchContext //     end; 


рдЬреЛ рдХреБрдЫ рднреА рд░рд╣рддрд╛ рд╣реИ рд╡рд╣ рдПрдХ рдЫреЛрдЯрд╛ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдзреНрд╡рдЬ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд╛ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ:

 function GetFlags: NativeInt; asm pushfd pop EAX end; 


рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ рд╡рд┐рдВрдбреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ WriteLn рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдХреНрд░реАрди рдкрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдкреВрд░реНрдг рдореЙрдбреНрдпреВрд▓ рдХреЛрдб (X86 / X64 рдХреЛрдбрд╛рдВрддрд░рдХ рд╕рд╣рд┐рдд)
 unit DCa.Generators; interface uses Winapi.Windows; const MinStackSize = 8 * 16384; type TNativeUIntArray = array [0 .. 65535] of NativeUInt; PNativeUIntArray = ^TNativeUIntArray; TGeneratorWithParam<ParamT, ResultT> = class; TGeneratorFunction<ParamT, ResultT> = procedure( Generator: TGeneratorWithParam<ParamT, ResultT> ); PGeneratorContext = ^TGeneratorContext; TGeneratorContext = packed record public SP: NativeUInt; Stack: PNativeUIntArray; StackLen: NativeUInt; Generator: TObject; Active: Boolean; procedure Enter( Input: NativeUInt = 0 ); procedure Leave; procedure Return; end; TGeneratorBase = class protected Context: TGeneratorContext; FFinished: Boolean; end; TGeneratorWithParam<ParamT, ResultT> = class( TGeneratorBase ) protected FFunc: TGeneratorFunction<ParamT, ResultT>; FValue: ResultT; FParam: ParamT; public procedure Stop; function Yield( const Value: ResultT ): Boolean; public function GetCurrent: ResultT; function MoveNext: Boolean; property Current: ResultT read GetCurrent; function GetEnumerator: TGeneratorWithParam<ParamT, ResultT>; constructor Create( Func: TGeneratorFunction<ParamT, ResultT>; const Param: ParamT ); overload; constructor Create( Func: TGeneratorFunction<ParamT, ResultT> ); overload; destructor Destroy; override; property Param: ParamT read FParam; property Value: ResultT read FValue; end; TGenerator<T> = class( TGeneratorWithParam<T, T> ); procedure Fibonacci( Generator: TGeneratorWithParam<UInt64, UInt64> ); function GetFlags: NativeInt; implementation procedure Fibonacci( Generator: TGeneratorWithParam<UInt64, UInt64> ); var V1, V2, V: UInt64; begin WriteLn( 'Fib Enter' ); V1 := 1; V2 := 1; V := V1 + V2; while Generator.Yield( V ) and ( V >= V2 ) do begin V1 := V2; V2 := V; V := V1 + V2; end; WriteLn( 'Fib Exit' ); end; function GetFlags: NativeInt; asm {$IFDEF CPUX86} pushfd pop EAX {$ELSE} pushfq pop RAX {$ENDIF} end; constructor TGeneratorWithParam<ParamT, ResultT>.Create( Func: TGeneratorFunction<ParamT, ResultT>; const Param: ParamT ); begin FFunc := Func; FParam := Param; Context.Generator := Self; Context.Stack := VirtualAlloc( nil, MinStackSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE ); Context.StackLen := MinStackSize div SizeOf( NativeUInt ); {$IFDEF DEBUG} FillChar( Context.Stack^, Context.StackLen * SizeOf( NativeUInt ), $DD ); {$ENDIF} Context.SP := NativeUInt( @Context.Stack^[Context.StackLen - 8 {$IFDEF CPUX64} - 6 {$ENDIF}] ); Context.Stack^[Context.StackLen - 4] := GetFlags; Pointer( Context.Stack^[Context.StackLen - 3] ) := @Func; Pointer( Context.Stack^[Context.StackLen - 2] ) := @TGeneratorContext.Return; Pointer( Context.Stack^[Context.StackLen - 1] ) := Self; end; constructor TGeneratorWithParam<ParamT, ResultT>.Create( Func: TGeneratorFunction<ParamT, ResultT> ); begin Create( Func, Default ( ParamT ) ); end; destructor TGeneratorWithParam<ParamT, ResultT>.Destroy; begin if not FFinished then Stop; inherited; VirtualFree( Context.Stack, 0, MEM_RELEASE ); end; function TGeneratorWithParam<ParamT, ResultT>.GetCurrent: ResultT; begin Result := Value; end; function TGeneratorWithParam<ParamT, ResultT>.GetEnumerator: TGeneratorWithParam<ParamT, ResultT>; begin Result := Self; end; function TGeneratorWithParam<ParamT, ResultT>.MoveNext: Boolean; begin if not Context.Active then begin Context.Active := True; Context.Enter( NativeUInt( Self ) ); end else begin Context.Enter( Ord( True ) ); end; Result := not FFinished; end; procedure TGeneratorWithParam<ParamT, ResultT>.Stop; begin FFinished := True; if Context.Active then Context.Enter( Ord( False ) ); end; function TGeneratorWithParam<ParamT, ResultT>.Yield( const Value: ResultT ): Boolean; begin FValue := Value; Context.Leave; Result := not FFinished; end; { TGeneratorContext } procedure SwitchContext; asm {$IFDEF CPUX86} pushfd //EFLAGS push EBX push EBP push ESI push EDI // xchg ESP, dword ptr [ECX].TGeneratorContext.&SP // pop EDI pop ESI pop EBP pop EBX popfd //EFLAGS {$ELSE} pushfq //EFLAGS push RBX push RBP push RSI push RDI push R10 push R11 push R12 push R13 push R14 push R15 // xchg RSP, qword ptr [RDX].TGeneratorContext.&SP // pop R15 pop R14 pop R13 pop R12 pop R11 pop R10 pop RDI pop RSI pop RBP pop RBX popfq //EFLAGS {$ENDIF} end; procedure TGeneratorContext.Enter( Input: NativeUInt ); asm {$IFDEF CPUX86} mov ECX, EAX mov EAX, EDX jmp SwitchContext {$ELSE} mov RAX, RDX mov RDX, RCX mov RCX, RAX jmp SwitchContext {$ENDIF} end; procedure TGeneratorContext.Leave; asm {$IFDEF CPUX86} mov ECX, EAX jmp SwitchContext {$ELSE} mov RDX, RCX jmp SwitchContext {$ENDIF} end; procedure TGeneratorContext.Return; asm {$IFDEF CPUX86} pop ECX mov [ECX].TGeneratorBase.FFinished, 1 lea ECX, [ECX].TGeneratorBase.Context jmp SwitchContext {$ELSE} pop RDX mov [RDX].TGeneratorBase.FFinished, 1 lea RDX, [RDX].TGeneratorBase.Context jmp SwitchContext {$ENDIF} end; initialization finalization end. 

Source: https://habr.com/ru/post/In157777/


All Articles