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 /** | 7 /** |
8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
9 * from the given element. | 9 * from the given element. |
10 */ | 10 */ |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // If the method is in an interceptor class, we need to also pass | 477 // If the method is in an interceptor class, we need to also pass |
478 // the actual receiver. | 478 // the actual receiver. |
479 int extraArgumentCount = isInterceptorClass ? 1 : 0; | 479 int extraArgumentCount = isInterceptorClass ? 1 : 0; |
480 // Use '$receiver' to avoid clashes with other parameter names. Using | 480 // Use '$receiver' to avoid clashes with other parameter names. Using |
481 // '$receiver' works because [JsNames.getValid] used for getting parameter | 481 // '$receiver' works because [JsNames.getValid] used for getting parameter |
482 // names never returns a name beginning with a single '$'. | 482 // names never returns a name beginning with a single '$'. |
483 String receiverArgumentName = r'$receiver'; | 483 String receiverArgumentName = r'$receiver'; |
484 | 484 |
485 // The parameters that this stub takes. | 485 // The parameters that this stub takes. |
486 List<js.Parameter> parametersBuffer = | 486 List<js.Parameter> parametersBuffer = |
487 new List<js.Parameter>(selector.argumentCount + extraArgumentCount); | 487 new List<js.Parameter>.fixedLength( |
| 488 selector.argumentCount + extraArgumentCount); |
488 // The arguments that will be passed to the real method. | 489 // The arguments that will be passed to the real method. |
489 List<js.Expression> argumentsBuffer = | 490 List<js.Expression> argumentsBuffer = |
490 new List<js.Expression>(parameters.parameterCount + extraArgumentCount); | 491 new List<js.Expression>.fixedLength( |
| 492 parameters.parameterCount + extraArgumentCount); |
491 | 493 |
492 int count = 0; | 494 int count = 0; |
493 if (isInterceptorClass) { | 495 if (isInterceptorClass) { |
494 count++; | 496 count++; |
495 parametersBuffer[0] = new js.Parameter(receiverArgumentName); | 497 parametersBuffer[0] = new js.Parameter(receiverArgumentName); |
496 argumentsBuffer[0] = new js.VariableUse(receiverArgumentName); | 498 argumentsBuffer[0] = new js.VariableUse(receiverArgumentName); |
497 } | 499 } |
498 | 500 |
499 int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1; | 501 int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1; |
500 TreeElements elements = | 502 TreeElements elements = |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 new js.Block( | 1102 new js.Block( |
1101 <js.Statement>[ | 1103 <js.Statement>[ |
1102 new js.Return( | 1104 new js.Return( |
1103 new js.VariableUse('receiver') | 1105 new js.VariableUse('receiver') |
1104 .dot(name) | 1106 .dot(name) |
1105 .callWith(arguments))])); | 1107 .callWith(arguments))])); |
1106 builder.addProperty(name, function); | 1108 builder.addProperty(name, function); |
1107 } | 1109 } |
1108 } | 1110 } |
1109 | 1111 |
1110 Collection<Element> getTypedefChecksOn(DartType type) { | 1112 Iterable<Element> getTypedefChecksOn(DartType type) { |
1111 return checkedTypedefs.filter((TypedefElement typedef) { | 1113 return checkedTypedefs.where((TypedefElement typedef) { |
1112 FunctionType typedefType = | 1114 FunctionType typedefType = |
1113 typedef.computeType(compiler).unalias(compiler); | 1115 typedef.computeType(compiler).unalias(compiler); |
1114 return compiler.types.isSubtype(type, typedefType); | 1116 return compiler.types.isSubtype(type, typedefType); |
1115 }); | 1117 }); |
1116 } | 1118 } |
1117 | 1119 |
1118 /** | 1120 /** |
1119 * Generate "is tests" for [cls]: itself, and the "is tests" for the | 1121 * Generate "is tests" for [cls]: itself, and the "is tests" for the |
1120 * classes it implements. We don't need to add the "is tests" of the | 1122 * classes it implements. We don't need to add the "is tests" of the |
1121 * super class because they will be inherited at runtime. | 1123 * super class because they will be inherited at runtime. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 js.Expression assignment = | 1277 js.Expression assignment = |
1276 js.assign(js.use(isolateProperties).dot(name), functionExpression); | 1278 js.assign(js.use(isolateProperties).dot(name), functionExpression); |
1277 buffer.add(js.prettyPrint(assignment, compiler)); | 1279 buffer.add(js.prettyPrint(assignment, compiler)); |
1278 buffer.add('$N$n'); | 1280 buffer.add('$N$n'); |
1279 } | 1281 } |
1280 | 1282 |
1281 void emitStaticFunctions(CodeBuffer buffer) { | 1283 void emitStaticFunctions(CodeBuffer buffer) { |
1282 bool isStaticFunction(Element element) => | 1284 bool isStaticFunction(Element element) => |
1283 !element.isInstanceMember() && !element.isField(); | 1285 !element.isInstanceMember() && !element.isField(); |
1284 | 1286 |
1285 Collection<Element> elements = | 1287 Iterable<Element> elements = |
1286 compiler.codegenWorld.generatedCode.keys.filter(isStaticFunction); | 1288 compiler.codegenWorld.generatedCode.keys.where(isStaticFunction); |
1287 Set<Element> pendingElementsWithBailouts = | 1289 Set<Element> pendingElementsWithBailouts = |
1288 new Set<Element>.from( | 1290 compiler.codegenWorld.generatedBailoutCode.keys |
1289 compiler.codegenWorld.generatedBailoutCode.keys.filter( | 1291 .where(isStaticFunction) |
1290 isStaticFunction)); | 1292 .toSet(); |
1291 | 1293 |
1292 for (Element element in Elements.sortedByPosition(elements)) { | 1294 for (Element element in Elements.sortedByPosition(elements)) { |
1293 js.Expression code = compiler.codegenWorld.generatedCode[element]; | 1295 js.Expression code = compiler.codegenWorld.generatedCode[element]; |
1294 emitStaticFunction(buffer, namer.getName(element), code); | 1296 emitStaticFunction(buffer, namer.getName(element), code); |
1295 js.Expression bailoutCode = | 1297 js.Expression bailoutCode = |
1296 compiler.codegenWorld.generatedBailoutCode[element]; | 1298 compiler.codegenWorld.generatedBailoutCode[element]; |
1297 if (bailoutCode != null) { | 1299 if (bailoutCode != null) { |
1298 pendingElementsWithBailouts.remove(element); | 1300 pendingElementsWithBailouts.remove(element); |
1299 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); | 1301 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); |
1300 } | 1302 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 buildGetter().dot(closureCallName) | 1571 buildGetter().dot(closureCallName) |
1570 .callWith(arguments))])); | 1572 .callWith(arguments))])); |
1571 | 1573 |
1572 defineStub(invocationName, function); | 1574 defineStub(invocationName, function); |
1573 } | 1575 } |
1574 } | 1576 } |
1575 } | 1577 } |
1576 | 1578 |
1577 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 1579 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
1578 ConstantHandler handler = compiler.constantHandler; | 1580 ConstantHandler handler = compiler.constantHandler; |
1579 List<VariableElement> staticNonFinalFields = | 1581 Iterable<VariableElement> staticNonFinalFields = |
1580 handler.getStaticNonFinalFieldsForEmission(); | 1582 handler.getStaticNonFinalFieldsForEmission(); |
1581 for (Element element in staticNonFinalFields) { | 1583 for (Element element in staticNonFinalFields) { |
1582 compiler.withCurrentElement(element, () { | 1584 compiler.withCurrentElement(element, () { |
1583 Constant initialValue = handler.getInitialValueFor(element); | 1585 Constant initialValue = handler.getInitialValueFor(element); |
1584 js.Expression init = | 1586 js.Expression init = |
1585 new js.Assignment( | 1587 new js.Assignment( |
1586 new js.PropertyAccess.field( | 1588 new js.PropertyAccess.field( |
1587 new js.VariableUse(isolateProperties), | 1589 new js.VariableUse(isolateProperties), |
1588 namer.getName(element)), | 1590 namer.getName(element)), |
1589 constantEmitter.referenceInInitializationContext(initialValue)); | 1591 constantEmitter.referenceInInitializationContext(initialValue)); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 // Values match JSInvocationMirror in js-helper library. | 1727 // Values match JSInvocationMirror in js-helper library. |
1726 int type = selector.invocationMirrorKind; | 1728 int type = selector.invocationMirrorKind; |
1727 String methodName = selector.invocationMirrorMemberName; | 1729 String methodName = selector.invocationMirrorMemberName; |
1728 List<js.Parameter> parameters = <js.Parameter>[]; | 1730 List<js.Parameter> parameters = <js.Parameter>[]; |
1729 CodeBuffer args = new CodeBuffer(); | 1731 CodeBuffer args = new CodeBuffer(); |
1730 for (int i = 0; i < selector.argumentCount; i++) { | 1732 for (int i = 0; i < selector.argumentCount; i++) { |
1731 parameters.add(new js.Parameter('\$$i')); | 1733 parameters.add(new js.Parameter('\$$i')); |
1732 } | 1734 } |
1733 | 1735 |
1734 List<js.Expression> argNames = | 1736 List<js.Expression> argNames = |
1735 selector.getOrderedNamedArguments().map((SourceString name) => | 1737 selector.getOrderedNamedArguments().mappedBy((SourceString name) => |
1736 js.string(name.slowToString())); | 1738 js.string(name.slowToString())).toList(); |
1737 | 1739 |
1738 String internalName = namer.invocationMirrorInternalName(selector); | 1740 String internalName = namer.invocationMirrorInternalName(selector); |
1739 | 1741 |
1740 String createInvocationMirror = namer.getName( | 1742 String createInvocationMirror = namer.getName( |
1741 compiler.createInvocationMirrorElement); | 1743 compiler.createInvocationMirrorElement); |
1742 | 1744 |
1743 js.Expression expression = | 1745 js.Expression expression = |
1744 new js.This() | 1746 new js.This() |
1745 .dot(noSuchMethodName) | 1747 .dot(noSuchMethodName) |
1746 .callWith( | 1748 .callWith( |
1747 <js.Expression>[ | 1749 <js.Expression>[ |
1748 new js.VariableUse(namer.CURRENT_ISOLATE) | 1750 new js.VariableUse(namer.CURRENT_ISOLATE) |
1749 .dot(createInvocationMirror) | 1751 .dot(createInvocationMirror) |
1750 .callWith( | 1752 .callWith( |
1751 <js.Expression>[ | 1753 <js.Expression>[ |
1752 js.string(methodName), | 1754 js.string(methodName), |
1753 js.string(internalName), | 1755 js.string(internalName), |
1754 new js.LiteralNumber('$type'), | 1756 new js.LiteralNumber('$type'), |
1755 new js.ArrayInitializer.from( | 1757 new js.ArrayInitializer.from( |
1756 parameters.map((param) => js.use(param.name))), | 1758 parameters.mappedBy((param) => js.use(param.name))
.toList()), |
1757 new js.ArrayInitializer.from(argNames)])]); | 1759 new js.ArrayInitializer.from(argNames)])]); |
1758 js.Expression function = | 1760 js.Expression function = |
1759 new js.Fun(parameters, | 1761 new js.Fun(parameters, |
1760 new js.Block(<js.Statement>[new js.Return(expression)])); | 1762 new js.Block(<js.Statement>[new js.Return(expression)])); |
1761 return function; | 1763 return function; |
1762 } | 1764 } |
1763 | 1765 |
1764 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 1766 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
1765 // Cache the object class and type. | 1767 // Cache the object class and type. |
1766 ClassElement objectClass = compiler.objectClass; | 1768 ClassElement objectClass = compiler.objectClass; |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 if (backend.objectInterceptorClass == null) return; | 2082 if (backend.objectInterceptorClass == null) return; |
2081 String objectName = namer.isolateAccess(backend.objectInterceptorClass); | 2083 String objectName = namer.isolateAccess(backend.objectInterceptorClass); |
2082 backend.specializedGetInterceptors.forEach( | 2084 backend.specializedGetInterceptors.forEach( |
2083 (String key, Collection<ClassElement> classes) { | 2085 (String key, Collection<ClassElement> classes) { |
2084 emitGetInterceptorMethod(buffer, objectName, key, classes); | 2086 emitGetInterceptorMethod(buffer, objectName, key, classes); |
2085 }); | 2087 }); |
2086 } | 2088 } |
2087 | 2089 |
2088 void computeNeededClasses() { | 2090 void computeNeededClasses() { |
2089 instantiatedClasses = | 2091 instantiatedClasses = |
2090 compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter()); | 2092 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()); |
2091 neededClasses = new Set<ClassElement>.from(instantiatedClasses); | 2093 neededClasses = instantiatedClasses.toSet(); |
2092 for (ClassElement element in instantiatedClasses) { | 2094 for (ClassElement element in instantiatedClasses) { |
2093 for (ClassElement superclass = element.superclass; | 2095 for (ClassElement superclass = element.superclass; |
2094 superclass != null; | 2096 superclass != null; |
2095 superclass = superclass.superclass) { | 2097 superclass = superclass.superclass) { |
2096 if (neededClasses.contains(superclass)) break; | 2098 if (neededClasses.contains(superclass)) break; |
2097 neededClasses.add(superclass); | 2099 neededClasses.add(superclass); |
2098 } | 2100 } |
2099 } | 2101 } |
2100 } | 2102 } |
2101 | 2103 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2180 """; | 2182 """; |
2181 const String HOOKS_API_USAGE = """ | 2183 const String HOOKS_API_USAGE = """ |
2182 // The code supports the following hooks: | 2184 // The code supports the following hooks: |
2183 // dartPrint(message) - if this function is defined it is called | 2185 // dartPrint(message) - if this function is defined it is called |
2184 // instead of the Dart [print] method. | 2186 // instead of the Dart [print] method. |
2185 // dartMainRunner(main) - if this function is defined, the Dart [main] | 2187 // dartMainRunner(main) - if this function is defined, the Dart [main] |
2186 // method will not be invoked directly. | 2188 // method will not be invoked directly. |
2187 // Instead, a closure that will invoke [main] is | 2189 // Instead, a closure that will invoke [main] is |
2188 // passed to [dartMainRunner]. | 2190 // passed to [dartMainRunner]. |
2189 """; | 2191 """; |
OLD | NEW |