refactor(ivy): move bindingIndex from LView to LFrame (#33235)

`bindingIndex` stores the current location of the bindings in the
template function. Because it used to be stored in `LView` that `LView`
was not reentrant. This could happen if a binding was a getter and had
a side-effect of calling `detectChanges()`.

By moving the `bindingIndex` to `LFrame` where all of the global state
is kept in reentrant way we correct the issue.

PR Close #33235
This commit is contained in:
Miško Hevery
2019-10-11 12:43:32 -07:00
committed by Andrew Kushnir
parent c61f413477
commit e16f75db56
22 changed files with 204 additions and 138 deletions

View File

@ -32,20 +32,19 @@ export const PARENT = 3;
export const NEXT = 4;
export const QUERIES = 5;
export const T_HOST = 6;
export const BINDING_INDEX = 7;
export const CLEANUP = 8;
export const CONTEXT = 9;
export const INJECTOR = 10;
export const RENDERER_FACTORY = 11;
export const RENDERER = 12;
export const SANITIZER = 13;
export const CHILD_HEAD = 14;
export const CHILD_TAIL = 15;
export const DECLARATION_VIEW = 16;
export const DECLARATION_LCONTAINER = 17;
export const PREORDER_HOOK_FLAGS = 18;
export const CLEANUP = 7;
export const CONTEXT = 8;
export const INJECTOR = 9;
export const RENDERER_FACTORY = 10;
export const RENDERER = 11;
export const SANITIZER = 12;
export const CHILD_HEAD = 13;
export const CHILD_TAIL = 14;
export const DECLARATION_VIEW = 15;
export const DECLARATION_LCONTAINER = 16;
export const PREORDER_HOOK_FLAGS = 17;
/** Size of LView's header. Necessary to adjust for it when setting slots. */
export const HEADER_OFFSET = 19;
export const HEADER_OFFSET = 18;
// This interface replaces the real LView interface if it is an arg or a
@ -120,15 +119,6 @@ export interface LView extends Array<any> {
*/
[T_HOST]: TViewNode|TElementNode|null;
/**
* The binding index we should access next.
*
* This is stored so that bindings can continue where they left off
* if a view is left midway through processing bindings (e.g. if there is
* a setter that creates an embedded view, like in ngIf).
*/
[BINDING_INDEX]: number;
/**
* When a view is destroyed, listeners need to be released and outputs need to be
* unsubscribed. This context array stores both listener functions wrapped with
@ -381,6 +371,8 @@ export interface TView {
* starts to store bindings only. Saving this value ensures that we
* will begin reading bindings at the correct point in the array when
* we are in update mode.
*
* -1 means that it has not been initialized.
*/
bindingStartIndex: number;