Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 09:46
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, merk, Вы писали:


AVK>>>Все на самом деле совсем не так, как ты тут рассказываешь.

M>>СОВСЕМ не как???
M>>можно поразвернутей?

AVK>Можно. Компилятор шарпа генерирует FSM, который прекрасно работает без ломания стека и прочих низкоуровневых хаков.

видимо нужно иметь особую проницательность, чтобы заметить, что то что я написал — запуск фцнкции в прежнем контексте...и есть ваша fsm... причием если я написал метод реализации, вы написали просто название того, что должно быть реализовано.
да уш.

15.07.08 16:11: Ветка выделена из темы Написание компилятора C#
Автор: nikov
Дата: 13.07.08
— AndrewVK
Re: Реализация итераторов в компиляторе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.07.08 09:48
Оценка:
Здравствуйте, merk, Вы писали:

M>видимо нужно иметь особую проницательность, чтобы заметить, что то что я написал — запуск фцнкции в прежнем контексте...и есть ваша fsm...


Правда что ли? Понимаешь какая закавыка — нет там никаких адресов. Совсем нет.

M> причием если я написал метод реализации, вы написали просто название того, что должно быть реализовано.

M>да уш.

Угу. Учите матчасть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[2]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 10:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, merk, Вы писали:


M>>видимо нужно иметь особую проницательность, чтобы заметить, что то что я написал — запуск фцнкции в прежнем контексте...и есть ваша fsm...


AVK>Правда что ли? Понимаешь какая закавыка — нет там никаких адресов. Совсем нет.

вообще нет? и команды представляют собой неупорядоченный набор кодов? и нет команд переходов? и нету меток? и нет адресов процедур(а есть тока имя или слот какой-нить?) и нет команды возврата?
вся эта кухня основана на понятии адреса, как бы вы его не назвали.
вы только что заявили, что сия выч.среда несводима к машине неймана.
учита матчасть.
Re[3]: Реализация итераторов в компиляторе
От: WolfHound  
Дата: 14.07.08 10:46
Оценка:
Здравствуйте, merk, Вы писали:

AVK>>Правда что ли? Понимаешь какая закавыка — нет там никаких адресов. Совсем нет.

M>вообще нет? и команды представляют собой неупорядоченный набор кодов? и нет команд переходов? и нету меток? и нет адресов процедур(а есть тока имя или слот какой-нить?) и нет команды возврата?
Он видимо считает что между switch'ем и адресами в данном случае есть принципиальная разница.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Реализация итераторов в компиляторе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.07.08 10:50
Оценка: +2
Здравствуйте, merk, Вы писали:

AVK>>Правда что ли? Понимаешь какая закавыка — нет там никаких адресов. Совсем нет.

M>вообще нет?

Вообще.

M> и команды представляют собой неупорядоченный набор кодов?


С какой стати?

M> и нет команд переходов?


Безусловных нету, условные конечно есть.

M> и нету меток?


Нет

M> и нет адресов процедур


Нет

M>(а есть тока имя или слот какой-нить?)


Да

M> и нет команды возврата?


Откуда? Из метода? Есть.

M>вся эта кухня основана на понятии адреса, как бы вы его не назвали.


К компилятору C# эта кухня отношения не имеет. Все разборки с адресами делает JIT, и это выходит за рамки данного топика.

Похоже, твоя лень не позовляет тебе провести простой эксперимент.
Код на шарпе:
static IEnumerable<T> Test1<T>(this IEnumerable<T> src)
{
    foreach (var item in src)
        yield return item;
}

Преобразуется в такой код (эквивалент на C#):
[CompilerGenerated]
private sealed class <Test1>d__0<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable
{
    // Fields
    private int <>1__state;
    private T <>2__current;
    public IEnumerable<T> <>3__src;
    public IEnumerator<T> <>7__wrap2;
    private int <>l__initialThreadId;
    public T <item>5__1;
    public IEnumerable<T> src;

    // Methods
    [DebuggerHidden]
    public <Test1>d__0(int <>1__state)
    {
        this.<>1__state = <>1__state;
        this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
    }

    private void <>m__Finally3()
    {
        this.<>1__state = -1;
        if (this.<>7__wrap2 != null)
        {
            this.<>7__wrap2.Dispose();
        }
    }

    private bool MoveNext()
    {
        try
        {
            switch (this.<>1__state)
            {
                case 0:
                    this.<>1__state = -1;
                    this.<>7__wrap2 = this.src.GetEnumerator();
                    this.<>1__state = 1;
                    while (this.<>7__wrap2.MoveNext())
                    {
                        this.<item>5__1 = this.<>7__wrap2.Current;
                        this.<>2__current = this.<item>5__1;
                        this.<>1__state = 2;
                        return true;
                    Label_006C:
                        this.<>1__state = 1;
                    }
                    this.<>m__Finally3();
                    break;

                case 2:
                    goto Label_006C;
            }
            return false;
        }
        fault
        {
            this.System.IDisposable.Dispose();
        }
    }

    [DebuggerHidden]
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        Class1.<Test1>d__0<T> d__;
        if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
        {
            this.<>1__state = 0;
            d__ = (Class1.<Test1>d__0<T>) this;
        }
        else
        {
            d__ = new Class1.<Test1>d__0<T>(0);
        }
        d__.src = this.<>3__src;
        return d__;
    }

    [DebuggerHidden]
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.System.Collections.Generic.IEnumerable<T>.GetEnumerator();
    }

    [DebuggerHidden]
    void IEnumerator.Reset()
    {
        throw new NotSupportedException();
    }

    void IDisposable.Dispose()
    {
        switch (this.<>1__state)
        {
            case 1:
            case 2:
                break;

            default:
                break;
                try
                {
                }
                finally
                {
                    this.<>m__Finally3();
                }
                break;
        }
    }

    // Properties
    T IEnumerator<T>.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }

    object IEnumerator.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }
}

...

static IEnumerable<T> Test1<T>(this IEnumerable<T> src)
{
    <Test1>d__0<T> d__ = new <Test1>d__0<T>(-2);
    d__.<>3__src = src;
    return d__;
}


Код
static IEnumerable<T> Test2<T>(this IEnumerable<T> src, T itemTemplate)
{
    foreach (var item in src)
    {
        if (item == null)
            continue;
        if (ReferenceEquals(item, itemTemplate))
            yield break;
        yield return item;
    }
}


преобразуется в
[CompilerGenerated]
private sealed class <Test2>d__6<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable
{
    // Fields
    private int <>1__state;
    private T <>2__current;
    public T <>3__itemTemplate;
    public IEnumerable<T> <>3__src;
    public IEnumerator<T> <>7__wrap8;
    private int <>l__initialThreadId;
    public T <item>5__7;
    public T itemTemplate;
    public IEnumerable<T> src;

    // Methods
    [DebuggerHidden]
    public <Test2>d__6(int <>1__state)
    {
        this.<>1__state = <>1__state;
        this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
    }

    private void <>m__Finally9()
    {
        this.<>1__state = -1;
        if (this.<>7__wrap8 != null)
        {
            this.<>7__wrap8.Dispose();
        }
    }

    private bool MoveNext()
    {
        bool CS$1$0000;
        try
        {
            switch (this.<>1__state)
            {
                case 0:
                    break;

                case 2:
                    goto Label_00B5;

                default:
                    goto Label_00D7;
            }
            this.<>1__state = -1;
            this.<>7__wrap8 = this.src.GetEnumerator();
            this.<>1__state = 1;
            while (this.<>7__wrap8.MoveNext())
            {
                this.<item>5__7 = this.<>7__wrap8.Current;
                if (this.<item>5__7 == null)
                {
                    continue;
                }
                if (object.ReferenceEquals(this.<item>5__7, this.itemTemplate))
                {
                    this.System.IDisposable.Dispose();
                    goto Label_00D7;
                }
                this.<>2__current = this.<item>5__7;
                this.<>1__state = 2;
                return true;
            Label_00B5:
                this.<>1__state = 1;
            }
            this.<>m__Finally9();
        Label_00D7:
            CS$1$0000 = false;
        }
        fault
        {
            this.System.IDisposable.Dispose();
        }
        return CS$1$0000;
    }

    [DebuggerHidden]
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        Class1.<Test2>d__6<T> d__;
        if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
        {
            this.<>1__state = 0;
            d__ = (Class1.<Test2>d__6<T>) this;
        }
        else
        {
            d__ = new Class1.<Test2>d__6<T>(0);
        }
        d__.src = this.<>3__src;
        d__.itemTemplate = this.<>3__itemTemplate;
        return d__;
    }

    [DebuggerHidden]
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.System.Collections.Generic.IEnumerable<T>.GetEnumerator();
    }

    [DebuggerHidden]
    void IEnumerator.Reset()
    {
        throw new NotSupportedException();
    }

    void IDisposable.Dispose()
    {
        switch (this.<>1__state)
        {
            case 1:
            case 2:
                break;

            default:
                break;
                try
                {
                }
                finally
                {
                    this.<>m__Finally9();
                }
                break;
        }
    }

    // Properties
    T IEnumerator<T>.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }

    object IEnumerator.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }
}

...

static IEnumerable<T> Test2<T>(this IEnumerable<T> src, T itemTemplate)
{
    <Test2>d__6<T> d__ = new <Test2>d__6<T>(-2);
    d__.<>3__src = src;
    d__.<>3__itemTemplate = itemTemplate;
    return d__;
}


А теперь исходный вопрос — ты все еще уверен, что напишешь работающий прототип компилятора шарпа за месяц?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[4]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 11:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, merk, Вы писали:


AVK>>>Правда что ли? Понимаешь какая закавыка — нет там никаких адресов. Совсем нет.

M>>вообще нет?

AVK>Вообще.


M>> и команды представляют собой неупорядоченный набор кодов?


AVK>С какой стати?


M>> и нет команд переходов?


AVK>Безусловных нету, условные конечно есть.


M>> и нету меток?


AVK>Нет


вот это в вашем коде — что оно?
AVK> case 2:
AVK> goto Label_00B5;

AVK> default:

AVK> goto Label_00D7;



M>> и нет адресов процедур


AVK>Нет


M>>(а есть тока имя или слот какой-нить?)


AVK>Да


что лежит в слоте?

M>>вся эта кухня основана на понятии адреса, как бы вы его не назвали.


AVK>К компилятору C# эта кухня отношения не имеет. Все разборки с адресами делает JIT, и это выходит за рамки данного топика.


наличие меток и goto целиком и полностью решает вопрос с адресами.

AVK>А теперь исходный вопрос — ты все еще уверен, что напишешь работающий прототип компилятора шарпа за месяц?


вы еще скажите что я вам должен 800 рублей.
если доказываете нечто делайте это корректно. никакой речи о прототипе за месяц с генерацией "такого вот" кода я не вел. и не мог вести.
Re[5]: Реализация итераторов в компиляторе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.07.08 11:21
Оценка:
Здравствуйте, merk, Вы писали:

M>вот это в вашем коде — что оно?


Это результат декомпиляции. В IL никаких меток нет.

AVK>>Да


M>что лежит в слоте?


Курите документацию, раздел метаданные сборки.

AVK>>А теперь исходный вопрос — ты все еще уверен, что напишешь работающий прототип компилятора шарпа за месяц?


M>вы еще скажите что я вам должен 800 рублей.


Слив засчитан.

M>если доказываете нечто делайте это корректно. никакой речи о прототипе за месяц с генерацией "такого вот" кода я не вел.


ну это месяц-два, если вообще нет грамматики этого сишарпа. а она уж наверняка есть.

... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[6]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 11:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, merk, Вы писали:


M>>вот это в вашем коде — что оно?


AVK>Это результат декомпиляции. В IL никаких меток нет.


AVK>>>Да


M>>что лежит в слоте?


AVK>Курите документацию, раздел метаданные сборки.


AVK>>>А теперь исходный вопрос — ты все еще уверен, что напишешь работающий прототип компилятора шарпа за месяц?


M>>вы еще скажите что я вам должен 800 рублей.


AVK>Слив засчитан.


M>>если доказываете нечто делайте это корректно. никакой речи о прототипе за месяц с генерацией "такого вот" кода я не вел.


AVK>

ну это месяц-два, если вообще нет грамматики этого сишарпа. а она уж наверняка есть.


ухватывайте контекст. не занимайтесь детской ерундой. разговор был о вашем предположении о прототипе
что мол —
это нечто, что генерит невразумительные сообщения об ошибках, сгенеренные кодом от генератора парсеров и "ПРИБЛИЗИТЕЛЬНО" выполняет какие-то ваши собственные тесты(без указания какие именно). и очень сомнительно что в набор тестов вы включили бы yield. причем работающий корректно, ибо он вас явно сильно испугал
Re[6]: Реализация итераторов в компиляторе
От: WolfHound  
Дата: 14.07.08 11:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

M>>вот это в вашем коде — что оно?

AVK>Это результат декомпиляции. В IL никаких меток нет.
А с опкодом br что делать будем?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 12:05
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, AndrewVK, Вы писали:


M>>>вот это в вашем коде — что оно?

AVK>>Это результат декомпиляции. В IL никаких меток нет.
WH>А с опкодом br что делать будем?
надо забыть.
товарищ вообще считает, что goto label в псевдокоде...это нечто неотображаемое на мсил. причем goto он получил отображением из самого мсила через декомпиляцию?
вот такое вот отображение множеств без наличия обратного...
прям какое то шифрование, елки палки!
Re[7]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 12:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, AndrewVK, Вы писали:


M>>>вот это в вашем коде — что оно?

AVK>>Это результат декомпиляции. В IL никаких меток нет.
WH>А с опкодом br что делать будем?

в машине для нормального императивного языка вообще без jump и label или их прямых заменителей не обойтись
иначе виснет реализация циклов, switch, break, а также return через прыжок в начало эпилога функции. это как минимум.
Re[7]: Реализация итераторов в компиляторе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.07.08 12:54
Оценка:
Здравствуйте, merk, Вы писали:

M>ухватывайте контекст. не занимайтесь детской ерундой. разговор был о вашем предположении о прототипе


никакой речи о прототипе за месяц с генерацией "такого вот" кода я не вел.

... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[7]: Реализация итераторов в компиляторе
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.07.08 12:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

AVK>>Это результат декомпиляции. В IL никаких меток нет.

WH>А с опкодом br что делать будем?

И где там метка? Там просто смещение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[8]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 12:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, WolfHound, Вы писали:


AVK>>>Это результат декомпиляции. В IL никаких меток нет.

WH>>А с опкодом br что делать будем?

AVK>И где там метка? Там просто смещение.

где там в лоб? там же по лбу!
Re[8]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 13:02
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, WolfHound, Вы писали:


AVK>>>Это результат декомпиляции. В IL никаких меток нет.

WH>>А с опкодом br что делать будем?

AVK>И где там метка? Там просто смещение.

адресация бывает не тока абсолютной, но и относительной. и от этого не перестает быть адресацией.
Re[9]: Реализация итераторов в компиляторе
От: nikov США http://www.linkedin.com/in/nikov
Дата: 14.07.08 13:40
Оценка: +1
Здравствуйте, merk, Вы писали:

AVK>>И где там метка? Там просто смещение.

M>адресация бывает не тока абсолютной, но и относительной. и от этого не перестает быть адресацией.

Разница существенная. Смещение в IL нельзя никуда запомнить, чтобы потом перейти на запомненное значение. Смещение для команд ветвления должно быть прописано в самом IL — это необходимо для верификации.
Re[10]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 14:21
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, merk, Вы писали:


AVK>>>И где там метка? Там просто смещение.

M>>адресация бывает не тока абсолютной, но и относительной. и от этого не перестает быть адресацией.

N>Разница существенная. Смещение в IL нельзя никуда запомнить, чтобы потом перейти на запомненное значение. Смещение для команд ветвления должно быть прописано в самом IL — это необходимо для верификации.


ну щас посмотрю этот ваш IL.
для "моего" случая с восстановлением контекста "запоминать смещение" не нужно.
нужно просто поставить нумерованные метки в MSIL, в местах после оператора выскакивания из контекста — тут это

yield return ...

после каждого такого оператора стоит метка. запоминается номер метки, а не адрес выхода.
при повторном входе эмулируется
switch (label_num)
{
label0:.... break;
label1:.....break;
...
}
таким образом мы возобновляем исполнение.
неужель трудно догадаться?
Re[11]: Реализация итераторов в компиляторе
От: merk Россия  
Дата: 14.07.08 14:30
Оценка:
Здравствуйте, merk, Вы писали:
M>после каждого такого оператора стоит метка. запоминается номер метки, а не адрес выхода.
M>при повторном входе эмулируется
M>switch (label_num)
M>{
M> label0:.... break;
M> label1:.....break;
M>...
M>}
M>таким образом мы возобновляем исполнение.
M>неужель трудно догадаться?

чтоб не придирались, это не switch оператор в чистом виде, а вариантый goto.
разница в том, что можно перейти в любую точку кода, на метку.
такая приблуда в мсиле может быть реализована?
Re[12]: Реализация итераторов в компиляторе
От: WolfHound  
Дата: 14.07.08 14:37
Оценка:
Здравствуйте, merk, Вы писали:

M>чтоб не придирались, это не switch оператор в чистом виде, а вариантый goto.

M>разница в том, что можно перейти в любую точку кода, на метку.
M>такая приблуда в мсиле может быть реализована?
Да.
Примерно так:
switch (label_num)
{
case label_num0: goto label0;
case label_num1: goto label1;
...
}
...
label0:
...
label1:
...
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Реализация итераторов в компиляторе
От: WolfHound  
Дата: 14.07.08 14:37
Оценка:
Здравствуйте, nikov, Вы писали:

N>Разница существенная. Смещение в IL нельзя никуда запомнить, чтобы потом перейти на запомненное значение. Смещение для команд ветвления должно быть прописано в самом IL — это необходимо для верификации.

Ну и?
Особенно учитывая что это эмулируется простейшим паттерном...
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.