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 |