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

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

Issue 12299008: Stop resolving all of js_helper unconditionally. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months 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 /** 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 CodeBuffer boundClosureBuffer; 62 CodeBuffer boundClosureBuffer;
63 CodeBuffer mainBuffer; 63 CodeBuffer mainBuffer;
64 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 64 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
65 well as in the generated code. */ 65 well as in the generated code. */
66 String isolateProperties; 66 String isolateProperties;
67 String classesCollector; 67 String classesCollector;
68 Set<ClassElement> neededClasses; 68 Set<ClassElement> neededClasses;
69 // TODO(ngeoffray): remove this field. 69 // TODO(ngeoffray): remove this field.
70 Set<ClassElement> instantiatedClasses; 70 Set<ClassElement> instantiatedClasses;
71 71
72 JavaScriptBackend get backend => compiler.backend;
73
72 String get _ => compiler.enableMinification ? "" : " "; 74 String get _ => compiler.enableMinification ? "" : " ";
73 String get n => compiler.enableMinification ? "" : "\n"; 75 String get n => compiler.enableMinification ? "" : "\n";
74 String get N => compiler.enableMinification ? "\n" : ";\n"; 76 String get N => compiler.enableMinification ? "\n" : ";\n";
75 77
76 /** 78 /**
77 * A cache of closures that are used to closurize instance methods. 79 * A cache of closures that are used to closurize instance methods.
78 * A closure is dynamically bound to the instance used when 80 * A closure is dynamically bound to the instance used when
79 * closurized. 81 * closurized.
80 */ 82 */
81 final Map<int, String> boundClosureCache; 83 final Map<int, String> boundClosureCache;
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 return js.fun(parameters, [ 635 return js.fun(parameters, [
634 // var getter = new Function("{ return $isolate." + fieldName + ";}"); 636 // var getter = new Function("{ return $isolate." + fieldName + ";}");
635 js['getter'].def(js['Function'].newWith([ 637 js['getter'].def(js['Function'].newWith([
636 js.string("{ return $isolate.") + 'fieldName' + js.string('}')])) 638 js.string("{ return $isolate.") + 'fieldName' + js.string('}')]))
637 ]..addAll(addLazyInitializerLogic()) 639 ]..addAll(addLazyInitializerLogic())
638 ); 640 );
639 } 641 }
640 642
641 List addLazyInitializerLogic() { 643 List addLazyInitializerLogic() {
642 String isolate = namer.CURRENT_ISOLATE; 644 String isolate = namer.CURRENT_ISOLATE;
643 JavaScriptBackend backend = compiler.backend; 645 String cyclicThrow = namer.isolateAccess(backend.getCyclicThrowHelper());
644 String cyclicThrow = namer.isolateAccess(backend.cyclicThrowHelper);
645 646
646 return [ 647 return [
647 // var sentinelUndefined = {}; 648 // var sentinelUndefined = {};
648 js['sentinelUndefined'].def({}), 649 js['sentinelUndefined'].def({}),
649 650
650 // var sentinelInProgress = {}; 651 // var sentinelInProgress = {};
651 js['sentinelInProgress'].def({}), 652 js['sentinelInProgress'].def({}),
652 653
653 // prototype[fieldName] = sentinelUndefined; 654 // prototype[fieldName] = sentinelUndefined;
654 js['prototype'][js['fieldName']].assign('sentinelUndefined'), 655 js['prototype'][js['fieldName']].assign('sentinelUndefined'),
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 // hit the method directly. 771 // hit the method directly.
771 return; 772 return;
772 } 773 }
773 ConstantHandler handler = compiler.constantHandler; 774 ConstantHandler handler = compiler.constantHandler;
774 List<SourceString> names = selector.getOrderedNamedArguments(); 775 List<SourceString> names = selector.getOrderedNamedArguments();
775 776
776 String invocationName = namer.invocationName(selector); 777 String invocationName = namer.invocationName(selector);
777 if (alreadyGenerated.contains(invocationName)) return; 778 if (alreadyGenerated.contains(invocationName)) return;
778 alreadyGenerated.add(invocationName); 779 alreadyGenerated.add(invocationName);
779 780
780 JavaScriptBackend backend = compiler.backend;
781 bool isInterceptorClass = 781 bool isInterceptorClass =
782 backend.isInterceptorClass(member.getEnclosingClass()); 782 backend.isInterceptorClass(member.getEnclosingClass());
783 783
784 // If the method is in an interceptor class, we need to also pass 784 // If the method is in an interceptor class, we need to also pass
785 // the actual receiver. 785 // the actual receiver.
786 int extraArgumentCount = isInterceptorClass ? 1 : 0; 786 int extraArgumentCount = isInterceptorClass ? 1 : 0;
787 // Use '$receiver' to avoid clashes with other parameter names. Using 787 // Use '$receiver' to avoid clashes with other parameter names. Using
788 // '$receiver' works because [:namer.safeName:] used for getting parameter 788 // '$receiver' works because [:namer.safeName:] used for getting parameter
789 // names never returns a name beginning with a single '$'. 789 // names never returns a name beginning with a single '$'.
790 String receiverArgumentName = r'$receiver'; 790 String receiverArgumentName = r'$receiver';
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 */ 1005 */
1006 void addInstanceMember(Element member, ClassBuilder builder) { 1006 void addInstanceMember(Element member, ClassBuilder builder) {
1007 assert(invariant(member, member.isDeclaration)); 1007 assert(invariant(member, member.isDeclaration));
1008 // TODO(floitsch): we don't need to deal with members of 1008 // TODO(floitsch): we don't need to deal with members of
1009 // uninstantiated classes, that have been overwritten by subclasses. 1009 // uninstantiated classes, that have been overwritten by subclasses.
1010 1010
1011 if (member.isFunction() 1011 if (member.isFunction()
1012 || member.isGenerativeConstructorBody() 1012 || member.isGenerativeConstructorBody()
1013 || member.isAccessor()) { 1013 || member.isAccessor()) {
1014 if (member.isAbstract(compiler)) return; 1014 if (member.isAbstract(compiler)) return;
1015 JavaScriptBackend backend = compiler.backend;
1016 jsAst.Expression code = backend.generatedCode[member]; 1015 jsAst.Expression code = backend.generatedCode[member];
1017 if (code == null) return; 1016 if (code == null) return;
1018 builder.addProperty(namer.getName(member), code); 1017 builder.addProperty(namer.getName(member), code);
1019 code = backend.generatedBailoutCode[member]; 1018 code = backend.generatedBailoutCode[member];
1020 if (code != null) { 1019 if (code != null) {
1021 builder.addProperty(namer.getBailoutName(member), code); 1020 builder.addProperty(namer.getBailoutName(member), code);
1022 } 1021 }
1023 FunctionElement function = member; 1022 FunctionElement function = member;
1024 FunctionSignature parameters = function.computeSignature(compiler); 1023 FunctionSignature parameters = function.computeSignature(compiler);
1025 if (!parameters.optionalParameters.isEmpty) { 1024 if (!parameters.optionalParameters.isEmpty) {
1026 addParameterStubs(member, builder.addProperty); 1025 addParameterStubs(member, builder.addProperty);
1027 } 1026 }
1028 } else if (!member.isField()) { 1027 } else if (!member.isField()) {
1029 compiler.internalError('unexpected kind: "${member.kind}"', 1028 compiler.internalError('unexpected kind: "${member.kind}"',
1030 element: member); 1029 element: member);
1031 } 1030 }
1032 emitExtraAccessors(member, builder); 1031 emitExtraAccessors(member, builder);
1033 } 1032 }
1034 1033
1035 /** 1034 /**
1036 * Documentation wanted -- johnniwinther 1035 * Documentation wanted -- johnniwinther
1037 * 1036 *
1038 * Invariant: [classElement] must be a declaration element. 1037 * Invariant: [classElement] must be a declaration element.
1039 */ 1038 */
1040 void emitInstanceMembers(ClassElement classElement, 1039 void emitInstanceMembers(ClassElement classElement,
1041 ClassBuilder builder) { 1040 ClassBuilder builder) {
1042 assert(invariant(classElement, classElement.isDeclaration)); 1041 assert(invariant(classElement, classElement.isDeclaration));
1043 JavaScriptBackend backend = compiler.backend;
1044 if (classElement == backend.objectInterceptorClass) { 1042 if (classElement == backend.objectInterceptorClass) {
1045 emitInterceptorMethods(builder); 1043 emitInterceptorMethods(builder);
1046 // The ObjectInterceptor does not have any instance methods. 1044 // The ObjectInterceptor does not have any instance methods.
1047 return; 1045 return;
1048 } 1046 }
1049 1047
1050 void visitMember(ClassElement enclosing, Element member) { 1048 void visitMember(ClassElement enclosing, Element member) {
1051 assert(invariant(classElement, member.isDeclaration)); 1049 assert(invariant(classElement, member.isDeclaration));
1052 if (member.isInstanceMember()) { 1050 if (member.isInstanceMember()) {
1053 addInstanceMember(member, builder); 1051 addInstanceMember(member, builder);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 const SourceString('=='), 1); 1129 const SourceString('=='), 1);
1132 Function kind = (classElement == backend.jsNullClass) 1130 Function kind = (classElement == backend.jsNullClass)
1133 ? js.equals 1131 ? js.equals
1134 : js.strictEquals; 1132 : js.strictEquals;
1135 builder.addProperty(name, js.fun(['receiver', 'a'], 1133 builder.addProperty(name, js.fun(['receiver', 'a'],
1136 js.block(js.return_(kind(js['receiver'], js['a']))))); 1134 js.block(js.return_(kind(js['receiver'], js['a'])))));
1137 } 1135 }
1138 } 1136 }
1139 1137
1140 void emitRuntimeClassesAndTests(CodeBuffer buffer) { 1138 void emitRuntimeClassesAndTests(CodeBuffer buffer) {
1141 JavaScriptBackend backend = compiler.backend;
1142 RuntimeTypeInformation rti = backend.rti; 1139 RuntimeTypeInformation rti = backend.rti;
1143 TypeChecks typeChecks = rti.getRequiredChecks(); 1140 TypeChecks typeChecks = rti.getRequiredChecks();
1144 1141
1145 bool needsHolder(ClassElement cls) { 1142 bool needsHolder(ClassElement cls) {
1146 return !neededClasses.contains(cls) || cls.isNative() || 1143 return !neededClasses.contains(cls) || cls.isNative() ||
1147 rti.isJsNative(cls); 1144 rti.isJsNative(cls);
1148 } 1145 }
1149 1146
1150 /** 1147 /**
1151 * Generates a holder object if it is needed. A holder is a JavaScript 1148 * Generates a holder object if it is needed. A holder is a JavaScript
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 } 1314 }
1318 1315
1319 void generateCheckedSetter(Element member, 1316 void generateCheckedSetter(Element member,
1320 String fieldName, 1317 String fieldName,
1321 String accessorName, 1318 String accessorName,
1322 ClassBuilder builder) { 1319 ClassBuilder builder) {
1323 assert(canGenerateCheckedSetter(member)); 1320 assert(canGenerateCheckedSetter(member));
1324 DartType type = member.computeType(compiler); 1321 DartType type = member.computeType(compiler);
1325 // TODO(ahe): Generate a dynamic type error here. 1322 // TODO(ahe): Generate a dynamic type error here.
1326 if (type.element.isErroneous()) return; 1323 if (type.element.isErroneous()) return;
1327 SourceString helper = compiler.backend.getCheckedModeHelper(type); 1324 SourceString helper = backend.getCheckedModeHelper(type);
1328 FunctionElement helperElement = compiler.findHelper(helper); 1325 FunctionElement helperElement = compiler.findHelper(helper);
1329 String helperName = namer.isolateAccess(helperElement); 1326 String helperName = namer.isolateAccess(helperElement);
1330 List<jsAst.Expression> arguments = <jsAst.Expression>[js['v']]; 1327 List<jsAst.Expression> arguments = <jsAst.Expression>[js['v']];
1331 if (helperElement.computeSignature(compiler).parameterCount != 1) { 1328 if (helperElement.computeSignature(compiler).parameterCount != 1) {
1332 arguments.add(js.string(namer.operatorIs(type.element))); 1329 arguments.add(js.string(namer.operatorIs(type.element)));
1333 } 1330 }
1334 1331
1335 String setterName = namer.setterNameFromAccessorName(accessorName); 1332 String setterName = namer.setterNameFromAccessorName(accessorName);
1336 builder.addProperty(setterName, 1333 builder.addProperty(setterName,
1337 js.fun(['v'], js['this'][fieldName].assign(js[helperName](arguments)))); 1334 js.fun(['v'], js['this'][fieldName].assign(js[helperName](arguments))));
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 } 1479 }
1483 1480
1484 int _compareSelectorNames(Selector selector1, Selector selector2) { 1481 int _compareSelectorNames(Selector selector1, Selector selector2) {
1485 String name1 = selector1.name.toString(); 1482 String name1 = selector1.name.toString();
1486 String name2 = selector2.name.toString(); 1483 String name2 = selector2.name.toString();
1487 if (name1 != name2) return Comparable.compare(name1, name2); 1484 if (name1 != name2) return Comparable.compare(name1, name2);
1488 return _selectorRank(selector1) - _selectorRank(selector2); 1485 return _selectorRank(selector1) - _selectorRank(selector2);
1489 } 1486 }
1490 1487
1491 void emitInterceptorMethods(ClassBuilder builder) { 1488 void emitInterceptorMethods(ClassBuilder builder) {
1492 JavaScriptBackend backend = compiler.backend;
1493 // Emit forwarders for the ObjectInterceptor class. We need to 1489 // Emit forwarders for the ObjectInterceptor class. We need to
1494 // emit all possible sends on intercepted methods. 1490 // emit all possible sends on intercepted methods.
1495 for (Selector selector in 1491 for (Selector selector in
1496 backend.usedInterceptors.toList()..sort(_compareSelectorNames)) { 1492 backend.usedInterceptors.toList()..sort(_compareSelectorNames)) {
1497 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; 1493 List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
1498 List<jsAst.Expression> arguments = <jsAst.Expression>[]; 1494 List<jsAst.Expression> arguments = <jsAst.Expression>[];
1499 parameters.add(new jsAst.Parameter('receiver')); 1495 parameters.add(new jsAst.Parameter('receiver'));
1500 1496
1501 String name = backend.namer.invocationName(selector); 1497 String name = backend.namer.invocationName(selector);
1502 if (selector.isSetter()) { 1498 if (selector.isSetter()) {
(...skipping 30 matching lines...) Expand all
1533 * substitutions, because they may have changed. 1529 * substitutions, because they may have changed.
1534 */ 1530 */
1535 void generateIsTestsOn(ClassElement cls, 1531 void generateIsTestsOn(ClassElement cls,
1536 void emitIsTest(Element element), 1532 void emitIsTest(Element element),
1537 void emitSubstitution(Element element, {emitNull})) { 1533 void emitSubstitution(Element element, {emitNull})) {
1538 if (checkedClasses.contains(cls)) { 1534 if (checkedClasses.contains(cls)) {
1539 emitIsTest(cls); 1535 emitIsTest(cls);
1540 emitSubstitution(cls); 1536 emitSubstitution(cls);
1541 } 1537 }
1542 1538
1543 JavaScriptBackend jsBackend = compiler.backend; 1539 RuntimeTypeInformation rti = backend.rti;
1544 RuntimeTypeInformation rti = jsBackend.rti;
1545 ClassElement superclass = cls.superclass; 1540 ClassElement superclass = cls.superclass;
1546 1541
1547 bool haveSameTypeVariables(ClassElement a, ClassElement b) { 1542 bool haveSameTypeVariables(ClassElement a, ClassElement b) {
1548 if (a.isClosure()) return true; 1543 if (a.isClosure()) return true;
1549 return a.typeVariables == b.typeVariables; 1544 return a.typeVariables == b.typeVariables;
1550 } 1545 }
1551 1546
1552 if (superclass != null && superclass != compiler.objectClass && 1547 if (superclass != null && superclass != compiler.objectClass &&
1553 !haveSameTypeVariables(cls, superclass)) { 1548 !haveSameTypeVariables(cls, superclass)) {
1554 // We cannot inherit the generated substitutions, because the type 1549 // We cannot inherit the generated substitutions, because the type
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1649 /** 1644 /**
1650 * Return a function that returns true if its argument is a class 1645 * Return a function that returns true if its argument is a class
1651 * that needs to be emitted. 1646 * that needs to be emitted.
1652 */ 1647 */
1653 Function computeClassFilter() { 1648 Function computeClassFilter() {
1654 Set<ClassElement> unneededClasses = new Set<ClassElement>(); 1649 Set<ClassElement> unneededClasses = new Set<ClassElement>();
1655 // The [Bool] class is not marked as abstract, but has a factory 1650 // The [Bool] class is not marked as abstract, but has a factory
1656 // constructor that always throws. We never need to emit it. 1651 // constructor that always throws. We never need to emit it.
1657 unneededClasses.add(compiler.boolClass); 1652 unneededClasses.add(compiler.boolClass);
1658 1653
1659 JavaScriptBackend backend = compiler.backend;
1660
1661 // Go over specialized interceptors and then constants to know which 1654 // Go over specialized interceptors and then constants to know which
1662 // interceptors are needed. 1655 // interceptors are needed.
1663 Set<ClassElement> needed = new Set<ClassElement>(); 1656 Set<ClassElement> needed = new Set<ClassElement>();
1664 backend.specializedGetInterceptors.forEach( 1657 backend.specializedGetInterceptors.forEach(
1665 (_, Collection<ClassElement> elements) { 1658 (_, Collection<ClassElement> elements) {
1666 needed.addAll(elements); 1659 needed.addAll(elements);
1667 } 1660 }
1668 ); 1661 );
1669 1662
1670 ConstantHandler handler = compiler.constantHandler; 1663 ConstantHandler handler = compiler.constantHandler;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 void emitStaticFunction(CodeBuffer buffer, 1734 void emitStaticFunction(CodeBuffer buffer,
1742 String name, 1735 String name,
1743 jsAst.Expression functionExpression) { 1736 jsAst.Expression functionExpression) {
1744 jsAst.Expression assignment = 1737 jsAst.Expression assignment =
1745 js[isolateProperties][name].assign(functionExpression); 1738 js[isolateProperties][name].assign(functionExpression);
1746 buffer.add(jsAst.prettyPrint(assignment, compiler)); 1739 buffer.add(jsAst.prettyPrint(assignment, compiler));
1747 buffer.add('$N$n'); 1740 buffer.add('$N$n');
1748 } 1741 }
1749 1742
1750 void emitStaticFunctions(CodeBuffer buffer) { 1743 void emitStaticFunctions(CodeBuffer buffer) {
1751 JavaScriptBackend backend = compiler.backend;
1752 bool isStaticFunction(Element element) => 1744 bool isStaticFunction(Element element) =>
1753 !element.isInstanceMember() && !element.isField(); 1745 !element.isInstanceMember() && !element.isField();
1754 1746
1755 Iterable<Element> elements = 1747 Iterable<Element> elements =
1756 backend.generatedCode.keys.where(isStaticFunction); 1748 backend.generatedCode.keys.where(isStaticFunction);
1757 Set<Element> pendingElementsWithBailouts = 1749 Set<Element> pendingElementsWithBailouts =
1758 backend.generatedBailoutCode.keys 1750 backend.generatedBailoutCode.keys
1759 .where(isStaticFunction) 1751 .where(isStaticFunction)
1760 .toSet(); 1752 .toSet();
1761 1753
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 // are more difficult to canonicalize because they would need to have the 1844 // are more difficult to canonicalize because they would need to have the
1853 // same default values. 1845 // same default values.
1854 1846
1855 bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0; 1847 bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
1856 int parameterCount = member.parameterCount(compiler); 1848 int parameterCount = member.parameterCount(compiler);
1857 1849
1858 Map<int, String> cache; 1850 Map<int, String> cache;
1859 String extraArg = null; 1851 String extraArg = null;
1860 // Methods on interceptor classes take an extra parameter, which is the 1852 // Methods on interceptor classes take an extra parameter, which is the
1861 // actual receiver of the call. 1853 // actual receiver of the call.
1862 JavaScriptBackend backend = compiler.backend;
1863 bool inInterceptor = backend.isInterceptorClass(member.getEnclosingClass()); 1854 bool inInterceptor = backend.isInterceptorClass(member.getEnclosingClass());
1864 if (inInterceptor) { 1855 if (inInterceptor) {
1865 cache = interceptorClosureCache; 1856 cache = interceptorClosureCache;
1866 extraArg = 'receiver'; 1857 extraArg = 'receiver';
1867 } else { 1858 } else {
1868 cache = boundClosureCache; 1859 cache = boundClosureCache;
1869 } 1860 }
1870 List<String> fieldNames = compiler.enableMinification 1861 List<String> fieldNames = compiler.enableMinification
1871 ? inInterceptor ? const ['a', 'b', 'c'] 1862 ? inInterceptor ? const ['a', 'b', 'c']
1872 : const ['a', 'b'] 1863 : const ['a', 'b']
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 /** 1967 /**
1977 * Documentation wanted -- johnniwinther 1968 * Documentation wanted -- johnniwinther
1978 * 1969 *
1979 * Invariant: [member] must be a declaration element. 1970 * Invariant: [member] must be a declaration element.
1980 */ 1971 */
1981 void emitCallStubForGetter(Element member, 1972 void emitCallStubForGetter(Element member,
1982 Set<Selector> selectors, 1973 Set<Selector> selectors,
1983 DefineStubFunction defineStub) { 1974 DefineStubFunction defineStub) {
1984 assert(invariant(member, member.isDeclaration)); 1975 assert(invariant(member, member.isDeclaration));
1985 LibraryElement memberLibrary = member.getLibrary(); 1976 LibraryElement memberLibrary = member.getLibrary();
1986 JavaScriptBackend backend = compiler.backend;
1987 // If the class is an interceptor class, the stub gets the 1977 // If the class is an interceptor class, the stub gets the
1988 // receiver explicitely and we need to pass it to the getter call. 1978 // receiver explicitely and we need to pass it to the getter call.
1989 bool isInterceptorClass = 1979 bool isInterceptorClass =
1990 backend.isInterceptorClass(member.getEnclosingClass()); 1980 backend.isInterceptorClass(member.getEnclosingClass());
1991 1981
1992 const String receiverArgumentName = r'$receiver'; 1982 const String receiverArgumentName = r'$receiver';
1993 1983
1994 jsAst.Expression buildGetter() { 1984 jsAst.Expression buildGetter() {
1995 if (member.isGetter()) { 1985 if (member.isGetter()) {
1996 String getterName = namer.getterName(member); 1986 String getterName = namer.getterName(member);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 buffer.add(jsAst.prettyPrint(init, compiler)); 2045 buffer.add(jsAst.prettyPrint(init, compiler));
2056 buffer.add('$N'); 2046 buffer.add('$N');
2057 }); 2047 });
2058 } 2048 }
2059 } 2049 }
2060 2050
2061 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { 2051 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
2062 ConstantHandler handler = compiler.constantHandler; 2052 ConstantHandler handler = compiler.constantHandler;
2063 List<VariableElement> lazyFields = 2053 List<VariableElement> lazyFields =
2064 handler.getLazilyInitializedFieldsForEmission(); 2054 handler.getLazilyInitializedFieldsForEmission();
2065 JavaScriptBackend backend = compiler.backend;
2066 if (!lazyFields.isEmpty) { 2055 if (!lazyFields.isEmpty) {
2067 needsLazyInitializer = true; 2056 needsLazyInitializer = true;
2068 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { 2057 for (VariableElement element in Elements.sortedByPosition(lazyFields)) {
2069 assert(backend.generatedBailoutCode[element] == null); 2058 assert(backend.generatedBailoutCode[element] == null);
2070 jsAst.Expression code = backend.generatedCode[element]; 2059 jsAst.Expression code = backend.generatedCode[element];
2071 assert(code != null); 2060 assert(code != null);
2072 // The code only computes the initial value. We build the lazy-check 2061 // The code only computes the initial value. We build the lazy-check
2073 // here: 2062 // here:
2074 // lazyInitializer(prototype, 'name', fieldName, getterName, initial); 2063 // lazyInitializer(prototype, 'name', fieldName, getterName, initial);
2075 // The name is used for error reporting. The 'initial' must be a 2064 // The name is used for error reporting. The 'initial' must be a
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 2370
2382 void emitGetInterceptorMethod(CodeBuffer buffer, 2371 void emitGetInterceptorMethod(CodeBuffer buffer,
2383 String objectName, 2372 String objectName,
2384 String key, 2373 String key,
2385 Collection<ClassElement> classes) { 2374 Collection<ClassElement> classes) {
2386 jsAst.Statement buildReturnInterceptor(ClassElement cls) { 2375 jsAst.Statement buildReturnInterceptor(ClassElement cls) {
2387 return js.return_(js[namer.isolateAccess(cls)]['prototype']); 2376 return js.return_(js[namer.isolateAccess(cls)]['prototype']);
2388 } 2377 }
2389 2378
2390 jsAst.VariableUse receiver = js['receiver']; 2379 jsAst.VariableUse receiver = js['receiver'];
2391 JavaScriptBackend backend = compiler.backend;
2392
2393 /** 2380 /**
2394 * Build a JavaScrit AST node for doing a type check on 2381 * Build a JavaScrit AST node for doing a type check on
2395 * [cls]. [cls] must be an interceptor class. 2382 * [cls]. [cls] must be an interceptor class.
2396 */ 2383 */
2397 jsAst.Statement buildInterceptorCheck(ClassElement cls) { 2384 jsAst.Statement buildInterceptorCheck(ClassElement cls) {
2398 jsAst.Expression condition; 2385 jsAst.Expression condition;
2399 assert(backend.isInterceptorClass(cls)); 2386 assert(backend.isInterceptorClass(cls));
2400 if (cls == backend.jsBoolClass) { 2387 if (cls == backend.jsBoolClass) {
2401 condition = receiver.typeof.equals(js.string('boolean')); 2388 condition = receiver.typeof.equals(js.string('boolean'));
2402 } else if (cls == backend.jsIntClass || 2389 } else if (cls == backend.jsIntClass ||
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 buffer.add(jsAst.prettyPrint( 2482 buffer.add(jsAst.prettyPrint(
2496 js[isolateProperties][key].assign(js.fun(['receiver'], block)), 2483 js[isolateProperties][key].assign(js.fun(['receiver'], block)),
2497 compiler)); 2484 compiler));
2498 buffer.add(N); 2485 buffer.add(N);
2499 } 2486 }
2500 2487
2501 /** 2488 /**
2502 * Emit all versions of the [:getInterceptor:] method. 2489 * Emit all versions of the [:getInterceptor:] method.
2503 */ 2490 */
2504 void emitGetInterceptorMethods(CodeBuffer buffer) { 2491 void emitGetInterceptorMethods(CodeBuffer buffer) {
2505 JavaScriptBackend backend = compiler.backend;
2506 // If no class needs to be intercepted, just return. 2492 // If no class needs to be intercepted, just return.
2507 if (backend.objectInterceptorClass == null) return; 2493 if (backend.objectInterceptorClass == null) return;
2508 String objectName = namer.isolateAccess(backend.objectInterceptorClass); 2494 String objectName = namer.isolateAccess(backend.objectInterceptorClass);
2509 var specializedGetInterceptors = backend.specializedGetInterceptors; 2495 var specializedGetInterceptors = backend.specializedGetInterceptors;
2510 for (String name in specializedGetInterceptors.keys.toList()..sort()) { 2496 for (String name in specializedGetInterceptors.keys.toList()..sort()) {
2511 Collection<ClassElement> classes = specializedGetInterceptors[name]; 2497 Collection<ClassElement> classes = specializedGetInterceptors[name];
2512 emitGetInterceptorMethod(buffer, objectName, name, classes); 2498 emitGetInterceptorMethod(buffer, objectName, name, classes);
2513 } 2499 }
2514 } 2500 }
2515 2501
2516 void computeNeededClasses() { 2502 void computeNeededClasses() {
2517 instantiatedClasses = 2503 instantiatedClasses =
2518 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter()) 2504 compiler.codegenWorld.instantiatedClasses.where(computeClassFilter())
2519 .toSet(); 2505 .toSet();
2520 neededClasses = new Set<ClassElement>.from(instantiatedClasses); 2506 neededClasses = new Set<ClassElement>.from(instantiatedClasses);
2521 for (ClassElement element in instantiatedClasses) { 2507 for (ClassElement element in instantiatedClasses) {
2522 for (ClassElement superclass = element.superclass; 2508 for (ClassElement superclass = element.superclass;
2523 superclass != null; 2509 superclass != null;
2524 superclass = superclass.superclass) { 2510 superclass = superclass.superclass) {
2525 if (neededClasses.contains(superclass)) break; 2511 if (neededClasses.contains(superclass)) break;
2526 neededClasses.add(superclass); 2512 neededClasses.add(superclass);
2527 } 2513 }
2528 } 2514 }
2529 } 2515 }
2530 2516
2531 int _compareSelectors(Selector selector1, Selector selector2) { 2517 int _compareSelectors(Selector selector1, Selector selector2) {
2532 int comparison = _compareSelectorNames(selector1, selector2); 2518 int comparison = _compareSelectorNames(selector1, selector2);
2533 if (comparison != 0) return comparison; 2519 if (comparison != 0) return comparison;
2534 2520
2535 JavaScriptBackend backend = compiler.backend;
2536 Set<ClassElement> classes1 = backend.getInterceptedClassesOn(selector1); 2521 Set<ClassElement> classes1 = backend.getInterceptedClassesOn(selector1);
2537 Set<ClassElement> classes2 = backend.getInterceptedClassesOn(selector2); 2522 Set<ClassElement> classes2 = backend.getInterceptedClassesOn(selector2);
2538 if (classes1.length != classes2.length) { 2523 if (classes1.length != classes2.length) {
2539 return classes1.length - classes2.length; 2524 return classes1.length - classes2.length;
2540 } 2525 }
2541 String getInterceptor1 = 2526 String getInterceptor1 =
2542 namer.getInterceptorName(backend.getInterceptorMethod, classes1); 2527 namer.getInterceptorName(backend.getInterceptorMethod, classes1);
2543 String getInterceptor2 = 2528 String getInterceptor2 =
2544 namer.getInterceptorName(backend.getInterceptorMethod, classes2); 2529 namer.getInterceptorName(backend.getInterceptorMethod, classes2);
2545 return Comparable.compare(getInterceptor1, getInterceptor2); 2530 return Comparable.compare(getInterceptor1, getInterceptor2);
2546 } 2531 }
2547 2532
2548 void emitOneShotInterceptors(CodeBuffer buffer) { 2533 void emitOneShotInterceptors(CodeBuffer buffer) {
2549 JavaScriptBackend backend = compiler.backend;
2550 for (Selector selector in 2534 for (Selector selector in
2551 backend.oneShotInterceptors.toList()..sort(_compareSelectors)) { 2535 backend.oneShotInterceptors.toList()..sort(_compareSelectors)) {
2552 Set<ClassElement> classes = backend.getInterceptedClassesOn(selector); 2536 Set<ClassElement> classes = backend.getInterceptedClassesOn(selector);
2553 String oneShotInterceptorName = namer.oneShotInterceptorName(selector); 2537 String oneShotInterceptorName = namer.oneShotInterceptorName(selector);
2554 String getInterceptorName = 2538 String getInterceptorName =
2555 namer.getInterceptorName(backend.getInterceptorMethod, classes); 2539 namer.getInterceptorName(backend.getInterceptorMethod, classes);
2556 2540
2557 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; 2541 List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
2558 List<jsAst.Expression> arguments = <jsAst.Expression>[]; 2542 List<jsAst.Expression> arguments = <jsAst.Expression>[];
2559 parameters.add(new jsAst.Parameter('receiver')); 2543 parameters.add(new jsAst.Parameter('receiver'));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 """; 2656 """;
2673 const String HOOKS_API_USAGE = """ 2657 const String HOOKS_API_USAGE = """
2674 // The code supports the following hooks: 2658 // The code supports the following hooks:
2675 // dartPrint(message) - if this function is defined it is called 2659 // dartPrint(message) - if this function is defined it is called
2676 // instead of the Dart [print] method. 2660 // instead of the Dart [print] method.
2677 // dartMainRunner(main) - if this function is defined, the Dart [main] 2661 // dartMainRunner(main) - if this function is defined, the Dart [main]
2678 // method will not be invoked directly. 2662 // method will not be invoked directly.
2679 // Instead, a closure that will invoke [main] is 2663 // Instead, a closure that will invoke [main] is
2680 // passed to [dartMainRunner]. 2664 // passed to [dartMainRunner].
2681 """; 2665 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698