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