| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
| 8 | 8 |
| 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 Element element = type.element; | 82 Element element = type.element; |
| 83 String isField = codegen.backend.namer.operatorIs(element); | 83 String isField = codegen.backend.namer.operatorIs(element); |
| 84 arguments.add(js.string(isField)); | 84 arguments.add(js.string(isField)); |
| 85 codegen.use(node.typeRepresentation); | 85 codegen.use(node.typeRepresentation); |
| 86 arguments.add(codegen.pop()); | 86 arguments.add(codegen.pop()); |
| 87 String asField = codegen.backend.namer.substitutionName(element); | 87 String asField = codegen.backend.namer.substitutionName(element); |
| 88 arguments.add(js.string(asField)); | 88 arguments.add(js.string(asField)); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| 92 class FunctionTypeCheckedModeHelper extends CheckedModeHelper { | |
| 93 const FunctionTypeCheckedModeHelper(String name) : super(name); | |
| 94 | |
| 95 void generateAdditionalArguments(SsaCodeGenerator codegen, | |
| 96 HTypeConversion node, | |
| 97 List<jsAst.Expression> arguments) { | |
| 98 DartType type = node.typeExpression; | |
| 99 String signatureName = codegen.backend.namer.getFunctionTypeName(type); | |
| 100 arguments.add(js.string(signatureName)); | |
| 101 | |
| 102 if (type.containsTypeVariables) { | |
| 103 ClassElement contextClass = Types.getClassContext(type); | |
| 104 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to | |
| 105 // string concatenation in the implementation), and may prevent | |
| 106 // segmentation of '$'. | |
| 107 String contextName = codegen.backend.namer.getNameForRti(contextClass); | |
| 108 arguments.add(js.string(contextName)); | |
| 109 | |
| 110 if (node.contextIsTypeArguments) { | |
| 111 arguments.add(new jsAst.LiteralNull()); | |
| 112 codegen.use(node.context); | |
| 113 arguments.add(codegen.pop()); | |
| 114 } else { | |
| 115 codegen.use(node.context); | |
| 116 arguments.add(codegen.pop()); | |
| 117 } | |
| 118 } | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 /* | 92 /* |
| 123 * Invariants: | 93 * Invariants: |
| 124 * canInline(function) implies canInline(function, insideLoop:true) | 94 * canInline(function) implies canInline(function, insideLoop:true) |
| 125 * !canInline(function, insideLoop: true) implies !canInline(function) | 95 * !canInline(function, insideLoop: true) implies !canInline(function) |
| 126 */ | 96 */ |
| 127 class FunctionInlineCache { | 97 class FunctionInlineCache { |
| 128 final Map<FunctionElement, bool> canBeInlined = | 98 final Map<FunctionElement, bool> canBeInlined = |
| 129 new Map<FunctionElement, bool>(); | 99 new Map<FunctionElement, bool>(); |
| 130 | 100 |
| 131 final Map<FunctionElement, bool> canBeInlinedInsideLoop = | 101 final Map<FunctionElement, bool> canBeInlinedInsideLoop = |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 const PropertyCheckedModeHelper('listSuperNativeTypeCast'), | 360 const PropertyCheckedModeHelper('listSuperNativeTypeCast'), |
| 391 const PropertyCheckedModeHelper('listSuperNativeTypeCheck'), | 361 const PropertyCheckedModeHelper('listSuperNativeTypeCheck'), |
| 392 const PropertyCheckedModeHelper('listSuperTypeCast'), | 362 const PropertyCheckedModeHelper('listSuperTypeCast'), |
| 393 const PropertyCheckedModeHelper('listSuperTypeCheck'), | 363 const PropertyCheckedModeHelper('listSuperTypeCheck'), |
| 394 const PropertyCheckedModeHelper('interceptedTypeCast'), | 364 const PropertyCheckedModeHelper('interceptedTypeCast'), |
| 395 const PropertyCheckedModeHelper('interceptedTypeCheck'), | 365 const PropertyCheckedModeHelper('interceptedTypeCheck'), |
| 396 const SubtypeCheckedModeHelper('subtypeCast'), | 366 const SubtypeCheckedModeHelper('subtypeCast'), |
| 397 const SubtypeCheckedModeHelper('assertSubtype'), | 367 const SubtypeCheckedModeHelper('assertSubtype'), |
| 398 const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'), | 368 const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'), |
| 399 const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'), | 369 const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'), |
| 400 const FunctionTypeCheckedModeHelper('functionSubtypeCast'), | |
| 401 const FunctionTypeCheckedModeHelper('assertFunctionSubtype'), | |
| 402 const PropertyCheckedModeHelper('propertyTypeCast'), | 370 const PropertyCheckedModeHelper('propertyTypeCast'), |
| 403 const PropertyCheckedModeHelper('propertyTypeCheck') ]; | 371 const PropertyCheckedModeHelper('propertyTypeCheck') ]; |
| 404 | 372 |
| 405 // Checked mode helpers indexed by name. | 373 // Checked mode helpers indexed by name. |
| 406 Map<String, CheckedModeHelper> checkedModeHelperByName = | 374 Map<String, CheckedModeHelper> checkedModeHelperByName = |
| 407 new Map<String, CheckedModeHelper>.fromIterable( | 375 new Map<String, CheckedModeHelper>.fromIterable( |
| 408 checkedModeHelpers, | 376 checkedModeHelpers, |
| 409 key: (helper) => helper.name); | 377 key: (helper) => helper.name); |
| 410 | 378 |
| 411 TypeVariableHandler typeVariableHandler; | 379 TypeVariableHandler typeVariableHandler; |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 enqueueInResolution(getCheckSubtype(), elements); | 1027 enqueueInResolution(getCheckSubtype(), elements); |
| 1060 if (isTypeVariable) { | 1028 if (isTypeVariable) { |
| 1061 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); | 1029 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); |
| 1062 if (inCheckedMode) { | 1030 if (inCheckedMode) { |
| 1063 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 1031 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
| 1064 } | 1032 } |
| 1065 } | 1033 } |
| 1066 enqueueClass(world, compiler.listClass, elements); | 1034 enqueueClass(world, compiler.listClass, elements); |
| 1067 } | 1035 } |
| 1068 if (type is FunctionType) { | 1036 if (type is FunctionType) { |
| 1069 enqueueInResolution(getCheckFunctionSubtype(), elements); | 1037 enqueueInResolution( |
| 1038 compiler.findHelper('functionTypeTestMetaHelper'), elements); |
| 1070 } | 1039 } |
| 1071 if (type.element.isNative()) { | 1040 if (type.element.isNative()) { |
| 1072 // We will neeed to add the "$is" and "$as" properties on the | 1041 // We will neeed to add the "$is" and "$as" properties on the |
| 1073 // JavaScript object prototype, so we make sure | 1042 // JavaScript object prototype, so we make sure |
| 1074 // [:defineProperty:] is compiled. | 1043 // [:defineProperty:] is compiled. |
| 1075 enqueue(world, | 1044 enqueue(world, |
| 1076 compiler.findHelper('defineProperty'), | 1045 compiler.findHelper('defineProperty'), |
| 1077 elements); | 1046 elements); |
| 1078 } | 1047 } |
| 1079 } | 1048 } |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 } else { | 1446 } else { |
| 1478 if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) { | 1447 if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) { |
| 1479 return typeCast | 1448 return typeCast |
| 1480 ? 'subtypeCast' | 1449 ? 'subtypeCast' |
| 1481 : 'assertSubtype'; | 1450 : 'assertSubtype'; |
| 1482 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1451 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 1483 return typeCast | 1452 return typeCast |
| 1484 ? 'subtypeOfRuntimeTypeCast' | 1453 ? 'subtypeOfRuntimeTypeCast' |
| 1485 : 'assertSubtypeOfRuntimeType'; | 1454 : 'assertSubtypeOfRuntimeType'; |
| 1486 } else if (type.kind == TypeKind.FUNCTION) { | 1455 } else if (type.kind == TypeKind.FUNCTION) { |
| 1487 return typeCast | 1456 return null; |
| 1488 ? 'functionSubtypeCast' | |
| 1489 : 'assertFunctionSubtype'; | |
| 1490 } else { | 1457 } else { |
| 1491 if (nativeCheck) { | 1458 if (nativeCheck) { |
| 1492 // TODO(karlklose): can we get rid of this branch when we use | 1459 // TODO(karlklose): can we get rid of this branch when we use |
| 1493 // interceptors? | 1460 // interceptors? |
| 1494 return typeCast | 1461 return typeCast |
| 1495 ? 'interceptedTypeCast' | 1462 ? 'interceptedTypeCast' |
| 1496 : 'interceptedTypeCheck'; | 1463 : 'interceptedTypeCheck'; |
| 1497 } else { | 1464 } else { |
| 1498 return typeCast | 1465 return typeCast |
| 1499 ? 'propertyTypeCast' | 1466 ? 'propertyTypeCast' |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 } | 1581 } |
| 1615 | 1582 |
| 1616 Element getCheckSubtypeOfRuntimeType() { | 1583 Element getCheckSubtypeOfRuntimeType() { |
| 1617 return compiler.findHelper('checkSubtypeOfRuntimeType'); | 1584 return compiler.findHelper('checkSubtypeOfRuntimeType'); |
| 1618 } | 1585 } |
| 1619 | 1586 |
| 1620 Element getAssertSubtypeOfRuntimeType() { | 1587 Element getAssertSubtypeOfRuntimeType() { |
| 1621 return compiler.findHelper('assertSubtypeOfRuntimeType'); | 1588 return compiler.findHelper('assertSubtypeOfRuntimeType'); |
| 1622 } | 1589 } |
| 1623 | 1590 |
| 1624 Element getCheckFunctionSubtype() { | |
| 1625 return compiler.findHelper('checkFunctionSubtype'); | |
| 1626 } | |
| 1627 | |
| 1628 Element getThrowNoSuchMethod() { | 1591 Element getThrowNoSuchMethod() { |
| 1629 return compiler.findHelper('throwNoSuchMethod'); | 1592 return compiler.findHelper('throwNoSuchMethod'); |
| 1630 } | 1593 } |
| 1631 | 1594 |
| 1632 Element getCreateRuntimeType() { | 1595 Element getCreateRuntimeType() { |
| 1633 return compiler.findHelper('createRuntimeType'); | 1596 return compiler.findHelper('createRuntimeType'); |
| 1634 } | 1597 } |
| 1635 | 1598 |
| 1636 Element getFallThroughError() { | 1599 Element getFallThroughError() { |
| 1637 return compiler.findHelper("getFallThroughError"); | 1600 return compiler.findHelper("getFallThroughError"); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1996 copy(constant.values); | 1959 copy(constant.values); |
| 1997 copy(constant.protoValue); | 1960 copy(constant.protoValue); |
| 1998 copy(constant); | 1961 copy(constant); |
| 1999 } | 1962 } |
| 2000 | 1963 |
| 2001 void visitConstructed(ConstructedConstant constant) { | 1964 void visitConstructed(ConstructedConstant constant) { |
| 2002 copy(constant.fields); | 1965 copy(constant.fields); |
| 2003 copy(constant); | 1966 copy(constant); |
| 2004 } | 1967 } |
| 2005 } | 1968 } |
| OLD | NEW |