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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 50313007: Implement dynamic function checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r30897. Created 7 years 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 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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698