| 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 2077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 for (ClassElement element in instantiatedClasses) { | 2088 for (ClassElement element in instantiatedClasses) { |
| 2089 for (ClassElement superclass = element.superclass; | 2089 for (ClassElement superclass = element.superclass; |
| 2090 superclass != null; | 2090 superclass != null; |
| 2091 superclass = superclass.superclass) { | 2091 superclass = superclass.superclass) { |
| 2092 if (neededClasses.contains(superclass)) break; | 2092 if (neededClasses.contains(superclass)) break; |
| 2093 neededClasses.add(superclass); | 2093 neededClasses.add(superclass); |
| 2094 } | 2094 } |
| 2095 } | 2095 } |
| 2096 } | 2096 } |
| 2097 | 2097 |
| 2098 void emitOneShotInterceptors(CodeBuffer buffer) { |
| 2099 JavaScriptBackend backend = compiler.backend; |
| 2100 for (Selector selector in backend.oneShotInterceptors) { |
| 2101 Set<ClassElement> classes = backend.getInterceptedClassesOn(selector); |
| 2102 String oneShotInterceptorName = namer.oneShotInterceptorName(selector); |
| 2103 String getInterceptorName = |
| 2104 namer.getInterceptorName(backend.getInterceptorMethod, classes); |
| 2105 |
| 2106 List<js.Parameter> parameters = <js.Parameter>[]; |
| 2107 List<js.Expression> arguments = <js.Expression>[]; |
| 2108 parameters.add(new js.Parameter('receiver')); |
| 2109 arguments.add(js.use('receiver')); |
| 2110 |
| 2111 if (selector.isSetter()) { |
| 2112 parameters.add(new js.Parameter('value')); |
| 2113 arguments.add(js.use('value')); |
| 2114 } else { |
| 2115 for (int i = 0; i < selector.argumentCount; i++) { |
| 2116 String argName = 'a$i'; |
| 2117 parameters.add(new js.Parameter(argName)); |
| 2118 arguments.add(js.use(argName)); |
| 2119 } |
| 2120 } |
| 2121 |
| 2122 String invocationName = backend.namer.invocationName(selector); |
| 2123 js.Fun function = |
| 2124 new js.Fun(parameters, |
| 2125 js.block1(js.return_( |
| 2126 js.use(isolateProperties) |
| 2127 .dot(getInterceptorName) |
| 2128 .callWith([js.use('receiver')]) |
| 2129 .dot(invocationName) |
| 2130 .callWith(arguments)))); |
| 2131 |
| 2132 js.PropertyAccess property = |
| 2133 js.fieldAccess(js.use(isolateProperties), oneShotInterceptorName); |
| 2134 |
| 2135 buffer.add(js.prettyPrint(js.assign(property, function), compiler)); |
| 2136 buffer.add(N); |
| 2137 } |
| 2138 } |
| 2139 |
| 2098 String assembleProgram() { | 2140 String assembleProgram() { |
| 2099 measure(() { | 2141 measure(() { |
| 2100 computeNeededClasses(); | 2142 computeNeededClasses(); |
| 2101 | 2143 |
| 2102 mainBuffer.add(GENERATED_BY); | 2144 mainBuffer.add(GENERATED_BY); |
| 2103 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE); | 2145 if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE); |
| 2104 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); | 2146 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); |
| 2105 mainBuffer.add('init()$N$n'); | 2147 mainBuffer.add('init()$N$n'); |
| 2106 // Shorten the code by using "$$" as temporary. | 2148 // Shorten the code by using "$$" as temporary. |
| 2107 classesCollector = r"$$"; | 2149 classesCollector = r"$$"; |
| 2108 mainBuffer.add('var $classesCollector$_=$_{}$N'); | 2150 mainBuffer.add('var $classesCollector$_=$_{}$N'); |
| 2109 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 2151 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
| 2110 isolateProperties = namer.CURRENT_ISOLATE; | 2152 isolateProperties = namer.CURRENT_ISOLATE; |
| 2111 mainBuffer.add( | 2153 mainBuffer.add( |
| 2112 'var $isolateProperties$_=$_$isolatePropertiesName$N'); | 2154 'var $isolateProperties$_=$_$isolatePropertiesName$N'); |
| 2113 emitClasses(mainBuffer); | 2155 emitClasses(mainBuffer); |
| 2114 mainBuffer.add(boundClosureBuffer); | 2156 mainBuffer.add(boundClosureBuffer); |
| 2115 // Clear the buffer, so that we can reuse it for the native classes. | 2157 // Clear the buffer, so that we can reuse it for the native classes. |
| 2116 boundClosureBuffer.clear(); | 2158 boundClosureBuffer.clear(); |
| 2117 emitStaticFunctions(mainBuffer); | 2159 emitStaticFunctions(mainBuffer); |
| 2118 emitStaticFunctionGetters(mainBuffer); | 2160 emitStaticFunctionGetters(mainBuffer); |
| 2119 // We need to finish the classes before we construct compile time | 2161 // We need to finish the classes before we construct compile time |
| 2120 // constants. | 2162 // constants. |
| 2121 emitFinishClassesInvocationIfNecessary(mainBuffer); | 2163 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 2122 emitRuntimeClassesAndTests(mainBuffer); | 2164 emitRuntimeClassesAndTests(mainBuffer); |
| 2123 emitCompileTimeConstants(mainBuffer); | 2165 emitCompileTimeConstants(mainBuffer); |
| 2124 // Static field initializations require the classes and compile-time | 2166 // Static field initializations require the classes and compile-time |
| 2125 // constants to be set up. | 2167 // constants to be set up. |
| 2126 emitStaticNonFinalFieldInitializations(mainBuffer); | 2168 emitStaticNonFinalFieldInitializations(mainBuffer); |
| 2169 emitOneShotInterceptors(mainBuffer); |
| 2127 emitGetInterceptorMethods(mainBuffer); | 2170 emitGetInterceptorMethods(mainBuffer); |
| 2128 emitLazilyInitializedStaticFields(mainBuffer); | 2171 emitLazilyInitializedStaticFields(mainBuffer); |
| 2129 | 2172 |
| 2130 isolateProperties = isolatePropertiesName; | 2173 isolateProperties = isolatePropertiesName; |
| 2131 // The following code should not use the short-hand for the | 2174 // The following code should not use the short-hand for the |
| 2132 // initialStatics. | 2175 // initialStatics. |
| 2133 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=${_}null$N'); | 2176 mainBuffer.add('var ${namer.CURRENT_ISOLATE}$_=${_}null$N'); |
| 2134 mainBuffer.add(boundClosureBuffer); | 2177 mainBuffer.add(boundClosureBuffer); |
| 2135 emitFinishClassesInvocationIfNecessary(mainBuffer); | 2178 emitFinishClassesInvocationIfNecessary(mainBuffer); |
| 2136 // After this assignment we will produce invalid JavaScript code if we use | 2179 // After this assignment we will produce invalid JavaScript code if we use |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2176 """; | 2219 """; |
| 2177 const String HOOKS_API_USAGE = """ | 2220 const String HOOKS_API_USAGE = """ |
| 2178 // The code supports the following hooks: | 2221 // The code supports the following hooks: |
| 2179 // dartPrint(message) - if this function is defined it is called | 2222 // dartPrint(message) - if this function is defined it is called |
| 2180 // instead of the Dart [print] method. | 2223 // instead of the Dart [print] method. |
| 2181 // dartMainRunner(main) - if this function is defined, the Dart [main] | 2224 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 2182 // method will not be invoked directly. | 2225 // method will not be invoked directly. |
| 2183 // Instead, a closure that will invoke [main] is | 2226 // Instead, a closure that will invoke [main] is |
| 2184 // passed to [dartMainRunner]. | 2227 // passed to [dartMainRunner]. |
| 2185 """; | 2228 """; |
| OLD | NEW |