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

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

Issue 19754002: Rewrite how we handle synthesized constructors in the compiler. This was motivated by issue https:/… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 205 }
206 updateLocal(boxElement, newBox); 206 updateLocal(boxElement, newBox);
207 } 207 }
208 208
209 /** 209 /**
210 * Documentation wanted -- johnniwinther 210 * Documentation wanted -- johnniwinther
211 * 211 *
212 * Invariant: [function] must be an implementation element. 212 * Invariant: [function] must be an implementation element.
213 */ 213 */
214 void startFunction(Element element, Expression node) { 214 void startFunction(Element element, Expression node) {
215 assert(invariant(node, element.isImplementation)); 215 assert(invariant(element, element.isImplementation));
216 Compiler compiler = builder.compiler; 216 Compiler compiler = builder.compiler;
217 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 217 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
218 element, node, builder.elements); 218 element, node, builder.elements);
219 219
220 if (element is FunctionElement) { 220 if (element is FunctionElement) {
221 FunctionElement functionElement = element; 221 FunctionElement functionElement = element;
222 FunctionSignature params = functionElement.computeSignature(compiler); 222 FunctionSignature params = functionElement.computeSignature(compiler);
223 params.orderedForEachParameter((Element parameterElement) { 223 params.orderedForEachParameter((Element parameterElement) {
224 if (element.isGenerativeConstructorBody()) { 224 if (element.isGenerativeConstructorBody()) {
225 ClosureScope scopeData = closureData.capturingScopes[node]; 225 ClosureScope scopeData = closureData.capturingScopes[node];
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 1264
1265 return true; 1265 return true;
1266 } 1266 }
1267 1267
1268 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { 1268 bool heuristicSayGoodToGo(FunctionExpression functionExpression) {
1269 // Don't inline recursivly 1269 // Don't inline recursivly
1270 if (inliningStack.any((entry) => entry.function == function)) { 1270 if (inliningStack.any((entry) => entry.function == function)) {
1271 return false; 1271 return false;
1272 } 1272 }
1273 1273
1274 if (element.isSynthesized) return true;
1275
1274 if (cachedCanBeInlined == true) return cachedCanBeInlined; 1276 if (cachedCanBeInlined == true) return cachedCanBeInlined;
1275 1277
1276 int numParameters = function.functionSignature.parameterCount; 1278 int numParameters = function.functionSignature.parameterCount;
1277 int maxInliningNodes; 1279 int maxInliningNodes;
1278 if (insideLoop) { 1280 if (insideLoop) {
1279 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 1281 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
1280 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 1282 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
1281 } else { 1283 } else {
1282 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 1284 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
1283 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 1285 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 sourceElementStack.removeLast(); 1341 sourceElementStack.removeLast();
1340 return result; 1342 return result;
1341 }); 1343 });
1342 } 1344 }
1343 1345
1344 /** 1346 /**
1345 * Documentation wanted -- johnniwinther 1347 * Documentation wanted -- johnniwinther
1346 * 1348 *
1347 * Invariant: [constructors] must contain only implementation elements. 1349 * Invariant: [constructors] must contain only implementation elements.
1348 */ 1350 */
1349 void inlineSuperOrRedirect(FunctionElement constructor, 1351 void inlineSuperOrRedirect(FunctionElement callee,
1350 Selector selector, 1352 List<HInstruction> compiledArguments,
1351 Link<Node> arguments,
1352 List<FunctionElement> constructors, 1353 List<FunctionElement> constructors,
1353 Map<Element, HInstruction> fieldValues, 1354 Map<Element, HInstruction> fieldValues,
1354 FunctionElement inlinedFromElement, 1355 FunctionElement caller) {
1355 Node callNode) { 1356 callee = callee.implementation;
1356 constructor = constructor.implementation; 1357 compiler.withCurrentElement(callee, () {
1357 compiler.withCurrentElement(constructor, () { 1358 constructors.add(callee);
1358 constructors.add(constructor); 1359 ClassElement enclosingClass = callee.getEnclosingClass();
1359
1360 List<HInstruction> compiledArguments = new List<HInstruction>();
1361 bool succeeded =
1362 inlinedFrom(inlinedFromElement,
1363 () => addStaticSendArgumentsToList(selector,
1364 arguments,
1365 constructor,
1366 compiledArguments));
1367 if (!succeeded) {
1368 // Non-matching super and redirects are compile-time errors and thus
1369 // checked by the resolver.
1370 compiler.internalError(
1371 "Parameters and arguments didn't match for super/redirect call",
1372 element: constructor);
1373 }
1374
1375 ClassElement enclosingClass = constructor.getEnclosingClass();
1376 if (backend.classNeedsRti(enclosingClass)) { 1360 if (backend.classNeedsRti(enclosingClass)) {
1377 // If [enclosingClass] needs RTI, we have to give a value to its 1361 // If [enclosingClass] needs RTI, we have to give a value to its
1378 // type parameters. 1362 // type parameters.
1379 ClassElement currentClass = inlinedFromElement.getEnclosingClass(); 1363 ClassElement currentClass = caller.getEnclosingClass();
1380 // For a super constructor call, the type is the supertype of 1364 // For a super constructor call, the type is the supertype of
1381 // [currentClass]. For a redirecting constructor, the type is 1365 // [currentClass]. For a redirecting constructor, the type is
1382 // the current type. [InterfaceType.asInstanceOf] takes care 1366 // the current type. [InterfaceType.asInstanceOf] takes care
1383 // of both. 1367 // of both.
1384 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass); 1368 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass);
1385 Link<DartType> typeVariables = enclosingClass.typeVariables; 1369 Link<DartType> typeVariables = enclosingClass.typeVariables;
1386 type.typeArguments.forEach((DartType argument) { 1370 type.typeArguments.forEach((DartType argument) {
1387 localsHandler.updateLocal(typeVariables.head.element, 1371 localsHandler.updateLocal(
1388 analyzeTypeArgument(argument, callNode)); 1372 typeVariables.head.element,
1373 analyzeTypeArgument(argument));
1389 typeVariables = typeVariables.tail; 1374 typeVariables = typeVariables.tail;
1390 }); 1375 });
1391 // If the supertype is a raw type, we need to set to null the 1376 // If the supertype is a raw type, we need to set to null the
1392 // type variables. 1377 // type variables.
1393 assert(typeVariables.isEmpty 1378 assert(typeVariables.isEmpty
1394 || enclosingClass.typeVariables == typeVariables); 1379 || enclosingClass.typeVariables == typeVariables);
1395 while (!typeVariables.isEmpty) { 1380 while (!typeVariables.isEmpty) {
1396 localsHandler.updateLocal(typeVariables.head.element, 1381 localsHandler.updateLocal(typeVariables.head.element,
1397 graph.addConstantNull(compiler)); 1382 graph.addConstantNull(compiler));
1398 typeVariables = typeVariables.tail; 1383 typeVariables = typeVariables.tail;
1399 } 1384 }
1400 } 1385 }
1401 1386
1402 inlinedFrom(constructor, () { 1387 inlinedFrom(callee, () {
1403 buildFieldInitializers(constructor.enclosingElement.implementation, 1388 buildFieldInitializers(callee.enclosingElement.implementation,
1404 fieldValues); 1389 fieldValues);
1405 }); 1390 });
1406 1391
1407 int index = 0; 1392 int index = 0;
1408 FunctionSignature params = constructor.computeSignature(compiler); 1393 FunctionSignature params = callee.computeSignature(compiler);
1409 params.orderedForEachParameter((Element parameter) { 1394 params.orderedForEachParameter((Element parameter) {
1410 HInstruction argument = compiledArguments[index++]; 1395 HInstruction argument = compiledArguments[index++];
1411 // Because we are inlining the initializer, we must update 1396 // Because we are inlining the initializer, we must update
1412 // what was given as parameter. This will be used in case 1397 // what was given as parameter. This will be used in case
1413 // there is a parameter check expression in the initializer. 1398 // there is a parameter check expression in the initializer.
1414 parameters[parameter] = argument; 1399 parameters[parameter] = argument;
1415 localsHandler.updateLocal(parameter, argument); 1400 localsHandler.updateLocal(parameter, argument);
1416 // Don't forget to update the field, if the parameter is of the 1401 // Don't forget to update the field, if the parameter is of the
1417 // form [:this.x:]. 1402 // form [:this.x:].
1418 if (parameter.kind == ElementKind.FIELD_PARAMETER) { 1403 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
1419 FieldParameterElement fieldParameterElement = parameter; 1404 FieldParameterElement fieldParameterElement = parameter;
1420 fieldValues[fieldParameterElement.fieldElement] = argument; 1405 fieldValues[fieldParameterElement.fieldElement] = argument;
1421 } 1406 }
1422 }); 1407 });
1423 1408
1424 // Build the initializers in the context of the new constructor. 1409 // Build the initializers in the context of the new constructor.
1425 TreeElements oldElements = elements; 1410 TreeElements oldElements = elements;
1426 if (constructor.isForwardingConstructor) { 1411 elements = compiler.enqueuer.resolution.getCachedElements(callee);
1427 constructor = constructor.targetConstructor;
1428 }
1429 elements =
1430 compiler.enqueuer.resolution.getCachedElements(constructor);
1431 ClosureClassMap oldClosureData = localsHandler.closureData; 1412 ClosureClassMap oldClosureData = localsHandler.closureData;
1432 Node node = constructor.parseNode(compiler); 1413 Node node = callee.parseNode(compiler);
1433 ClosureClassMap newClosureData = 1414 ClosureClassMap newClosureData =
1434 compiler.closureToClassMapper.computeClosureToClassMapping( 1415 compiler.closureToClassMapper.computeClosureToClassMapping(
1435 constructor, node, elements); 1416 callee, node, elements);
1436 localsHandler.closureData = newClosureData; 1417 localsHandler.closureData = newClosureData;
1437 localsHandler.enterScope(node, constructor); 1418 localsHandler.enterScope(node, callee);
1438 buildInitializers(constructor, constructors, fieldValues); 1419 buildInitializers(callee, constructors, fieldValues);
1439 localsHandler.closureData = oldClosureData; 1420 localsHandler.closureData = oldClosureData;
1440 elements = oldElements; 1421 elements = oldElements;
1441 }); 1422 });
1442 } 1423 }
1443 1424
1444 /** 1425 /**
1445 * Run through the initializers and inline all field initializers. Recursively 1426 * Run through the initializers and inline all field initializers. Recursively
1446 * inlines super initializers. 1427 * inlines super initializers.
1447 * 1428 *
1448 * The constructors of the inlined initializers is added to [constructors] 1429 * The constructors of the inlined initializers is added to [constructors]
1449 * with sub constructors having a lower index than super constructors. 1430 * with sub constructors having a lower index than super constructors.
1450 * 1431 *
1451 * Invariant: The [constructor] and elements in [constructors] must all be 1432 * Invariant: The [constructor] and elements in [constructors] must all be
1452 * implementation elements. 1433 * implementation elements.
1453 */ 1434 */
1454 void buildInitializers(FunctionElement constructor, 1435 void buildInitializers(FunctionElement constructor,
1455 List<FunctionElement> constructors, 1436 List<FunctionElement> constructors,
1456 Map<Element, HInstruction> fieldValues) { 1437 Map<Element, HInstruction> fieldValues) {
1457 assert(invariant(constructor, constructor.isImplementation)); 1438 assert(invariant(constructor, constructor.isImplementation));
1439 if (constructor.isSynthesized) {
1440 List<HInstruction> arguments = <HInstruction>[];
1441 HInstruction compileArgument(Element element) {
1442 return localsHandler.readLocal(element);
1443 }
1444
1445 Element target = constructor.targetConstructor.implementation;
1446 Selector.addForwardingElementArgumentsToList(
1447 constructor,
1448 arguments,
1449 target,
1450 compileArgument,
1451 handleConstantForOptionalParameter,
1452 compiler);
1453 inlineSuperOrRedirect(
1454 target,
1455 arguments,
1456 constructors,
1457 fieldValues,
1458 constructor);
1459 return;
1460 }
1458 FunctionExpression functionNode = constructor.parseNode(compiler); 1461 FunctionExpression functionNode = constructor.parseNode(compiler);
1459 1462
1460 bool foundSuperOrRedirect = false; 1463 bool foundSuperOrRedirect = false;
1461
1462 if (functionNode.initializers != null) { 1464 if (functionNode.initializers != null) {
1463 Link<Node> initializers = functionNode.initializers.nodes; 1465 Link<Node> initializers = functionNode.initializers.nodes;
1464 for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) { 1466 for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
1465 assert(link.head is Send); 1467 assert(link.head is Send);
1466 if (link.head is !SendSet) { 1468 if (link.head is !SendSet) {
1467 // A super initializer or constructor redirection. 1469 // A super initializer or constructor redirection.
1470 foundSuperOrRedirect = true;
1468 Send call = link.head; 1471 Send call = link.head;
1469 assert(Initializers.isSuperConstructorCall(call) || 1472 assert(Initializers.isSuperConstructorCall(call) ||
1470 Initializers.isConstructorRedirect(call)); 1473 Initializers.isConstructorRedirect(call));
1471 FunctionElement target = elements[call]; 1474 FunctionElement target = elements[call].implementation;
1472 Selector selector = elements.getSelector(call); 1475 Selector selector = elements.getSelector(call);
1473 Link<Node> arguments = call.arguments; 1476 Link<Node> arguments = call.arguments;
1477 List<HInstruction> compiledArguments = new List<HInstruction>();
1478 inlinedFrom(constructor, () {
1479 addStaticSendArgumentsToList(selector,
1480 arguments,
1481 target,
1482 compiledArguments);
1483 });
1474 inlineSuperOrRedirect(target, 1484 inlineSuperOrRedirect(target,
1475 selector, 1485 compiledArguments,
1476 arguments,
1477 constructors, 1486 constructors,
1478 fieldValues, 1487 fieldValues,
1479 constructor, 1488 constructor);
1480 call);
1481 foundSuperOrRedirect = true;
1482 } else { 1489 } else {
1483 // A field initializer. 1490 // A field initializer.
1484 SendSet init = link.head; 1491 SendSet init = link.head;
1485 Link<Node> arguments = init.arguments; 1492 Link<Node> arguments = init.arguments;
1486 assert(!arguments.isEmpty && arguments.tail.isEmpty); 1493 assert(!arguments.isEmpty && arguments.tail.isEmpty);
1487 inlinedFrom(constructor, () { 1494 inlinedFrom(constructor, () {
1488 visit(arguments.head); 1495 visit(arguments.head);
1489 }); 1496 });
1490 fieldValues[elements[init]] = pop(); 1497 fieldValues[elements[init]] = pop();
1491 } 1498 }
1492 } 1499 }
1493 } 1500 }
1494 1501
1495 if (!foundSuperOrRedirect) { 1502 if (!foundSuperOrRedirect) {
1496 // No super initializer found. Try to find the default constructor if 1503 // No super initializer found. Try to find the default constructor if
1497 // the class is not Object. 1504 // the class is not Object.
1498 ClassElement enclosingClass = constructor.getEnclosingClass(); 1505 ClassElement enclosingClass = constructor.getEnclosingClass();
1499 ClassElement superClass = enclosingClass.superclass; 1506 ClassElement superClass = enclosingClass.superclass;
1500 if (!enclosingClass.isObject(compiler)) { 1507 if (!enclosingClass.isObject(compiler)) {
1501 assert(superClass != null); 1508 assert(superClass != null);
1502 assert(superClass.resolutionState == STATE_DONE); 1509 assert(superClass.resolutionState == STATE_DONE);
1503 Selector selector = 1510 Selector selector =
1504 new Selector.callDefaultConstructor(enclosingClass.getLibrary()); 1511 new Selector.callDefaultConstructor(enclosingClass.getLibrary());
1505 // TODO(johnniwinther): Should we find injected constructors as well? 1512 // TODO(johnniwinther): Should we find injected constructors as well?
1506 FunctionElement target = superClass.lookupConstructor(selector); 1513 FunctionElement target = superClass.lookupConstructor(selector);
1507 if (target == null) { 1514 if (target == null) {
1508 compiler.internalError("no default constructor available"); 1515 compiler.internalError("no default constructor available");
1509 } 1516 }
1517 List<HInstruction> arguments = <HInstruction>[];
1518 selector.addArgumentsToList(const Link<Node>(),
1519 arguments,
1520 target.implementation,
1521 null,
1522 handleConstantForOptionalParameter,
1523 compiler);
1510 inlineSuperOrRedirect(target, 1524 inlineSuperOrRedirect(target,
1511 selector, 1525 arguments,
1512 const Link<Node>(),
1513 constructors, 1526 constructors,
1514 fieldValues, 1527 fieldValues,
1515 constructor, 1528 constructor);
1516 functionNode);
1517 } 1529 }
1518 } 1530 }
1519 } 1531 }
1520 1532
1521 /** 1533 /**
1522 * Run through the fields of [cls] and add their potential 1534 * Run through the fields of [cls] and add their potential
1523 * initializers. 1535 * initializers.
1524 * 1536 *
1525 * Invariant: [classElement] must be an implementation element. 1537 * Invariant: [classElement] must be an implementation element.
1526 */ 1538 */
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2907 Link<Node> arguments, 2919 Link<Node> arguments,
2908 FunctionElement element, 2920 FunctionElement element,
2909 List<HInstruction> list) { 2921 List<HInstruction> list) {
2910 assert(invariant(element, element.isImplementation)); 2922 assert(invariant(element, element.isImplementation));
2911 2923
2912 HInstruction compileArgument(Node argument) { 2924 HInstruction compileArgument(Node argument) {
2913 visit(argument); 2925 visit(argument);
2914 return pop(); 2926 return pop();
2915 } 2927 }
2916 2928
2917 if (element.isForwardingConstructor) {
2918 element = element.targetConstructor;
2919 }
2920
2921 return selector.addArgumentsToList(arguments, 2929 return selector.addArgumentsToList(arguments,
2922 list, 2930 list,
2923 element, 2931 element,
2924 compileArgument, 2932 compileArgument,
2925 handleConstantForOptionalParameter, 2933 handleConstantForOptionalParameter,
2926 compiler); 2934 compiler);
2927 } 2935 }
2928 2936
2929 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 2937 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
2930 for (; !link.isEmpty; link = link.tail) { 2938 for (; !link.isEmpty; link = link.tail) {
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
3364 compiler.cancel('Unimplemented unresolved type variable', 3372 compiler.cancel('Unimplemented unresolved type variable',
3365 element: type.element); 3373 element: type.element);
3366 } 3374 }
3367 } 3375 }
3368 3376
3369 /** 3377 /**
3370 * Documentation wanted -- johnniwinther 3378 * Documentation wanted -- johnniwinther
3371 * 3379 *
3372 * Invariant: [argument] must not be malformed in checked mode. 3380 * Invariant: [argument] must not be malformed in checked mode.
3373 */ 3381 */
3374 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { 3382 HInstruction analyzeTypeArgument(DartType argument) {
3375 assert(invariant(currentNode, 3383 assert(invariant(currentElement,
3376 !compiler.enableTypeAssertions || !argument.isMalformed, 3384 !compiler.enableTypeAssertions || !argument.isMalformed,
3377 message: '$argument is malformed in checked mode')); 3385 message: '$argument is malformed in checked mode'));
3378 if (argument == compiler.types.dynamicType || argument.isMalformed) { 3386 if (argument == compiler.types.dynamicType || argument.isMalformed) {
3379 // Represent [dynamic] as [null]. 3387 // Represent [dynamic] as [null].
3380 return graph.addConstantNull(compiler); 3388 return graph.addConstantNull(compiler);
3381 } 3389 }
3382 3390
3383 List<HInstruction> inputs = <HInstruction>[]; 3391 List<HInstruction> inputs = <HInstruction>[];
3384 3392
3385 String template = rti.getTypeRepresentation(argument, (variable) { 3393 String template = rti.getTypeRepresentation(argument, (variable) {
3386 inputs.add(addTypeVariableReference(variable)); 3394 inputs.add(addTypeVariableReference(variable));
3387 }); 3395 });
3388 3396
3389 HInstruction result = createForeign(template, backend.stringType, inputs); 3397 HInstruction result = createForeign(template, backend.stringType, inputs);
3390 add(result); 3398 add(result);
3391 return result; 3399 return result;
3392 } 3400 }
3393 3401
3394 void handleListConstructor(InterfaceType type, 3402 void handleListConstructor(InterfaceType type,
3395 Node currentNode, 3403 Node currentNode,
3396 HInstruction newObject) { 3404 HInstruction newObject) {
3397 if (!backend.classNeedsRti(type.element)) return; 3405 if (!backend.classNeedsRti(type.element)) return;
3398 if (!type.isRaw) { 3406 if (!type.isRaw) {
3399 List<HInstruction> inputs = <HInstruction>[]; 3407 List<HInstruction> inputs = <HInstruction>[];
3400 type.typeArguments.forEach((DartType argument) { 3408 type.typeArguments.forEach((DartType argument) {
3401 inputs.add(analyzeTypeArgument(argument, currentNode)); 3409 inputs.add(analyzeTypeArgument(argument));
3402 }); 3410 });
3403 callSetRuntimeTypeInfo(type.element, inputs, newObject); 3411 callSetRuntimeTypeInfo(type.element, inputs, newObject);
3404 } 3412 }
3405 } 3413 }
3406 3414
3407 void callSetRuntimeTypeInfo(ClassElement element, 3415 void callSetRuntimeTypeInfo(ClassElement element,
3408 List<HInstruction> rtiInputs, 3416 List<HInstruction> rtiInputs,
3409 HInstruction newObject) { 3417 HInstruction newObject) {
3410 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { 3418 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) {
3411 return; 3419 return;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3454 ClassElement cls = element.getEnclosingClass(); 3462 ClassElement cls = element.getEnclosingClass();
3455 return new HType.nonNullExact(cls.thisType, compiler); 3463 return new HType.nonNullExact(cls.thisType, compiler);
3456 } else { 3464 } else {
3457 return new HType.inferredReturnTypeForElement( 3465 return new HType.inferredReturnTypeForElement(
3458 originalElement, compiler); 3466 originalElement, compiler);
3459 } 3467 }
3460 } 3468 }
3461 3469
3462 Element constructor = elements[send]; 3470 Element constructor = elements[send];
3463 Selector selector = elements.getSelector(send); 3471 Selector selector = elements.getSelector(send);
3464 if (constructor.isForwardingConstructor) {
3465 compiler.unimplemented('forwarded constructor in named mixin application',
3466 element: constructor.getEnclosingClass());
3467 }
3468 if (compiler.enqueuer.resolution.getCachedElements(constructor) == null) {
3469 compiler.internalError("Unresolved element: $constructor", node: send);
3470 }
3471 FunctionElement functionElement = constructor; 3472 FunctionElement functionElement = constructor;
3472 constructor = functionElement.redirectionTarget; 3473 constructor = functionElement.redirectionTarget;
3473 3474
3474 final bool isSymbolConstructor = 3475 final bool isSymbolConstructor =
3475 functionElement == compiler.symbolConstructor; 3476 functionElement == compiler.symbolConstructor;
3476 3477
3477 if (isSymbolConstructor) { 3478 if (isSymbolConstructor) {
3478 constructor = compiler.symbolValidatedConstructor; 3479 constructor = compiler.symbolValidatedConstructor;
3479 assert(invariant(send, constructor != null, 3480 assert(invariant(send, constructor != null,
3480 message: 'Constructor Symbol.validated is missing')); 3481 message: 'Constructor Symbol.validated is missing'));
(...skipping 20 matching lines...) Expand all
3501 } 3502 }
3502 3503
3503 ClassElement cls = constructor.getEnclosingClass(); 3504 ClassElement cls = constructor.getEnclosingClass();
3504 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) { 3505 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) {
3505 generateAbstractClassInstantiationError(send, cls.name.slowToString()); 3506 generateAbstractClassInstantiationError(send, cls.name.slowToString());
3506 return; 3507 return;
3507 } 3508 }
3508 if (backend.classNeedsRti(cls)) { 3509 if (backend.classNeedsRti(cls)) {
3509 Link<DartType> typeVariable = cls.typeVariables; 3510 Link<DartType> typeVariable = cls.typeVariables;
3510 type.typeArguments.forEach((DartType argument) { 3511 type.typeArguments.forEach((DartType argument) {
3511 inputs.add(analyzeTypeArgument(argument, send)); 3512 inputs.add(analyzeTypeArgument(argument));
3512 typeVariable = typeVariable.tail; 3513 typeVariable = typeVariable.tail;
3513 }); 3514 });
3514 // Also add null to non-provided type variables to call the 3515 // Also add null to non-provided type variables to call the
3515 // constructor with the right number of arguments. 3516 // constructor with the right number of arguments.
3516 while (!typeVariable.isEmpty) { 3517 while (!typeVariable.isEmpty) {
3517 inputs.add(graph.addConstantNull(compiler)); 3518 inputs.add(graph.addConstantNull(compiler));
3518 typeVariable = typeVariable.tail; 3519 typeVariable = typeVariable.tail;
3519 } 3520 }
3520 } 3521 }
3521 3522
(...skipping 1958 matching lines...) Expand 10 before | Expand all | Expand 10 after
5480 new HSubGraphBlockInformation(elseBranch.graph)); 5481 new HSubGraphBlockInformation(elseBranch.graph));
5481 5482
5482 HBasicBlock conditionStartBlock = conditionBranch.block; 5483 HBasicBlock conditionStartBlock = conditionBranch.block;
5483 conditionStartBlock.setBlockFlow(info, joinBlock); 5484 conditionStartBlock.setBlockFlow(info, joinBlock);
5484 SubGraph conditionGraph = conditionBranch.graph; 5485 SubGraph conditionGraph = conditionBranch.graph;
5485 HIf branch = conditionGraph.end.last; 5486 HIf branch = conditionGraph.end.last;
5486 assert(branch is HIf); 5487 assert(branch is HIf);
5487 branch.blockInformation = conditionStartBlock.blockFlow; 5488 branch.blockInformation = conditionStartBlock.blockFlow;
5488 } 5489 }
5489 } 5490 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698