Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10913133: Allow closures inside lazy initializers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add test. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 updateLocal(boxedVariable, oldValue); 360 updateLocal(boxedVariable, oldValue);
361 } 361 }
362 updateLocal(boxElement, newBox); 362 updateLocal(boxElement, newBox);
363 } 363 }
364 364
365 /** 365 /**
366 * Documentation wanted -- johnniwinther 366 * Documentation wanted -- johnniwinther
367 * 367 *
368 * Invariant: [function] must be an implementation element. 368 * Invariant: [function] must be an implementation element.
369 */ 369 */
370 void startFunction(FunctionElement function, 370 void startFunction(Element element, Expression node) {
371 FunctionExpression node) { 371 assert(invariant(node, element.isImplementation));
372 assert(invariant(node, function.isImplementation));
373 Compiler compiler = builder.compiler; 372 Compiler compiler = builder.compiler;
374 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 373 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
375 node, builder.elements); 374 element, node, builder.elements);
376 FunctionSignature signature = function.computeSignature(compiler); 375
377 signature.orderedForEachParameter((Element element) { 376 if (element is FunctionElement) {
378 HInstruction parameter = new HParameterValue(element); 377 FunctionElement functionElement = element;
379 builder.add(parameter); 378 FunctionSignature params = functionElement.computeSignature(compiler);
380 builder.parameters[element] = parameter; 379 params.orderedForEachParameter((Element parameterElement) {
381 directLocals[element] = parameter; 380 HInstruction parameter = new HParameterValue(parameterElement);
382 parameter.guaranteedType = 381 builder.add(parameter);
383 builder.mapInferredType(typesTask.getGuaranteedTypeOfElement(element)); 382 builder.parameters[parameterElement] = parameter;
384 }); 383 directLocals[parameterElement] = parameter;
384 parameter.guaranteedType =
385 builder.mapInferredType(
386 typesTask.getGuaranteedTypeOfElement(parameterElement));
387 });
388 }
385 389
386 enterScope(node); 390 enterScope(node);
387 391
388 // If the freeVariableMapping is not empty, then this function was a 392 // If the freeVariableMapping is not empty, then this function was a
389 // nested closure that captures variables. Redirect the captured 393 // nested closure that captures variables. Redirect the captured
390 // variables to fields in the closure. 394 // variables to fields in the closure.
391 closureData.freeVariableMapping.forEach((Element from, Element to) { 395 closureData.freeVariableMapping.forEach((Element from, Element to) {
392 redirectElement(from, to); 396 redirectElement(from, to);
393 }); 397 });
394 if (closureData.isClosure()) { 398 if (closureData.isClosure()) {
395 // Inside closure redirect references to itself to [:this:]. 399 // Inside closure redirect references to itself to [:this:].
396 HInstruction thisInstruction = new HThis(); 400 HInstruction thisInstruction = new HThis();
397 builder.add(thisInstruction); 401 builder.add(thisInstruction);
398 updateLocal(closureData.closureElement, thisInstruction); 402 updateLocal(closureData.closureElement, thisInstruction);
399 } else if (function.isInstanceMember() 403 } else if (element.isInstanceMember()
400 || function.isGenerativeConstructor()) { 404 || element.isGenerativeConstructor()) {
401 // Once closures have been mapped to classes their instance members might 405 // Once closures have been mapped to classes their instance members might
402 // not have any thisElement if the closure was created inside a static 406 // not have any thisElement if the closure was created inside a static
403 // context. 407 // context.
404 ClassElement cls = function.getEnclosingClass(); 408 ClassElement cls = element.getEnclosingClass();
405 DartType type = cls.computeType(builder.compiler); 409 DartType type = cls.computeType(builder.compiler);
406 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); 410 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type));
407 builder.add(thisInstruction); 411 builder.add(thisInstruction);
408 directLocals[closureData.thisElement] = thisInstruction; 412 directLocals[closureData.thisElement] = thisInstruction;
409 } 413 }
410 } 414 }
411 415
412 bool hasValueForDirectLocal(Element element) { 416 bool hasValueForDirectLocal(Element element) {
413 assert(element !== null); 417 assert(element !== null);
414 assert(isAccessedDirectly(element)); 418 assert(isAccessedDirectly(element));
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 FunctionExpression function = functionElement.parseNode(compiler); 927 FunctionExpression function = functionElement.parseNode(compiler);
924 assert(function !== null); 928 assert(function !== null);
925 assert(!function.modifiers.isExternal()); 929 assert(!function.modifiers.isExternal());
926 assert(elements[function] !== null); 930 assert(elements[function] !== null);
927 openFunction(functionElement, function); 931 openFunction(functionElement, function);
928 function.body.accept(this); 932 function.body.accept(this);
929 return closeFunction(); 933 return closeFunction();
930 } 934 }
931 935
932 HGraph buildLazyInitializer(VariableElement variable) { 936 HGraph buildLazyInitializer(VariableElement variable) {
933 HBasicBlock block = graph.addNewBlock();
934 open(graph.entry);
935 close(new HGoto()).addSuccessor(block);
936 open(block);
937 SendSet node = variable.parseNode(compiler); 937 SendSet node = variable.parseNode(compiler);
938 openFunction(variable, node);
938 Link<Node> link = node.arguments; 939 Link<Node> link = node.arguments;
939 assert(!link.isEmpty() && link.tail.isEmpty()); 940 assert(!link.isEmpty() && link.tail.isEmpty());
940 visit(link.head); 941 visit(link.head);
941 HInstruction value = pop(); 942 HInstruction value = pop();
942 value = potentiallyCheckType(value, variable); 943 value = potentiallyCheckType(value, variable);
943 close(new HReturn(value)).addSuccessor(graph.exit); 944 close(new HReturn(value)).addSuccessor(graph.exit);
944 graph.finalize(); 945 return closeFunction();
945 return graph;
946 } 946 }
947 947
948 /** 948 /**
949 * Returns the constructor body associated with the given constructor or 949 * Returns the constructor body associated with the given constructor or
950 * creates a new constructor body, if none can be found. 950 * creates a new constructor body, if none can be found.
951 * 951 *
952 * Returns [:null:] if the constructor does not have a body. 952 * Returns [:null:] if the constructor does not have a body.
953 */ 953 */
954 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 954 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
955 assert(constructor.isGenerativeConstructor()); 955 assert(constructor.isGenerativeConstructor());
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 ClosureClassMap closureData = localsHandler.closureData; 1404 ClosureClassMap closureData = localsHandler.closureData;
1405 Element checkResultElement = closureData.parametersWithSentinel[element]; 1405 Element checkResultElement = closureData.parametersWithSentinel[element];
1406 localsHandler.updateLocal(checkResultElement, check); 1406 localsHandler.updateLocal(checkResultElement, check);
1407 } 1407 }
1408 1408
1409 /** 1409 /**
1410 * Documentation wanted -- johnniwinther 1410 * Documentation wanted -- johnniwinther
1411 * 1411 *
1412 * Invariant: [functionElement] must be the implementation element. 1412 * Invariant: [functionElement] must be the implementation element.
1413 */ 1413 */
1414 void openFunction(FunctionElement functionElement, 1414 void openFunction(Element element, Expression node) {
1415 FunctionExpression node) { 1415 assert(invariant(element, element.isImplementation));
1416 assert(invariant(functionElement, functionElement.isImplementation));
1417 HBasicBlock block = graph.addNewBlock(); 1416 HBasicBlock block = graph.addNewBlock();
1418 open(graph.entry); 1417 open(graph.entry);
1419 1418
1420 localsHandler.startFunction(functionElement, node); 1419 localsHandler.startFunction(element, node);
1421 close(new HGoto()).addSuccessor(block); 1420 close(new HGoto()).addSuccessor(block);
1422 1421
1423 open(block); 1422 open(block);
1424 1423
1425 FunctionSignature params = functionElement.computeSignature(compiler); 1424 if (element is FunctionElement) {
1426 params.orderedForEachParameter((Element element) { 1425 FunctionElement functionElement = element;
1427 if (elements.isParameterChecked(element)) { 1426 FunctionSignature params = functionElement.computeSignature(compiler);
1428 addParameterCheckInstruction(element); 1427 params.orderedForEachParameter((Element parameterElement) {
1429 } 1428 if (elements.isParameterChecked(parameterElement)) {
1430 }); 1429 addParameterCheckInstruction(parameterElement);
1430 }
1431 });
1431 1432
1432 // Put the type checks in the first successor of the entry, 1433 // Put the type checks in the first successor of the entry,
1433 // because that is where the type guards will also be inserted. 1434 // because that is where the type guards will also be inserted.
1434 // This way we ensure that a type guard will dominate the type 1435 // This way we ensure that a type guard will dominate the type
1435 // check. 1436 // check.
1436 params.orderedForEachParameter((Element element) { 1437 params.orderedForEachParameter((Element element) {
1437 HInstruction newParameter = potentiallyCheckType( 1438 HInstruction newParameter = potentiallyCheckType(
1438 localsHandler.directLocals[element], element); 1439 localsHandler.directLocals[element], element);
1439 localsHandler.directLocals[element] = newParameter; 1440 localsHandler.directLocals[element] = newParameter;
1440 }); 1441 });
1442 } else {
1443 // Otherwise it is a lazy initializer which does not have parameters.
1444 assert(element is VariableElement);
1445 }
1441 1446
1442 // Add the type parameters of the class as parameters of this 1447 // Add the type parameters of the class as parameters of this
1443 // method. 1448 // method.
1444 var enclosing = functionElement.enclosingElement; 1449 var enclosing = element.enclosingElement;
1445 if (functionElement.isConstructor() && compiler.world.needsRti(enclosing)) { 1450 if (element.isConstructor() && compiler.world.needsRti(enclosing)) {
1446 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1451 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1447 HParameterValue param = new HParameterValue(typeVariable.element); 1452 HParameterValue param = new HParameterValue(typeVariable.element);
1448 add(param); 1453 add(param);
1449 localsHandler.directLocals[typeVariable.element] = param; 1454 localsHandler.directLocals[typeVariable.element] = param;
1450 }); 1455 });
1451 } 1456 }
1452 } 1457 }
1453 1458
1454 HInstruction potentiallyCheckType( 1459 HInstruction potentiallyCheckType(
1455 HInstruction original, Element sourceElement, 1460 HInstruction original, Element sourceElement,
(...skipping 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after
4454 new HSubGraphBlockInformation(elseBranch.graph)); 4459 new HSubGraphBlockInformation(elseBranch.graph));
4455 4460
4456 HBasicBlock conditionStartBlock = conditionBranch.block; 4461 HBasicBlock conditionStartBlock = conditionBranch.block;
4457 conditionStartBlock.setBlockFlow(info, joinBlock); 4462 conditionStartBlock.setBlockFlow(info, joinBlock);
4458 SubGraph conditionGraph = conditionBranch.graph; 4463 SubGraph conditionGraph = conditionBranch.graph;
4459 HIf branch = conditionGraph.end.last; 4464 HIf branch = conditionGraph.end.last;
4460 assert(branch is HIf); 4465 assert(branch is HIf);
4461 branch.blockInformation = conditionStartBlock.blockFlow; 4466 branch.blockInformation = conditionStartBlock.blockFlow;
4462 } 4467 }
4463 } 4468 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698