[nem-bug] [Nemerle 0000694]: Incorrect conversion from Generator method to state machine

feedback at nemerle.org feedback at nemerle.org
Fri Aug 11 19:53:19 CEST 2006


A NOTE has been added to this issue.
======================================================================
<http://nemerle.org/bugs/view.php?id=694> 
======================================================================
Reported By:                mikeluwork
Assigned To:                
======================================================================
Project:                    Nemerle
Issue ID:                   694
Category:                   Compiler
Reproducibility:            always
Severity:                   block
Priority:                   normal
Status:                     new
======================================================================
Date Submitted:             06-28-2006 22:57 CEST
Last Modified:              08-11-2006 19:53 CEST
======================================================================
Summary:                    Incorrect conversion from Generator method  to state
machine
Description: 
The compiler (0.9.3 on .NET fx 2.0) thinks the following code is ok. But
the generated IL code doesn't convert yield statement to a correct state
machine.
The code is a direct translation from an equivalent C# code. Using .net
reflector reveals the error is in this generated method. It seems the loop
is not converted correctly. (C# code in 'Additional Info' field)

public bool MoveNext()
{
      try
      {
            bool flag2;
            if (this._N_state != 1)
            {
                  if (this._N_state != 0)
                  {
                        flag2 = false;
                  }
                  else
                  {
                        this._N_i1245 = 0;
                        while (true)
                        {
                              if (((this._N_i1245 < (0x5f5e100 /
Threads.Threads.NUMTHREADS)) ? 1 : 0) != 1)
                              {
                                    break;
                              }
                              Threads.Threads.x++;
                              this._N_i1245++;
                        }
                        this._N_current = Threads.Threads.x;
                        this._N_state = 1;
                        flag2 = true;
                  }
            }
            else
            {
                  Threads.Threads.active = false;
                  flag2 = false;
            }
            return flag2;
      }
      fault
      {
            this.Dispose();
      }
}

 


---- nemerle code begins ----
using System;
using System.Collections.Generic;
using System.Text;


namespace Threads {
    class Threads {
        static mutable x = 0;
        static mutable active = true;
        static TOTALSWITCHES = 100000000;
        static NUMTHREADS: int = TOTALSWITCHES/100;
        static threads = array (NUMTHREADS + 1): array
[IEnumerator[int]];

// Property version
         looper: IEnumerable[int]{
            get {
                while (true) {
                	++x;
                    yield x;
                    }
                }
            }

// Function version
        static quitter(): IEnumerable[int]  {
            for (mutable i = 0; i < TOTALSWITCHES / NUMTHREADS; i++)
            	++x;
                yield x;
            active = false;
            }

        static scheduler(): void {
            while (active)
                foreach (thread in threads) {
                    _ = thread.MoveNext();
                    }
            }

        static Main(_args: array[string]): void {
            mutable start = DateTime.Now;
            for (mutable i = 0; i < NUMTHREADS; i++) {
                threads[i] = Threads().looper.GetEnumerator();
                }
            threads[NUMTHREADS] = quitter().GetEnumerator();

            Console.WriteLine("C# time to initialize: " + (DateTime.Now -
start).ToString());
            mutable start2 = DateTime.Now;
            scheduler();
            Console.WriteLine("C# time to run:       " + (DateTime.Now -
start2).ToString());
            Console.WriteLine("C# total time:        " + (DateTime.Now -
start).ToString());
            Console.WriteLine("Total Switches: {0}", TOTALSWITCHES);
            Console.WriteLine("Total Threads:  {0}", NUMTHREADS);
            when (x != TOTALSWITCHES + NUMTHREADS + TOTALSWITCHES /
NUMTHREADS)
                Console.WriteLine("Bad checksum: {0}", x);
            }
        }
    }

======================================================================

----------------------------------------------------------------------
 nazgul - 08-11-06 19:53 
----------------------------------------------------------------------
// Function version
        static quitter(): IEnumerable[int] {
            for (mutable i = 0; i < TOTALSWITCHES / NUMTHREADS; i++)
                ++x;
                yield x;
            active = false;
            }

is missing {}, it should be:

// Function version
   static quitter(): IEnumerable[int] {
       for (mutable i = 0; i < TOTALSWITCHES / NUMTHREADS; i++) {
         ++x;
         yield x;
       }
       active = false;
   }

Issue History
Date Modified  Username       Field                    Change              
======================================================================
06-28-06 22:57 mikeluwork     New Issue                                    
07-06-06 21:16 mikeluwork     Issue Monitored: mikeluwork                    
08-11-06 19:53 nazgul         Note Added: 0001412                          
======================================================================




More information about the bugs mailing list