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

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

Issue 12473003: Remove deprecated StringBuffer.add, addAll and addCharCode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 : mainBuffer = new CodeBuffer(), 128 : mainBuffer = new CodeBuffer(),
129 this.namer = namer, 129 this.namer = namer,
130 boundClosureCache = new Map<int, String>(), 130 boundClosureCache = new Map<int, String>(),
131 interceptorClosureCache = new Map<int, String>(), 131 interceptorClosureCache = new Map<int, String>(),
132 constantEmitter = new ConstantEmitter(compiler, namer), 132 constantEmitter = new ConstantEmitter(compiler, namer),
133 super(compiler) { 133 super(compiler) {
134 nativeEmitter = new NativeEmitter(this); 134 nativeEmitter = new NativeEmitter(this);
135 } 135 }
136 136
137 void addComment(String comment, CodeBuffer buffer) { 137 void addComment(String comment, CodeBuffer buffer) {
138 buffer.add(jsAst.prettyPrint(js.comment(comment), compiler)); 138 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler));
139 } 139 }
140 140
141 void computeRequiredTypeChecks() { 141 void computeRequiredTypeChecks() {
142 assert(checkedClasses == null && checkedTypedefs == null); 142 assert(checkedClasses == null && checkedTypedefs == null);
143 143
144 compiler.codegenWorld.addImplicitChecks(classesUsingTypeVariableTests); 144 compiler.codegenWorld.addImplicitChecks(classesUsingTypeVariableTests);
145 145
146 checkedClasses = new Set<ClassElement>(); 146 checkedClasses = new Set<ClassElement>();
147 checkedTypedefs = new Set<TypedefElement>(); 147 checkedTypedefs = new Set<TypedefElement>();
148 compiler.codegenWorld.isChecks.forEach((DartType t) { 148 compiler.codegenWorld.isChecks.forEach((DartType t) {
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 611
612 List buildFinishIsolateConstructor() { 612 List buildFinishIsolateConstructor() {
613 return [ 613 return [
614 // $finishIsolateConstructorName = $finishIsolateConstructorFunction 614 // $finishIsolateConstructorName = $finishIsolateConstructorFunction
615 js[finishIsolateConstructorName].assign(finishIsolateConstructorFunction) 615 js[finishIsolateConstructorName].assign(finishIsolateConstructorFunction)
616 ]; 616 ];
617 } 617 }
618 618
619 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { 619 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
620 String isolate = namer.isolateName; 620 String isolate = namer.isolateName;
621 buffer.add("$isolate = $finishIsolateConstructorName($isolate)$N"); 621 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
622 } 622 }
623 623
624 /** 624 /**
625 * Generate stubs to handle invocation of methods with optional 625 * Generate stubs to handle invocation of methods with optional
626 * arguments. 626 * arguments.
627 * 627 *
628 * A method like [: foo([x]) :] may be invoked by the following 628 * A method like [: foo([x]) :] may be invoked by the following
629 * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this 629 * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this
630 * function for detailed examples. 630 * function for detailed examples.
631 */ 631 */
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 /** 1018 /**
1019 * Generates a holder object if it is needed. A holder is a JavaScript 1019 * Generates a holder object if it is needed. A holder is a JavaScript
1020 * object literal with a field [builtin$cls] that contains the name of the 1020 * object literal with a field [builtin$cls] that contains the name of the
1021 * class as a string (just like object constructors do). The is-checks for 1021 * class as a string (just like object constructors do). The is-checks for
1022 * the class are are added to the holder object later. 1022 * the class are are added to the holder object later.
1023 */ 1023 */
1024 void maybeGenerateHolder(ClassElement cls) { 1024 void maybeGenerateHolder(ClassElement cls) {
1025 if (!needsHolder(cls)) return; 1025 if (!needsHolder(cls)) return;
1026 String holder = namer.isolateAccess(cls); 1026 String holder = namer.isolateAccess(cls);
1027 String name = namer.getName(cls); 1027 String name = namer.getName(cls);
1028 buffer.add('$holder$_=$_{builtin\$cls:$_"$name"'); 1028 buffer.write('$holder$_=$_{builtin\$cls:$_"$name"');
1029 buffer.add('}$N'); 1029 buffer.write('}$N');
1030 } 1030 }
1031 1031
1032 // Create representation objects for classes that we do not have a class 1032 // Create representation objects for classes that we do not have a class
1033 // definition for (because they are uninstantiated or native). 1033 // definition for (because they are uninstantiated or native).
1034 for (ClassElement cls in rti.allArguments) { 1034 for (ClassElement cls in rti.allArguments) {
1035 maybeGenerateHolder(cls); 1035 maybeGenerateHolder(cls);
1036 } 1036 }
1037 1037
1038 // Add checks to the constructors of instantiated classes or to the created 1038 // Add checks to the constructors of instantiated classes or to the created
1039 // holder object. 1039 // holder object.
1040 for (ClassElement cls in typeChecks) { 1040 for (ClassElement cls in typeChecks) {
1041 String holder = namer.isolateAccess(cls); 1041 String holder = namer.isolateAccess(cls);
1042 for (ClassElement check in typeChecks[cls]) { 1042 for (ClassElement check in typeChecks[cls]) {
1043 buffer.add('$holder.${namer.operatorIs(check)}$_=${_}true$N'); 1043 buffer.write('$holder.${namer.operatorIs(check)}$_=${_}true$N');
1044 String body = rti.getSupertypeSubstitution(cls, check); 1044 String body = rti.getSupertypeSubstitution(cls, check);
1045 if (body != null) { 1045 if (body != null) {
1046 buffer.add('$holder.${namer.substitutionName(check)}$_=${_}$body$N'); 1046 buffer.write('$holder.${namer.substitutionName(check)}$_=${_}$body$N') ;
1047 } 1047 }
1048 }; 1048 };
1049 } 1049 }
1050 } 1050 }
1051 1051
1052 void visitNativeMixins(ClassElement classElement, 1052 void visitNativeMixins(ClassElement classElement,
1053 void visit(MixinApplicationElement mixinApplication)) { 1053 void visit(MixinApplicationElement mixinApplication)) {
1054 if (!classElement.isNative()) return; 1054 if (!classElement.isNative()) return;
1055 // Use recursion to make sure to visit the superclasses before the 1055 // Use recursion to make sure to visit the superclasses before the
1056 // subclasses. Once we start keeping track of the emitted fields 1056 // subclasses. Once we start keeping track of the emitted fields
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 1346
1347 emitClassConstructor(classElement, builder); 1347 emitClassConstructor(classElement, builder);
1348 emitSuper(superName, builder); 1348 emitSuper(superName, builder);
1349 emitClassFields(classElement, builder, 1349 emitClassFields(classElement, builder,
1350 superClass: superName, classIsNative: false); 1350 superClass: superName, classIsNative: false);
1351 emitClassGettersSetters(classElement, builder); 1351 emitClassGettersSetters(classElement, builder);
1352 emitInstanceMembers(classElement, builder); 1352 emitInstanceMembers(classElement, builder);
1353 1353
1354 jsAst.Expression init = 1354 jsAst.Expression init =
1355 js[classesCollector][className].assign(builder.toObjectInitializer()); 1355 js[classesCollector][className].assign(builder.toObjectInitializer());
1356 buffer.add(jsAst.prettyPrint(init, compiler)); 1356 buffer.write(jsAst.prettyPrint(init, compiler));
1357 buffer.add('$N$n'); 1357 buffer.write('$N$n');
1358 } 1358 }
1359 1359
1360 bool get getterAndSetterCanBeImplementedByFieldSpec => true; 1360 bool get getterAndSetterCanBeImplementedByFieldSpec => true;
1361 1361
1362 int _selectorRank(Selector selector) { 1362 int _selectorRank(Selector selector) {
1363 int arity = selector.argumentCount * 3; 1363 int arity = selector.argumentCount * 3;
1364 if (selector.isGetter()) return arity + 2; 1364 if (selector.isGetter()) return arity + 2;
1365 if (selector.isSetter()) return arity + 1; 1365 if (selector.isSetter()) return arity + 1;
1366 return arity; 1366 return arity;
1367 } 1367 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 // The closure class could have become necessary because of the generation 1551 // The closure class could have become necessary because of the generation
1552 // of stubs. 1552 // of stubs.
1553 ClassElement closureClass = compiler.closureClass; 1553 ClassElement closureClass = compiler.closureClass;
1554 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) { 1554 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) {
1555 generateClass(closureClass, bufferForElement(closureClass, buffer)); 1555 generateClass(closureClass, bufferForElement(closureClass, buffer));
1556 } 1556 }
1557 } 1557 }
1558 1558
1559 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { 1559 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
1560 if (needsDefineClass) { 1560 if (needsDefineClass) {
1561 buffer.add('$finishClassesName($classesCollector,' 1561 buffer.write('$finishClassesName($classesCollector,'
1562 '$_$isolateProperties,' 1562 '$_$isolateProperties,'
1563 '${_}null)$N'); 1563 '${_}null)$N');
1564 1564
1565 // Reset the map. 1565 // Reset the map.
1566 buffer.add("$classesCollector$_=${_}null$N$n"); 1566 buffer.write("$classesCollector$_=${_}null$N$n");
1567 } 1567 }
1568 } 1568 }
1569 1569
1570 void emitStaticFunction(CodeBuffer buffer, 1570 void emitStaticFunction(CodeBuffer buffer,
1571 String name, 1571 String name,
1572 jsAst.Expression functionExpression) { 1572 jsAst.Expression functionExpression) {
1573 jsAst.Expression assignment = 1573 jsAst.Expression assignment =
1574 js[isolateProperties][name].assign(functionExpression); 1574 js[isolateProperties][name].assign(functionExpression);
1575 buffer.add(jsAst.prettyPrint(assignment, compiler)); 1575 buffer.write(jsAst.prettyPrint(assignment, compiler));
1576 buffer.add('$N$n'); 1576 buffer.write('$N$n');
1577 } 1577 }
1578 1578
1579 void emitStaticFunctions(CodeBuffer eagerBuffer) { 1579 void emitStaticFunctions(CodeBuffer eagerBuffer) {
1580 bool isStaticFunction(Element element) => 1580 bool isStaticFunction(Element element) =>
1581 !element.isInstanceMember() && !element.isField(); 1581 !element.isInstanceMember() && !element.isField();
1582 1582
1583 Iterable<Element> elements = 1583 Iterable<Element> elements =
1584 backend.generatedCode.keys.where(isStaticFunction); 1584 backend.generatedCode.keys.where(isStaticFunction);
1585 Set<Element> pendingElementsWithBailouts = 1585 Set<Element> pendingElementsWithBailouts =
1586 backend.generatedBailoutCode.keys 1586 backend.generatedBailoutCode.keys
(...skipping 30 matching lines...) Expand all
1617 // The static function does not have the correct name. Since 1617 // The static function does not have the correct name. Since
1618 // [addParameterStubs] use the name to create its stubs we simply 1618 // [addParameterStubs] use the name to create its stubs we simply
1619 // create a fake element with the correct name. 1619 // create a fake element with the correct name.
1620 // Note: the callElement will not have any enclosingElement. 1620 // Note: the callElement will not have any enclosingElement.
1621 FunctionElement callElement = 1621 FunctionElement callElement =
1622 new ClosureInvocationElement(namer.closureInvocationSelectorName, 1622 new ClosureInvocationElement(namer.closureInvocationSelectorName,
1623 element); 1623 element);
1624 String staticName = namer.getName(element); 1624 String staticName = namer.getName(element);
1625 String invocationName = namer.instanceMethodName(callElement); 1625 String invocationName = namer.instanceMethodName(callElement);
1626 String fieldAccess = '$isolateProperties.$staticName'; 1626 String fieldAccess = '$isolateProperties.$staticName';
1627 buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N"); 1627 buffer.write("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
1628 1628
1629 addParameterStubs(callElement, (String name, jsAst.Expression value) { 1629 addParameterStubs(callElement, (String name, jsAst.Expression value) {
1630 jsAst.Expression assignment = 1630 jsAst.Expression assignment =
1631 js[isolateProperties][staticName][name].assign(value); 1631 js[isolateProperties][staticName][name].assign(value);
1632 buffer.add( 1632 buffer.write(jsAst.prettyPrint(assignment.toStatement(), compiler));
1633 jsAst.prettyPrint(assignment.toStatement(), compiler)); 1633 buffer.write('$N');
1634 buffer.add('$N');
1635 }); 1634 });
1636 1635
1637 // If a static function is used as a closure we need to add its name 1636 // If a static function is used as a closure we need to add its name
1638 // in case it is used in spawnFunction. 1637 // in case it is used in spawnFunction.
1639 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; 1638 String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
1640 buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N'); 1639 buffer.write('$fieldAccess.$fieldName$_=$_"$staticName"$N');
1641 getTypedefChecksOn(element.computeType(compiler)).forEach( 1640 getTypedefChecksOn(element.computeType(compiler)).forEach(
1642 (Element typedef) { 1641 (Element typedef) {
1643 String operator = namer.operatorIs(typedef); 1642 String operator = namer.operatorIs(typedef);
1644 buffer.add('$fieldAccess.$operator$_=${_}true$N'); 1643 buffer.write('$fieldAccess.$operator$_=${_}true$N');
1645 } 1644 }
1646 ); 1645 );
1647 } 1646 }
1648 } 1647 }
1649 1648
1650 void emitBoundClosureClassHeader(String mangledName, 1649 void emitBoundClosureClassHeader(String mangledName,
1651 String superName, 1650 String superName,
1652 List<String> fieldNames, 1651 List<String> fieldNames,
1653 ClassBuilder builder) { 1652 ClassBuilder builder) {
1654 builder.addProperty('', 1653 builder.addProperty('',
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 Iterable<VariableElement> staticNonFinalFields = 1873 Iterable<VariableElement> staticNonFinalFields =
1875 handler.getStaticNonFinalFieldsForEmission(); 1874 handler.getStaticNonFinalFieldsForEmission();
1876 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { 1875 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) {
1877 // [:interceptedNames:] is handled in [emitInterceptedNames]. 1876 // [:interceptedNames:] is handled in [emitInterceptedNames].
1878 if (element == backend.interceptedNames) continue; 1877 if (element == backend.interceptedNames) continue;
1879 compiler.withCurrentElement(element, () { 1878 compiler.withCurrentElement(element, () {
1880 Constant initialValue = handler.getInitialValueFor(element); 1879 Constant initialValue = handler.getInitialValueFor(element);
1881 jsAst.Expression init = 1880 jsAst.Expression init =
1882 js[isolateProperties][namer.getName(element)].assign( 1881 js[isolateProperties][namer.getName(element)].assign(
1883 constantEmitter.referenceInInitializationContext(initialValue)); 1882 constantEmitter.referenceInInitializationContext(initialValue));
1884 buffer.add(jsAst.prettyPrint(init, compiler)); 1883 buffer.write(jsAst.prettyPrint(init, compiler));
1885 buffer.add('$N'); 1884 buffer.write('$N');
1886 }); 1885 });
1887 } 1886 }
1888 } 1887 }
1889 1888
1890 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { 1889 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
1891 ConstantHandler handler = compiler.constantHandler; 1890 ConstantHandler handler = compiler.constantHandler;
1892 List<VariableElement> lazyFields = 1891 List<VariableElement> lazyFields =
1893 handler.getLazilyInitializedFieldsForEmission(); 1892 handler.getLazilyInitializedFieldsForEmission();
1894 if (!lazyFields.isEmpty) { 1893 if (!lazyFields.isEmpty) {
1895 needsLazyInitializer = true; 1894 needsLazyInitializer = true;
(...skipping 10 matching lines...) Expand all
1906 arguments.add(js[isolateProperties]); 1905 arguments.add(js[isolateProperties]);
1907 arguments.add(js.string(element.name.slowToString())); 1906 arguments.add(js.string(element.name.slowToString()));
1908 arguments.add(js.string(namer.getName(element))); 1907 arguments.add(js.string(namer.getName(element)));
1909 arguments.add(js.string(namer.getLazyInitializerName(element))); 1908 arguments.add(js.string(namer.getLazyInitializerName(element)));
1910 arguments.add(code); 1909 arguments.add(code);
1911 jsAst.Expression getter = buildLazyInitializedGetter(element); 1910 jsAst.Expression getter = buildLazyInitializedGetter(element);
1912 if (getter != null) { 1911 if (getter != null) {
1913 arguments.add(getter); 1912 arguments.add(getter);
1914 } 1913 }
1915 jsAst.Expression init = js[lazyInitializerName](arguments); 1914 jsAst.Expression init = js[lazyInitializerName](arguments);
1916 buffer.add(jsAst.prettyPrint(init, compiler)); 1915 buffer.write(jsAst.prettyPrint(init, compiler));
1917 buffer.add("$N"); 1916 buffer.write("$N");
1918 } 1917 }
1919 } 1918 }
1920 } 1919 }
1921 1920
1922 jsAst.Expression buildLazyInitializedGetter(VariableElement element) { 1921 jsAst.Expression buildLazyInitializedGetter(VariableElement element) {
1923 // Nothing to do, the 'lazy' function will create the getter. 1922 // Nothing to do, the 'lazy' function will create the getter.
1924 return null; 1923 return null;
1925 } 1924 }
1926 1925
1927 void emitCompileTimeConstants(CodeBuffer eagerBuffer) { 1926 void emitCompileTimeConstants(CodeBuffer eagerBuffer) {
(...skipping 12 matching lines...) Expand all
1940 // share the ones that take up too much space (like some strings). 1939 // share the ones that take up too much space (like some strings).
1941 if (name == null) continue; 1940 if (name == null) continue;
1942 if (!addedMakeConstantList && constant.isList()) { 1941 if (!addedMakeConstantList && constant.isList()) {
1943 addedMakeConstantList = true; 1942 addedMakeConstantList = true;
1944 emitMakeConstantList(eagerBuffer); 1943 emitMakeConstantList(eagerBuffer);
1945 } 1944 }
1946 CodeBuffer buffer = 1945 CodeBuffer buffer =
1947 bufferForElement(constant.computeType(compiler).element, eagerBuffer); 1946 bufferForElement(constant.computeType(compiler).element, eagerBuffer);
1948 jsAst.Expression init = js[isolateProperties][name].assign( 1947 jsAst.Expression init = js[isolateProperties][name].assign(
1949 constantInitializerExpression(constant)); 1948 constantInitializerExpression(constant));
1950 buffer.add(jsAst.prettyPrint(init, compiler)); 1949 buffer.write(jsAst.prettyPrint(init, compiler));
1951 buffer.add('$N'); 1950 buffer.write('$N');
1952 } 1951 }
1953 } 1952 }
1954 1953
1955 void emitMakeConstantList(CodeBuffer buffer) { 1954 void emitMakeConstantList(CodeBuffer buffer) {
1956 buffer.add(namer.isolateName); 1955 buffer.write(namer.isolateName);
1957 buffer.add(r'''.makeConstantList = function(list) { 1956 buffer.write(r'''.makeConstantList = function(list) {
1958 list.immutable$list = true; 1957 list.immutable$list = true;
1959 list.fixed$length = true; 1958 list.fixed$length = true;
1960 return list; 1959 return list;
1961 }; 1960 };
1962 '''); 1961 ''');
1963 } 1962 }
1964 1963
1965 /** 1964 /**
1966 * Documentation wanted -- johnniwinther 1965 * Documentation wanted -- johnniwinther
1967 * 1966 *
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 String buildIsolateSetup(CodeBuffer buffer, 2121 String buildIsolateSetup(CodeBuffer buffer,
2123 Element appMain, 2122 Element appMain,
2124 Element isolateMain) { 2123 Element isolateMain) {
2125 String mainAccess = "${namer.isolateAccess(appMain)}"; 2124 String mainAccess = "${namer.isolateAccess(appMain)}";
2126 String currentIsolate = "${namer.CURRENT_ISOLATE}"; 2125 String currentIsolate = "${namer.CURRENT_ISOLATE}";
2127 // Since we pass the closurized version of the main method to 2126 // Since we pass the closurized version of the main method to
2128 // the isolate method, we must make sure that it exists. 2127 // the isolate method, we must make sure that it exists.
2129 if (!compiler.codegenWorld.staticFunctionsNeedingGetter.contains(appMain)) { 2128 if (!compiler.codegenWorld.staticFunctionsNeedingGetter.contains(appMain)) {
2130 Selector selector = new Selector.callClosure(0); 2129 Selector selector = new Selector.callClosure(0);
2131 String invocationName = namer.invocationName(selector); 2130 String invocationName = namer.invocationName(selector);
2132 buffer.add("$mainAccess.$invocationName = $mainAccess$N"); 2131 buffer.write("$mainAccess.$invocationName = $mainAccess$N");
2133 } 2132 }
2134 return "${namer.isolateAccess(isolateMain)}($mainAccess)"; 2133 return "${namer.isolateAccess(isolateMain)}($mainAccess)";
2135 } 2134 }
2136 2135
2137 emitMain(CodeBuffer buffer) { 2136 emitMain(CodeBuffer buffer) {
2138 if (compiler.isMockCompilation) return; 2137 if (compiler.isMockCompilation) return;
2139 Element main = compiler.mainApp.find(Compiler.MAIN); 2138 Element main = compiler.mainApp.find(Compiler.MAIN);
2140 String mainCall = null; 2139 String mainCall = null;
2141 if (compiler.hasIsolateSupport()) { 2140 if (compiler.hasIsolateSupport()) {
2142 Element isolateMain = 2141 Element isolateMain =
2143 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); 2142 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE);
2144 mainCall = buildIsolateSetup(buffer, main, isolateMain); 2143 mainCall = buildIsolateSetup(buffer, main, isolateMain);
2145 } else { 2144 } else {
2146 mainCall = '${namer.isolateAccess(main)}()'; 2145 mainCall = '${namer.isolateAccess(main)}()';
2147 } 2146 }
2148 addComment('BEGIN invoke [main].', buffer); 2147 addComment('BEGIN invoke [main].', buffer);
2149 buffer.add(""" 2148 buffer.write("""
2150 if (typeof document !== "undefined" && document.readyState !== "complete") { 2149 if (typeof document !== "undefined" && document.readyState !== "complete") {
2151 document.addEventListener("readystatechange", function () { 2150 document.addEventListener("readystatechange", function () {
2152 if (document.readyState == "complete") { 2151 if (document.readyState == "complete") {
2153 if (typeof dartMainRunner === "function") { 2152 if (typeof dartMainRunner === "function") {
2154 dartMainRunner(function() { ${mainCall}; }); 2153 dartMainRunner(function() { ${mainCall}; });
2155 } else { 2154 } else {
2156 ${mainCall}; 2155 ${mainCall};
2157 } 2156 }
2158 } 2157 }
2159 }, false); 2158 }, false);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 if (hasBool) { 2271 if (hasBool) {
2273 block.statements.add(buildInterceptorCheck(backend.jsBoolClass)); 2272 block.statements.add(buildInterceptorCheck(backend.jsBoolClass));
2274 } 2273 }
2275 // TODO(ahe): It might be faster to check for Array before 2274 // TODO(ahe): It might be faster to check for Array before
2276 // function and bool. 2275 // function and bool.
2277 if (hasArray) { 2276 if (hasArray) {
2278 block.statements.add(buildInterceptorCheck(backend.jsArrayClass)); 2277 block.statements.add(buildInterceptorCheck(backend.jsArrayClass));
2279 } 2278 }
2280 block.statements.add(js.return_(receiver)); 2279 block.statements.add(js.return_(receiver));
2281 2280
2282 buffer.add(jsAst.prettyPrint( 2281 buffer.write(jsAst.prettyPrint(
2283 js[isolateProperties][key].assign(js.fun(['receiver'], block)), 2282 js[isolateProperties][key].assign(js.fun(['receiver'], block)),
2284 compiler)); 2283 compiler));
2285 buffer.add(N); 2284 buffer.write(N);
2286 } 2285 }
2287 2286
2288 /** 2287 /**
2289 * Emit all versions of the [:getInterceptor:] method. 2288 * Emit all versions of the [:getInterceptor:] method.
2290 */ 2289 */
2291 void emitGetInterceptorMethods(CodeBuffer buffer) { 2290 void emitGetInterceptorMethods(CodeBuffer buffer) {
2292 var specializedGetInterceptors = backend.specializedGetInterceptors; 2291 var specializedGetInterceptors = backend.specializedGetInterceptors;
2293 for (String name in specializedGetInterceptors.keys.toList()..sort()) { 2292 for (String name in specializedGetInterceptors.keys.toList()..sort()) {
2294 Collection<ClassElement> classes = specializedGetInterceptors[name]; 2293 Collection<ClassElement> classes = specializedGetInterceptors[name];
2295 emitGetInterceptorMethod(buffer, name, classes); 2294 emitGetInterceptorMethod(buffer, name, classes);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 String invocationName = backend.namer.invocationName(selector); 2547 String invocationName = backend.namer.invocationName(selector);
2549 body.add(js.return_( 2548 body.add(js.return_(
2550 js[isolateProperties][getInterceptorName]('receiver')[invocationName]( 2549 js[isolateProperties][getInterceptorName]('receiver')[invocationName](
2551 arguments))); 2550 arguments)));
2552 2551
2553 jsAst.Fun function = js.fun(parameters, body); 2552 jsAst.Fun function = js.fun(parameters, body);
2554 2553
2555 jsAst.PropertyAccess property = 2554 jsAst.PropertyAccess property =
2556 js[isolateProperties][name]; 2555 js[isolateProperties][name];
2557 2556
2558 buffer.add(jsAst.prettyPrint(property.assign(function), compiler)); 2557 buffer.write(jsAst.prettyPrint(property.assign(function), compiler));
2559 buffer.add(N); 2558 buffer.write(N);
2560 } 2559 }
2561 } 2560 }
2562 2561
2563 /** 2562 /**
2564 * If [:invokeOn:] has been compiled, emit all the possible selector names 2563 * If [:invokeOn:] has been compiled, emit all the possible selector names
2565 * that are intercepted into the [:interceptedNames:] top-level 2564 * that are intercepted into the [:interceptedNames:] top-level
2566 * variable. The implementation of [:invokeOn:] will use it to 2565 * variable. The implementation of [:invokeOn:] will use it to
2567 * determine whether it should call the method with an extra 2566 * determine whether it should call the method with an extra
2568 * parameter. 2567 * parameter.
2569 */ 2568 */
2570 void emitInterceptedNames(CodeBuffer buffer) { 2569 void emitInterceptedNames(CodeBuffer buffer) {
2571 if (!compiler.enabledInvokeOn) return; 2570 if (!compiler.enabledInvokeOn) return;
2572 String name = backend.namer.getName(backend.interceptedNames); 2571 String name = backend.namer.getName(backend.interceptedNames);
2573 jsAst.PropertyAccess property = js[isolateProperties][name]; 2572 jsAst.PropertyAccess property = js[isolateProperties][name];
2574 2573
2575 int index = 0; 2574 int index = 0;
2576 List<jsAst.ArrayElement> elements = backend.usedInterceptors.map( 2575 List<jsAst.ArrayElement> elements = backend.usedInterceptors.map(
2577 (Selector selector) { 2576 (Selector selector) {
2578 jsAst.Literal str = js.string(namer.invocationName(selector)); 2577 jsAst.Literal str = js.string(namer.invocationName(selector));
2579 return new jsAst.ArrayElement(index++, str); 2578 return new jsAst.ArrayElement(index++, str);
2580 }).toList(); 2579 }).toList();
2581 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer( 2580 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(
2582 backend.usedInterceptors.length, 2581 backend.usedInterceptors.length,
2583 elements); 2582 elements);
2584 2583
2585 buffer.add(jsAst.prettyPrint(property.assign(array), compiler)); 2584 buffer.write(jsAst.prettyPrint(property.assign(array), compiler));
2586 buffer.add(N); 2585 buffer.write(N);
2587 } 2586 }
2588 2587
2589 void emitInitFunction(CodeBuffer buffer) { 2588 void emitInitFunction(CodeBuffer buffer) {
2590 jsAst.Fun fun = js.fun([], [ 2589 jsAst.Fun fun = js.fun([], [
2591 js['$isolateProperties = {}'], 2590 js['$isolateProperties = {}'],
2592 ] 2591 ]
2593 ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary()) 2592 ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary())
2594 ..addAll(buildLazyInitializerFunctionIfNecessary()) 2593 ..addAll(buildLazyInitializerFunctionIfNecessary())
2595 ..addAll(buildFinishIsolateConstructor()) 2594 ..addAll(buildFinishIsolateConstructor())
2596 ); 2595 );
2597 jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration( 2596 jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration(
2598 new jsAst.VariableDeclaration('init'), fun); 2597 new jsAst.VariableDeclaration('init'), fun);
2599 buffer.add(jsAst.prettyPrint(decl, compiler).getText()); 2598 buffer.write(jsAst.prettyPrint(decl, compiler).getText());
2600 } 2599 }
2601 2600
2602 String assembleProgram() { 2601 String assembleProgram() {
2603 measure(() { 2602 measure(() {
2604 computeNeededClasses(); 2603 computeNeededClasses();
2605 2604
2606 // Compute the required type checks to know which classes need a 2605 // Compute the required type checks to know which classes need a
2607 // 'is$' method. 2606 // 'is$' method.
2608 computeRequiredTypeChecks(); 2607 computeRequiredTypeChecks();
2609 2608
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2715 2714
2716 CodeBuffer bufferForElement(Element element, CodeBuffer eagerBuffer) { 2715 CodeBuffer bufferForElement(Element element, CodeBuffer eagerBuffer) {
2717 if (!isDeferred(element)) return eagerBuffer; 2716 if (!isDeferred(element)) return eagerBuffer;
2718 emitDeferredPreambleWhenEmpty(deferredBuffer); 2717 emitDeferredPreambleWhenEmpty(deferredBuffer);
2719 return deferredBuffer; 2718 return deferredBuffer;
2720 } 2719 }
2721 2720
2722 void emitDeferredCode(CodeBuffer buffer) { 2721 void emitDeferredCode(CodeBuffer buffer) {
2723 if (buffer.isEmpty) return; 2722 if (buffer.isEmpty) return;
2724 2723
2725 buffer.add(n); 2724 buffer.write(n);
2726 2725
2727 buffer.add('${namer.CURRENT_ISOLATE}$_=${_}old${namer.CURRENT_ISOLATE}$N'); 2726 buffer.write(
2727 '${namer.CURRENT_ISOLATE}$_=${_}old${namer.CURRENT_ISOLATE}$N');
2728 2728
2729 String code = buffer.getText(); 2729 String code = buffer.getText();
2730 compiler.outputProvider('part', 'js') 2730 compiler.outputProvider('part', 'js')
2731 ..add(code) 2731 ..add(code)
2732 ..close(); 2732 ..close();
2733 outputSourceMap(buffer, compiler.assembledCode, 'part'); 2733 outputSourceMap(buffer, compiler.assembledCode, 'part');
2734 } 2734 }
2735 2735
2736 void emitDeferredPreambleWhenEmpty(CodeBuffer buffer) { 2736 void emitDeferredPreambleWhenEmpty(CodeBuffer buffer) {
2737 if (!buffer.isEmpty) return; 2737 if (!buffer.isEmpty) return;
2738 2738
2739 buffer.add(GENERATED_BY); 2739 buffer.write(GENERATED_BY);
2740 2740
2741 buffer.add('var old${namer.CURRENT_ISOLATE}$_=' 2741 buffer.write('var old${namer.CURRENT_ISOLATE}$_='
2742 '$_${namer.CURRENT_ISOLATE}$N'); 2742 '$_${namer.CURRENT_ISOLATE}$N');
2743 2743
2744 // TODO(ahe): This defines a lot of properties on the 2744 // TODO(ahe): This defines a lot of properties on the
2745 // Isolate.prototype object. We know this will turn it into a 2745 // Isolate.prototype object. We know this will turn it into a
2746 // slow object in V8, so instead we should do something similar to 2746 // slow object in V8, so instead we should do something similar to
2747 // Isolate.$finishIsolateConstructor. 2747 // Isolate.$finishIsolateConstructor.
2748 buffer.add('${namer.CURRENT_ISOLATE}$_=' 2748 buffer.write('${namer.CURRENT_ISOLATE}$_='
2749 '$_${namer.isolateName}.prototype$N$n'); 2749 '$_${namer.isolateName}.prototype$N$n');
2750 } 2750 }
2751 2751
2752 String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) { 2752 String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) {
2753 SourceMapBuilder sourceMapBuilder = new SourceMapBuilder(); 2753 SourceMapBuilder sourceMapBuilder = new SourceMapBuilder();
2754 buffer.forEachSourceLocation(sourceMapBuilder.addMapping); 2754 buffer.forEachSourceLocation(sourceMapBuilder.addMapping);
2755 return sourceMapBuilder.build(compiledFile); 2755 return sourceMapBuilder.build(compiledFile);
2756 } 2756 }
2757 2757
2758 void outputSourceMap(CodeBuffer buffer, String code, String name) { 2758 void outputSourceMap(CodeBuffer buffer, String code, String name) {
2759 if (!generateSourceMap) return; 2759 if (!generateSourceMap) return;
(...skipping 21 matching lines...) Expand all
2781 """; 2781 """;
2782 const String HOOKS_API_USAGE = """ 2782 const String HOOKS_API_USAGE = """
2783 // The code supports the following hooks: 2783 // The code supports the following hooks:
2784 // dartPrint(message) - if this function is defined it is called 2784 // dartPrint(message) - if this function is defined it is called
2785 // instead of the Dart [print] method. 2785 // instead of the Dart [print] method.
2786 // dartMainRunner(main) - if this function is defined, the Dart [main] 2786 // dartMainRunner(main) - if this function is defined, the Dart [main]
2787 // method will not be invoked directly. 2787 // method will not be invoked directly.
2788 // Instead, a closure that will invoke [main] is 2788 // Instead, a closure that will invoke [main] is
2789 // passed to [dartMainRunner]. 2789 // passed to [dartMainRunner].
2790 """; 2790 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698