Property | Type | Description | |
---|---|---|---|
BuildStateMachine | |||
CompileIterator | |||
CreateDisposeMethod | void | ||
CreateGetEnumeratorMethodGeneric | void | ||
CreateGetEnumeratorMethodNonGeneric | void | ||
CreateIteratorClosure | |||
CreateIteratorClosureConstructor | void | ||
CreateIteratorClosureFields | void | ||
CreateIteratorClosureMethods | void | ||
CreateIteratorClosureProperties | void | ||
CreateMoveNextMethod | void | ||
CreateNewIteratorMethodBody | |||
CreateResetMethod | void | ||
GetBodyOfGenericGetEnumerator | |||
GetClosureEnumeratorTypeArguments | IEnumerable |
||
GetClosureTypeReferenceFromIterator | ITypeReference | ||
GetFieldReference | IFieldReference | ||
GetLocalOrParameterType | ITypeReference | ||
GetMethodReference | IMethodReference | ||
IteratorClosureGenerator | Microsoft.Cci.MutableCodeModel | ||
TranslateIteratorMethodBodyToMoveNextBody | IBlockStatement |
Method | Description | |
---|---|---|
BuildStateMachine ( |
Build the state machine. We start from state 0. For each yield return, we assign a unique state, which we call continueing state. For a yield return assigned with state x, we move the state machine from the previous state to x. Whenever we see a yield break, we transit the state to -1. When we return from state x, we jump to a label that is inserted right after the previous yield return (that is assigned with state x).
|
|
CompileIterator ( IBlockStatement block ) : |
Compile the method body, represented by block. It creates the closure class and all its members and creates a new body for the iterator method.
|
|
CreateDisposeMethod ( |
DisposeMethod method. Currently the method body does nothing.
|
|
CreateGetEnumeratorMethodGeneric ( |
Create the generic version of the GetEnumerator for the iterator closure class.
|
|
CreateGetEnumeratorMethodNonGeneric ( |
Create the non-generic version of GetEnumerator and add it to the member list of iterator closure class.
|
|
CreateIteratorClosure ( |
Create the iterator closure class and add it to the private helper types list.
|
|
CreateIteratorClosureConstructor ( |
Create the constuctor of the iterator class. The pseudo-code is: Ctor(int state) { object.Ctor(); this.state = state; this.threadid = Thread.CurrentThread.ManagedThreadId; }
|
|
CreateIteratorClosureFields ( |
Create fields for the closure class, which include fields for captured variables and fields for maintaining the state machine.
|
|
CreateIteratorClosureMethods ( |
Create the methods of the iterator closure.
|
|
CreateIteratorClosureProperties ( |
Create two properties: object Current and T Current as the closure class implements both the generic and non-generic version of ienumerator. Current Implementation generates getters, but not the property.
|
|
CreateMoveNextMethod ( |
Create the MoveNext method. This method sets up metadata and calls TranslateIteratorMethodBodyToMoveNextBody to compile the body.
|
|
CreateNewIteratorMethodBody ( |
Create the new body of the iterator method. Pseudo code: iteratorClosureLocal = new Closure(0); iteratorClosureLocal.field = parameter; // for each parameter including this. return iteratorClosureLocal; |
|
CreateResetMethod ( |
Create the Reset method. Like in CSC, this method contains nothing.
|
|
GetBodyOfGenericGetEnumerator ( |
Create the body of the generic version of GetEnumerator for the iterator closure class. The body's pseudo code. { if (Thread.CurrentThread.ManagedThreadId == this.l_initialThreadId AND this.state == -2) { this.state = 0; return this; } else { return a new copy of the iterator instance with state being zero. } }
|
|
GetClosureEnumeratorTypeArguments ( ITypeReference methodTypeReference ) : IEnumerable |
Find the type argument of the IEnumerable generic type implemented by a methodTypeReference, or System.Object if methodTypeReference implements the non-generic IEnumerable.
|
|
GetClosureTypeReferenceFromIterator ( |
Instantiate the closure class using the generic method parameters of the iterator method, if any.
|
|
GetFieldReference ( |
Instantiate a closure class field using the generic method parameters of the iterator method, if any. Code Review: cache the result of GetClosureTypeReferenceFromIterator.
|
|
GetLocalOrParameterType ( object obj ) : ITypeReference |
Return the type of the parameter (excluding this) or local variable represented by obj.
|
|
GetMethodReference ( |
Instantiate a closure class method using the generic method parameters of the iterator method, if any.
|
|
IteratorClosureGenerator ( IMethodDefinition method, List |
Create closure class, including all its members for an iterator method and rewrite the body of the iterator method. Specifically, we 1) creates a closure class that implements: IEnumerator, generic and nongeneric versions, IEnumerable, generic and nongeneric versions, and IDisposable. The generic versions of IEnumerator and IEnumerator is instantiated by a type T that is used to instantiate the return type of the iterator method. The members of the closure class include: 1.1) fields corresponding to every parameter and local variables. 1.2) fields that manages the state machine: __current and __state, and a currentThreadId field. 1.3) a constructor that takes one int argument. 1.4) methods that are required by the interfaces of the closure class: MoveNext, Reset, GetEnumerator, Current getter, and DisposeMethod. 2) creates the new body of the iterator method: which returns a local variable that holds a new object of the closure class, with the fields of the closure class that correspond to the parameters (including the self parameter if applicable) initialized. 3) transforms the body, which should now not contain any annonymous delegates, into the body of the MoveNext method of the closure class. This includes: 3.1) every local/parameter reference -> this.field reference 3.2) every yield return or yield break -> assignment to current and return true or false, respectively. 3.3) a switch statement for the state machine, with state values corresponds to each yield return/yield break. 3.4) try statement for foreach if the iterator method body uses one. 4) If the iterator method has a type parameter, so will the closure class. Make sure in the closure class only the right type parameter is referenced.
|
|
TranslateIteratorMethodBodyToMoveNextBody ( |
Create method body of the MoveNext from a copy of the body of the iterator method. First we substitute the locals/parameters with closure fields, and generic method type parameter of the iterator method with generic type parameters of the closure class (if any). Then, we build the state machine.
|