Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Продумать схему реализации замыканий #6

Closed
impworks opened this issue Sep 27, 2012 · 4 comments
Closed
Assignees
Labels
Milestone

Comments

@impworks
Copy link
Owner

Нужно подумать на тему того, как лучше реализовать замыкания. Пока видится два варианта:

  1. Иметь специальный класс, который перестраивает дерево, заменяя обращения к локальной переменной на обращения к полю объекта специального класса.
  2. Иметь специальный класс, который обходит блок кода и помечает переменные как замкнутые, а в коде обращения к переменной будет прописано специальное условие, проверяющее этот флаг.

Первый более общий и более правильный - иметь гибкие механизмы перестраивания дерева кода открыло бы огромные возможности для всяких штук типа yield return или async, второй же вариант проще, хотя класс, отвечающий за обращение к переменным сильно замусорится.

@ghost ghost assigned impworks Sep 27, 2012
@ForNeVeR
Copy link
Collaborator

ForNeVeR commented Oct 9, 2012

Второй вариант выглядит громоздким и костыльным. Я совершенно уверен, что первый значительно лучше - пусть и немного сложнее.

@impworks
Copy link
Owner Author

А мне второй вариант кажется более простым и менее бажным. Там подмена переменной на поле будет производиться в двух местах (get \ set) на уровне IL-кода, и мы ничего не заметим. А в случае с первым есть как минимум шесть различных мест, представленных разными нодами:

a
a.fiield
a[index]
// и еще 3 соответствующих им lvalue

Возможно, есть и другие, которые я навскидку не вспомнил.

@impworks
Copy link
Owner Author

impworks commented Jan 3, 2013

В общем замыкания реализуются следующим образом:

  1. У каждой области видимости создается Scope, хранящий информацию о видимых локальных переменных.
  2. Метод Prepare предварительно обходит каждую из функций, включая главную, в поисках лямбда-выражений.
  3. Если хотя бы одно найдено, создается специальный тип с нечитаемым именем, который будет хранить замыкания. Самая лямбда-функция связывается с MethodBuilder для одного из методов этого типа.
  4. Тело лямбды обходится в поисках локальных переменных из внешней области видимости.
  5. Под каждую такую переменную создается поле в closure-классе, и она помечается как замкнутая в своем Scope.

@impworks
Copy link
Owner Author

impworks commented Feb 7, 2013

Схема придумана и реализована в виде следующих механизмов:

  1. Связки методов ProcessClosures и GetChildNodes в классе NodeBase.
  2. Класса Scope и его возможности сцепляться с родительской областью видимости.

@impworks impworks closed this as completed Feb 7, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants