refactor(view): change view to pass all bindings to proto change detector at once

This commit is contained in:
vsavkin 2015-03-11 21:43:22 -07:00
parent 1adb23d222
commit 3273adade5
7 changed files with 93 additions and 83 deletions

View File

@ -7,7 +7,7 @@ export {ExpressionChangedAfterItHasBeenChecked, ChangeDetectionError}
from './src/change_detection/exceptions'; from './src/change_detection/exceptions';
export {ChangeRecord, ChangeDispatcher, ChangeDetector, export {ChangeRecord, ChangeDispatcher, ChangeDetector,
CHECK_ONCE, CHECK_ALWAYS, DETACHED, CHECKED} from './src/change_detection/interfaces'; CHECK_ONCE, CHECK_ALWAYS, DETACHED, CHECKED} from './src/change_detection/interfaces';
export {ProtoChangeDetector, DynamicProtoChangeDetector, JitProtoChangeDetector} export {ProtoChangeDetector, DynamicProtoChangeDetector, JitProtoChangeDetector, BindingRecord}
from './src/change_detection/proto_change_detector'; from './src/change_detection/proto_change_detector';
export {DynamicChangeDetector} export {DynamicChangeDetector}
from './src/change_detection/dynamic_change_detector'; from './src/change_detection/dynamic_change_detector';

View File

@ -45,36 +45,44 @@ import {
export class ProtoChangeDetector { export class ProtoChangeDetector {
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null){} addAst(ast:AST, bindingMemento:any, directiveMemento:any = null){}
instantiate(dispatcher:any):ChangeDetector{ instantiate(dispatcher:any, bindingRecords:List):ChangeDetector{
return null; return null;
} }
} }
export class BindingRecord {
ast:AST;
bindingMemento:any;
directiveMemento:any;
constructor(ast:AST, bindingMemento:any, directiveMemento:any) {
this.ast = ast;
this.bindingMemento = bindingMemento;
this.directiveMemento = directiveMemento;
}
}
export class DynamicProtoChangeDetector extends ProtoChangeDetector { export class DynamicProtoChangeDetector extends ProtoChangeDetector {
_records:List<ProtoRecord>;
_recordBuilder:ProtoRecordBuilder;
_pipeRegistry:PipeRegistry; _pipeRegistry:PipeRegistry;
_records:List<ProtoRecord>;
constructor(pipeRegistry:PipeRegistry) { constructor(pipeRegistry:PipeRegistry) {
super(); super();
this._pipeRegistry = pipeRegistry; this._pipeRegistry = pipeRegistry;
this._records = null;
this._recordBuilder = new ProtoRecordBuilder();
} }
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null) { instantiate(dispatcher:any, bindingRecords:List) {
this._recordBuilder.addAst(ast, bindingMemento, directiveMemento); this._createRecordsIfNecessary(bindingRecords);
}
instantiate(dispatcher:any) {
this._createRecordsIfNecessary();
return new DynamicChangeDetector(dispatcher, this._pipeRegistry, this._records); return new DynamicChangeDetector(dispatcher, this._pipeRegistry, this._records);
} }
_createRecordsIfNecessary() { _createRecordsIfNecessary(bindingRecords:List) {
if (isBlank(this._records)) { if (isBlank(this._records)) {
var records = this._recordBuilder.records; var recordBuilder = new ProtoRecordBuilder();
this._records = coalesce(records); ListWrapper.forEach(bindingRecords, (r) => {
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento);
});
this._records = coalesce(recordBuilder.records);
} }
} }
} }
@ -82,29 +90,27 @@ export class DynamicProtoChangeDetector extends ProtoChangeDetector {
var _jitProtoChangeDetectorClassCounter:number = 0; var _jitProtoChangeDetectorClassCounter:number = 0;
export class JitProtoChangeDetector extends ProtoChangeDetector { export class JitProtoChangeDetector extends ProtoChangeDetector {
_factory:Function; _factory:Function;
_recordBuilder:ProtoRecordBuilder;
_pipeRegistry; _pipeRegistry;
constructor(pipeRegistry) { constructor(pipeRegistry) {
super(); super();
this._pipeRegistry = pipeRegistry; this._pipeRegistry = pipeRegistry;
this._factory = null; this._factory = null;
this._recordBuilder = new ProtoRecordBuilder();
} }
addAst(ast:AST, bindingMemento:any, directiveMemento:any = null) { instantiate(dispatcher:any, bindingRecords:List) {
this._recordBuilder.addAst(ast, bindingMemento, directiveMemento); this._createFactoryIfNecessary(bindingRecords);
}
instantiate(dispatcher:any) {
this._createFactoryIfNecessary();
return this._factory(dispatcher, this._pipeRegistry); return this._factory(dispatcher, this._pipeRegistry);
} }
_createFactoryIfNecessary() { _createFactoryIfNecessary(bindingRecords:List) {
if (isBlank(this._factory)) { if (isBlank(this._factory)) {
var recordBuilder = new ProtoRecordBuilder();
ListWrapper.forEach(bindingRecords, (r) => {
recordBuilder.addAst(r.ast, r.bindingMemento, r.directiveMemento);
});
var c = _jitProtoChangeDetectorClassCounter++; var c = _jitProtoChangeDetectorClassCounter++;
var records = coalesce(this._recordBuilder.records); var records = coalesce(recordBuilder.records);
var typeName = `ChangeDetector${c}`; var typeName = `ChangeDetector${c}`;
this._factory = new ChangeDetectorJITGenerator(typeName, records).generate(); this._factory = new ChangeDetectorJITGenerator(typeName, records).generate();
} }

View File

@ -1,8 +1,8 @@
import {DOM} from 'angular2/src/dom/dom_adapter'; import {DOM} from 'angular2/src/dom/dom_adapter';
import {Promise} from 'angular2/src/facade/async'; import {Promise} from 'angular2/src/facade/async';
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
import {AST, ContextWithVariableBindings, ChangeDispatcher, ProtoChangeDetector, ChangeDetector, ChangeRecord} import {AST, ContextWithVariableBindings, ChangeDispatcher, ProtoChangeDetector, ChangeDetector,
from 'angular2/change_detection'; ChangeRecord, BindingRecord} from 'angular2/change_detection';
import {ProtoElementInjector, ElementInjector, PreBuiltObjects} from './element_injector'; import {ProtoElementInjector, ElementInjector, PreBuiltObjects} from './element_injector';
import {BindingPropagationConfig} from './binding_propagation_config'; import {BindingPropagationConfig} from './binding_propagation_config';
@ -46,10 +46,10 @@ export class View {
context: any; context: any;
contextWithLocals:ContextWithVariableBindings; contextWithLocals:ContextWithVariableBindings;
constructor(proto:ProtoView, nodes:List, protoChangeDetector:ProtoChangeDetector, protoContextLocals:Map) { constructor(proto:ProtoView, nodes:List, protoContextLocals:Map) {
this.proto = proto; this.proto = proto;
this.nodes = nodes; this.nodes = nodes;
this.changeDetector = protoChangeDetector.instantiate(this); this.changeDetector = null;
this.elementInjectors = null; this.elementInjectors = null;
this.rootElementInjectors = null; this.rootElementInjectors = null;
this.textNodes = null; this.textNodes = null;
@ -63,8 +63,9 @@ export class View {
: null; : null;
} }
init(elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List, init(changeDetector:ChangeDetector, elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List,
viewContainers:List, preBuiltObjects:List, componentChildViews:List) { viewContainers:List, preBuiltObjects:List, componentChildViews:List) {
this.changeDetector = changeDetector;
this.elementInjectors = elementInjectors; this.elementInjectors = elementInjectors;
this.rootElementInjectors = rootElementInjectors; this.rootElementInjectors = rootElementInjectors;
this.textNodes = textNodes; this.textNodes = textNodes;
@ -294,12 +295,13 @@ export class ProtoView {
_viewPool: ViewPool; _viewPool: ViewPool;
stylePromises: List<Promise>; stylePromises: List<Promise>;
// List<Map<eventName, handler>>, indexed by binder index // List<Map<eventName, handler>>, indexed by binder index
eventHandlers: List; eventHandlers:List;
bindingRecords:List;
constructor( constructor(
template, template,
protoChangeDetector:ProtoChangeDetector, protoChangeDetector:ProtoChangeDetector,
shadowDomStrategy: ShadowDomStrategy) { shadowDomStrategy:ShadowDomStrategy) {
this.element = template; this.element = template;
this.elementBinders = []; this.elementBinders = [];
this.variableBindings = MapWrapper.create(); this.variableBindings = MapWrapper.create();
@ -315,6 +317,7 @@ export class ProtoView {
this._viewPool = new ViewPool(VIEW_POOL_CAPACITY); this._viewPool = new ViewPool(VIEW_POOL_CAPACITY);
this.stylePromises = []; this.stylePromises = [];
this.eventHandlers = []; this.eventHandlers = [];
this.bindingRecords = [];
} }
// TODO(rado): hostElementInjector should be moved to hydrate phase. // TODO(rado): hostElementInjector should be moved to hydrate phase.
@ -357,7 +360,9 @@ export class ProtoView {
viewNodes = [rootElementClone]; viewNodes = [rootElementClone];
} }
var view = new View(this, viewNodes, this.protoChangeDetector, this.protoContextLocals); var view = new View(this, viewNodes, this.protoContextLocals);
var changeDetector = this.protoChangeDetector.instantiate(view, this.bindingRecords);
var binders = this.elementBinders; var binders = this.elementBinders;
var elementInjectors = ListWrapper.createFixedSize(binders.length); var elementInjectors = ListWrapper.createFixedSize(binders.length);
var eventHandlers = ListWrapper.createFixedSize(binders.length); var eventHandlers = ListWrapper.createFixedSize(binders.length);
@ -413,12 +418,12 @@ export class ProtoView {
if (isPresent(binder.componentDirective)) { if (isPresent(binder.componentDirective)) {
var strategy = this.shadowDomStrategy; var strategy = this.shadowDomStrategy;
var childView = binder.nestedProtoView.instantiate(elementInjector, eventManager); var childView = binder.nestedProtoView.instantiate(elementInjector, eventManager);
view.changeDetector.addChild(childView.changeDetector); changeDetector.addChild(childView.changeDetector);
lightDom = strategy.constructLightDom(view, childView, element); lightDom = strategy.constructLightDom(view, childView, element);
strategy.attachTemplate(element, childView); strategy.attachTemplate(element, childView);
bindingPropagationConfig = new BindingPropagationConfig(view.changeDetector); bindingPropagationConfig = new BindingPropagationConfig(changeDetector);
ListWrapper.push(componentChildViews, childView); ListWrapper.push(componentChildViews, childView);
} }
@ -454,7 +459,7 @@ export class ProtoView {
this.eventHandlers = eventHandlers; this.eventHandlers = eventHandlers;
view.init(elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings, view.init(changeDetector, elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
viewContainers, preBuiltObjects, componentChildViews); viewContainers, preBuiltObjects, componentChildViews);
return view; return view;
@ -519,7 +524,7 @@ export class ProtoView {
} }
ListWrapper.push(elBinder.textNodeIndices, indexInParent); ListWrapper.push(elBinder.textNodeIndices, indexInParent);
var memento = this.textNodesWithBindingCount++; var memento = this.textNodesWithBindingCount++;
this.protoChangeDetector.addAst(expression, memento); ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
} }
/** /**
@ -532,7 +537,7 @@ export class ProtoView {
this.elementsWithBindingCount++; this.elementsWithBindingCount++;
} }
var memento = new ElementBindingMemento(this.elementsWithBindingCount-1, setterName, setter); var memento = new ElementBindingMemento(this.elementsWithBindingCount-1, setterName, setter);
this.protoChangeDetector.addAst(expression, memento); ListWrapper.push(this.bindingRecords, new BindingRecord(expression, memento, null));
} }
/** /**
@ -579,7 +584,7 @@ export class ProtoView {
setter setter
); );
var directiveMemento = DirectiveMemento.get(bindingMemento); var directiveMemento = DirectiveMemento.get(bindingMemento);
this.protoChangeDetector.addAst(expression, bindingMemento, directiveMemento); ListWrapper.push(this.bindingRecords, new BindingRecord(expression, bindingMemento, directiveMemento));
} }
// Create a rootView as if the compiler encountered <rootcmp></rootcmp>, // Create a rootView as if the compiler encountered <rootcmp></rootcmp>,

View File

@ -6,7 +6,7 @@ import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/faca
import {Parser} from 'angular2/src/change_detection/parser/parser'; import {Parser} from 'angular2/src/change_detection/parser/parser';
import {Lexer} from 'angular2/src/change_detection/parser/lexer'; import {Lexer} from 'angular2/src/change_detection/parser/lexer';
import {ChangeDispatcher, DynamicChangeDetector, ChangeDetectionError, ContextWithVariableBindings, import {ChangeDispatcher, DynamicChangeDetector, ChangeDetectionError, ContextWithVariableBindings, BindingRecord,
PipeRegistry, Pipe, NO_CHANGE, CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from 'angular2/change_detection'; PipeRegistry, Pipe, NO_CHANGE, CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from 'angular2/change_detection';
import {ChangeDetectionUtil} from 'angular2/src/change_detection/change_detection_util'; import {ChangeDetectionUtil} from 'angular2/src/change_detection/change_detection_util';
@ -30,9 +30,8 @@ export function main() {
function createChangeDetector(memo:string, exp:string, context = null, registry = null) { function createChangeDetector(memo:string, exp:string, context = null, registry = null) {
var pcd = createProtoChangeDetector(registry); var pcd = createProtoChangeDetector(registry);
pcd.addAst(ast(exp), memo, memo);
var dispatcher = new TestDispatcher(); var dispatcher = new TestDispatcher();
var cd = pcd.instantiate(dispatcher); var cd = pcd.instantiate(dispatcher, [new BindingRecord(ast(exp), memo, memo)]);
cd.hydrate(context); cd.hydrate(context);
return {"changeDetector" : cd, "dispatcher" : dispatcher}; return {"changeDetector" : cd, "dispatcher" : dispatcher};
@ -179,10 +178,9 @@ export function main() {
var parser = new Parser(new Lexer()); var parser = new Parser(new Lexer());
var pcd = createProtoChangeDetector(); var pcd = createProtoChangeDetector();
var ast = parser.parseInterpolation("B{{a}}A", "location"); var ast = parser.parseInterpolation("B{{a}}A", "location");
pcd.addAst(ast, "memo", "memo");
var dispatcher = new TestDispatcher(); var dispatcher = new TestDispatcher();
var cd = pcd.instantiate(dispatcher); var cd = pcd.instantiate(dispatcher, [new BindingRecord(ast, "memo", "memo")]);
cd.hydrate(new TestData("value")); cd.hydrate(new TestData("value"));
cd.detectChanges(); cd.detectChanges();
@ -230,12 +228,13 @@ export function main() {
describe("group changes", () => { describe("group changes", () => {
it("should notify the dispatcher when a group of records changes", () => { it("should notify the dispatcher when a group of records changes", () => {
var pcd = createProtoChangeDetector(); var pcd = createProtoChangeDetector();
pcd.addAst(ast("1 + 2"), "memo", "1");
pcd.addAst(ast("10 + 20"), "memo", "1");
pcd.addAst(ast("100 + 200"), "memo2", "2");
var dispatcher = new TestDispatcher(); var dispatcher = new TestDispatcher();
var cd = pcd.instantiate(dispatcher); var cd = pcd.instantiate(dispatcher, [
new BindingRecord(ast("1 + 2"), "memo", "1"),
new BindingRecord(ast("10 + 20"), "memo", "1"),
new BindingRecord(ast("100 + 200"), "memo", "2")
]);
cd.detectChanges(); cd.detectChanges();
@ -244,12 +243,12 @@ export function main() {
it("should notify the dispatcher before switching to the next group", () => { it("should notify the dispatcher before switching to the next group", () => {
var pcd = createProtoChangeDetector(); var pcd = createProtoChangeDetector();
pcd.addAst(ast("a()"), "a", "1");
pcd.addAst(ast("b()"), "b", "2");
pcd.addAst(ast("c()"), "c", "2");
var dispatcher = new TestDispatcher(); var dispatcher = new TestDispatcher();
var cd = pcd.instantiate(dispatcher); var cd = pcd.instantiate(dispatcher, [
new BindingRecord(ast("a()"), "a", "1"),
new BindingRecord(ast("b()"), "b", "2"),
new BindingRecord(ast("c()"), "c", "2")
]);
var tr = new TestRecord(); var tr = new TestRecord();
tr.a = () => { tr.a = () => {
@ -279,7 +278,9 @@ export function main() {
pcd.addAst(ast("a"), "a", 1); pcd.addAst(ast("a"), "a", 1);
var dispatcher = new TestDispatcher(); var dispatcher = new TestDispatcher();
var cd = pcd.instantiate(dispatcher); var cd = pcd.instantiate(dispatcher, [
new BindingRecord(ast("a"), "a", 1)
]);
cd.hydrate(new TestData('value')); cd.hydrate(new TestData('value'));
expect(() => { expect(() => {
@ -292,9 +293,9 @@ export function main() {
describe("error handling", () => { describe("error handling", () => {
xit("should wrap exceptions into ChangeDetectionError", () => { xit("should wrap exceptions into ChangeDetectionError", () => {
var pcd = createProtoChangeDetector(); var pcd = createProtoChangeDetector();
pcd.addAst(ast('invalidProp', 'someComponent'), "a", 1); var cd = pcd.instantiate(new TestDispatcher(), [
new BindingRecord(ast("invalidProp", "someComponent"), "a", 1)
var cd = pcd.instantiate(new TestDispatcher()); ]);
cd.hydrate(null); cd.hydrate(null);
try { try {
@ -349,10 +350,10 @@ export function main() {
beforeEach(() => { beforeEach(() => {
var protoParent = createProtoChangeDetector(); var protoParent = createProtoChangeDetector();
parent = protoParent.instantiate(null); parent = protoParent.instantiate(null, []);
var protoChild = createProtoChangeDetector(); var protoChild = createProtoChangeDetector();
child = protoChild.instantiate(null); child = protoChild.instantiate(null, []);
}); });
it("should add children", () => { it("should add children", () => {
@ -395,7 +396,7 @@ export function main() {
}); });
it("should change CHECK_ONCE to CHECKED", () => { it("should change CHECK_ONCE to CHECKED", () => {
var cd = createProtoChangeDetector().instantiate(null); var cd = createProtoChangeDetector().instantiate(null, []);
cd.mode = CHECK_ONCE; cd.mode = CHECK_ONCE;
cd.detectChanges(); cd.detectChanges();
@ -404,7 +405,7 @@ export function main() {
}); });
it("should not change the CHECK_ALWAYS", () => { it("should not change the CHECK_ALWAYS", () => {
var cd = createProtoChangeDetector().instantiate(null); var cd = createProtoChangeDetector().instantiate(null, []);
cd.mode = CHECK_ALWAYS; cd.mode = CHECK_ALWAYS;
cd.detectChanges(); cd.detectChanges();
@ -415,7 +416,7 @@ export function main() {
describe("markPathToRootAsCheckOnce", () => { describe("markPathToRootAsCheckOnce", () => {
function changeDetector(mode, parent) { function changeDetector(mode, parent) {
var cd = createProtoChangeDetector().instantiate(null); var cd = createProtoChangeDetector().instantiate(null, []);
cd.mode = mode; cd.mode = mode;
if (isPresent(parent)) parent.addChild(cd); if (isPresent(parent)) parent.addChild(cd);
return cd; return cd;

View File

@ -12,7 +12,6 @@ import {NgElement} from 'angular2/src/core/dom/element';
import {LightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom'; import {LightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
import {Directive} from 'angular2/src/core/annotations/annotations'; import {Directive} from 'angular2/src/core/annotations/annotations';
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config'; import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config';
import {DynamicProtoChangeDetector} from 'angular2/change_detection';
@proxy @proxy
@IMPLEMENTS(View) @IMPLEMENTS(View)
@ -476,7 +475,7 @@ export function main() {
StringMapWrapper.set(handlers, 'click', (e, view) => { called = true;}); StringMapWrapper.set(handlers, 'click', (e, view) => { called = true;});
var pv = new ProtoView(null, null, null); var pv = new ProtoView(null, null, null);
pv.eventHandlers = [handlers]; pv.eventHandlers = [handlers];
var view = new View(pv, null, new DynamicProtoChangeDetector(null), MapWrapper.create()); var view = new View(pv, null, MapWrapper.create());
var preBuildObject = new PreBuiltObjects(view, null, null, null, null); var preBuildObject = new PreBuiltObjects(view, null, null, null, null);
var inj = injector([NeedsEventEmitter], null, null, preBuildObject); var inj = injector([NeedsEventEmitter], null, null, preBuildObject);
inj.get(NeedsEventEmitter).click(); inj.get(NeedsEventEmitter).click();

View File

@ -10,8 +10,9 @@ import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_str
import {DynamicProtoChangeDetector, ChangeDetector, Lexer, Parser} from 'angular2/change_detection'; import {DynamicProtoChangeDetector, ChangeDetector, Lexer, Parser} from 'angular2/change_detection';
function createView(nodes) { function createView(nodes) {
var view = new View(null, nodes, new DynamicProtoChangeDetector(null), MapWrapper.create()); var view = new View(null, nodes, MapWrapper.create());
view.init([], [], [], [], [], [], []); var cd = new DynamicProtoChangeDetector(null).instantiate(view, []);
view.init(cd, [], [], [], [], [], [], []);
return view; return view;
} }

View File

@ -10,7 +10,8 @@ import {
ChangeDispatcher, ChangeDispatcher,
ChangeDetection, ChangeDetection,
dynamicChangeDetection, dynamicChangeDetection,
jitChangeDetection jitChangeDetection,
BindingRecord
} from 'angular2/change_detection'; } from 'angular2/change_detection';
@ -104,31 +105,28 @@ function setUpChangeDetection(changeDetection:ChangeDetection, iterations) {
var parser = new Parser(new Lexer()); var parser = new Parser(new Lexer());
var parentProto = changeDetection.createProtoChangeDetector('parent'); var parentProto = changeDetection.createProtoChangeDetector('parent');
var parentCd = parentProto.instantiate(dispatcher); var parentCd = parentProto.instantiate(dispatcher, []);
var proto = changeDetection.createProtoChangeDetector("proto"); var proto = changeDetection.createProtoChangeDetector("proto");
var astWithSource = [ var bindingRecords = [
parser.parseBinding('field0', null), new BindingRecord(parser.parseBinding('field0', null), "memo", 0),
parser.parseBinding('field1', null), new BindingRecord(parser.parseBinding('field1', null), "memo", 1),
parser.parseBinding('field2', null), new BindingRecord(parser.parseBinding('field2', null), "memo", 2),
parser.parseBinding('field3', null), new BindingRecord(parser.parseBinding('field3', null), "memo", 3),
parser.parseBinding('field4', null), new BindingRecord(parser.parseBinding('field4', null), "memo", 4),
parser.parseBinding('field5', null), new BindingRecord(parser.parseBinding('field5', null), "memo", 5),
parser.parseBinding('field6', null), new BindingRecord(parser.parseBinding('field6', null), "memo", 6),
parser.parseBinding('field7', null), new BindingRecord(parser.parseBinding('field7', null), "memo", 7),
parser.parseBinding('field8', null), new BindingRecord(parser.parseBinding('field8', null), "memo", 8),
parser.parseBinding('field9', null) new BindingRecord(parser.parseBinding('field9', null), "memo", 9)
]; ];
for (var j = 0; j < 10; ++j) {
proto.addAst(astWithSource[j].ast, "memo", j);
}
for (var i = 0; i < iterations; ++i) { for (var i = 0; i < iterations; ++i) {
var obj = new Obj(); var obj = new Obj();
for (var j = 0; j < 10; ++j) { for (var j = 0; j < 10; ++j) {
obj.setField(j, i); obj.setField(j, i);
} }
var cd = proto.instantiate(dispatcher); var cd = proto.instantiate(dispatcher, bindingRecords);
cd.hydrate(obj); cd.hydrate(obj);
parentCd.addChild(cd); parentCd.addChild(cd);
} }