OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |