| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' show PrimitiveConstantValue; | 8 import '../constants/values.dart' show PrimitiveConstantValue; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../dart2jslib.dart'; | 10 import '../dart2jslib.dart'; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 final List<JumpCollector> breakCollectors = <JumpCollector>[]; | 212 final List<JumpCollector> breakCollectors = <JumpCollector>[]; |
| 213 | 213 |
| 214 /// A stack of collectors for continues. | 214 /// A stack of collectors for continues. |
| 215 final List<JumpCollector> continueCollectors = <JumpCollector>[]; | 215 final List<JumpCollector> continueCollectors = <JumpCollector>[]; |
| 216 | 216 |
| 217 final List<ConstDeclaration> localConstants = <ConstDeclaration>[]; | 217 final List<ConstDeclaration> localConstants = <ConstDeclaration>[]; |
| 218 | 218 |
| 219 final ExecutableElement currentElement; | 219 final ExecutableElement currentElement; |
| 220 | 220 |
| 221 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); | 221 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); |
| 222 ir.Parameter _thisParameter; |
| 223 ir.Parameter enclosingMethodThisParameter; |
| 222 | 224 |
| 223 final List<ir.Definition> functionParameters = <ir.Definition>[]; | 225 final List<ir.Definition> functionParameters = <ir.Definition>[]; |
| 224 | 226 |
| 225 IrBuilderDelimitedState(this.constantSystem, this.currentElement); | 227 IrBuilderDelimitedState(this.constantSystem, this.currentElement); |
| 228 |
| 229 ir.Parameter get thisParameter => _thisParameter; |
| 230 void set thisParameter(ir.Parameter value) { |
| 231 assert(_thisParameter == null); |
| 232 _thisParameter = value; |
| 233 } |
| 234 } |
| 235 |
| 236 class ThisParameterLocal implements Local { |
| 237 final ExecutableElement executableContext; |
| 238 ThisParameterLocal(this.executableContext); |
| 239 String get name => 'this'; |
| 240 toString() => 'ThisParameterLocal($executableContext)'; |
| 226 } | 241 } |
| 227 | 242 |
| 228 /// A factory for building the cps IR. | 243 /// A factory for building the cps IR. |
| 229 /// | 244 /// |
| 230 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured | 245 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured |
| 231 /// variables in different ways. | 246 /// variables in different ways. |
| 232 abstract class IrBuilder { | 247 abstract class IrBuilder { |
| 233 IrBuilder _makeInstance(); | 248 IrBuilder _makeInstance(); |
| 234 | 249 |
| 235 // TODO(johnniwinther): Remove this from the [IrBuilder]. | 250 // TODO(johnniwinther): Remove this from the [IrBuilder]. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 void _enterForLoopBody(ClosureScope scope, | 304 void _enterForLoopBody(ClosureScope scope, |
| 290 List<LocalElement> loopVariables); | 305 List<LocalElement> loopVariables); |
| 291 | 306 |
| 292 /// Called before building the update of a for-loop. | 307 /// Called before building the update of a for-loop. |
| 293 void _enterForLoopUpdate(ClosureScope scope, | 308 void _enterForLoopUpdate(ClosureScope scope, |
| 294 List<LocalElement> loopVariables); | 309 List<LocalElement> loopVariables); |
| 295 | 310 |
| 296 /// Add the given function parameter to the IR, and bind it in the environment | 311 /// Add the given function parameter to the IR, and bind it in the environment |
| 297 /// or put it in its box, if necessary. | 312 /// or put it in its box, if necessary. |
| 298 void _createFunctionParameter(ParameterElement parameterElement); | 313 void _createFunctionParameter(ParameterElement parameterElement); |
| 314 void _createThisParameter(); |
| 299 | 315 |
| 300 /// Creates an access to the receiver from the current (or enclosing) method. | 316 /// Creates an access to the receiver from the current (or enclosing) method. |
| 301 /// | 317 /// |
| 302 /// If inside a closure class, [buildThis] will redirect access through | 318 /// If inside a closure class, [buildThis] will redirect access through |
| 303 /// closure fields in order to access the receiver from the enclosing method. | 319 /// closure fields in order to access the receiver from the enclosing method. |
| 304 ir.Primitive buildThis(); | 320 ir.Primitive buildThis(); |
| 305 | 321 |
| 306 // TODO(johnniwinther): Make these field final and remove the default values | 322 // TODO(johnniwinther): Make these field final and remove the default values |
| 307 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. | 323 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. |
| 308 | 324 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 IrBuilder makeRecursiveBuilder() { | 396 IrBuilder makeRecursiveBuilder() { |
| 381 IrBuilder inner = _makeInstance() | 397 IrBuilder inner = _makeInstance() |
| 382 ..state = state | 398 ..state = state |
| 383 ..environment = new Environment.empty(); | 399 ..environment = new Environment.empty(); |
| 384 environment.index2variable.forEach(inner.createLocalParameter); | 400 environment.index2variable.forEach(inner.createLocalParameter); |
| 385 return inner; | 401 return inner; |
| 386 } | 402 } |
| 387 | 403 |
| 388 /// Construct a builder for an inner function. | 404 /// Construct a builder for an inner function. |
| 389 IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) { | 405 IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) { |
| 406 IrBuilderDelimitedState innerState = |
| 407 new IrBuilderDelimitedState(state.constantSystem, currentElement) |
| 408 ..enclosingMethodThisParameter = state.enclosingMethodThisParameter; |
| 390 return _makeInstance() | 409 return _makeInstance() |
| 391 ..state = new IrBuilderDelimitedState(state.constantSystem, currentEleme
nt) | 410 ..state = innerState |
| 392 ..environment = new Environment.empty(); | 411 ..environment = new Environment.empty(); |
| 393 } | 412 } |
| 394 | 413 |
| 395 bool get isOpen => _root == null || _current != null; | 414 bool get isOpen => _root == null || _current != null; |
| 396 | 415 |
| 397 | 416 |
| 398 void buildFieldInitializerHeader({ClosureScope closureScope}) { | 417 void buildFieldInitializerHeader({ClosureScope closureScope}) { |
| 399 _enterScope(closureScope); | 418 _enterScope(closureScope); |
| 400 } | 419 } |
| 401 | 420 |
| 402 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters, | 421 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters, |
| 403 {ClosureScope closureScope, | 422 {ClosureScope closureScope, |
| 404 ClosureEnvironment env}) { | 423 ClosureEnvironment env}) { |
| 424 _createThisParameter(); |
| 405 _enterClosureEnvironment(env); | 425 _enterClosureEnvironment(env); |
| 406 _enterScope(closureScope); | 426 _enterScope(closureScope); |
| 407 parameters.forEach(_createFunctionParameter); | 427 parameters.forEach(_createFunctionParameter); |
| 408 return _parameters; | 428 return _parameters; |
| 409 } | 429 } |
| 410 | 430 |
| 411 /// Creates a parameter for [local] and adds it to the current environment. | 431 /// Creates a parameter for [local] and adds it to the current environment. |
| 412 ir.Parameter createLocalParameter(Local local) { | 432 ir.Parameter createLocalParameter(Local local) { |
| 413 ir.Parameter parameter = new ir.Parameter(local); | 433 ir.Parameter parameter = new ir.Parameter(local); |
| 414 _parameters.add(parameter); | 434 _parameters.add(parameter); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 ir.FunctionDefinition makeFunctionDefinition( | 671 ir.FunctionDefinition makeFunctionDefinition( |
| 652 List<ConstantExpression> defaults) { | 672 List<ConstantExpression> defaults) { |
| 653 FunctionElement element = state.currentElement; | 673 FunctionElement element = state.currentElement; |
| 654 if (element.isAbstract || element.isExternal) { | 674 if (element.isAbstract || element.isExternal) { |
| 655 assert(invariant(element, _root == null, | 675 assert(invariant(element, _root == null, |
| 656 message: "Non-empty body for abstract method $element: $_root")); | 676 message: "Non-empty body for abstract method $element: $_root")); |
| 657 assert(invariant(element, state.localConstants.isEmpty, | 677 assert(invariant(element, state.localConstants.isEmpty, |
| 658 message: "Local constants for abstract method $element: " | 678 message: "Local constants for abstract method $element: " |
| 659 "${state.localConstants}")); | 679 "${state.localConstants}")); |
| 660 return new ir.FunctionDefinition.abstract( | 680 return new ir.FunctionDefinition.abstract( |
| 661 element, state.functionParameters, defaults); | 681 element, state.thisParameter, state.functionParameters, defaults); |
| 662 } else { | 682 } else { |
| 663 ir.RunnableBody body = makeRunnableBody(); | 683 ir.RunnableBody body = makeRunnableBody(); |
| 664 return new ir.FunctionDefinition( | 684 return new ir.FunctionDefinition( |
| 665 element, state.functionParameters, body, | 685 element, state.thisParameter, state.functionParameters, body, |
| 666 state.localConstants, defaults); | 686 state.localConstants, defaults); |
| 667 } | 687 } |
| 668 } | 688 } |
| 669 | 689 |
| 670 /// Create a constructor definition without a body, for representing | 690 /// Create a constructor definition without a body, for representing |
| 671 /// external constructors declarations. | 691 /// external constructors declarations. |
| 672 ir.ConstructorDefinition makeAbstractConstructorDefinition( | 692 ir.ConstructorDefinition makeAbstractConstructorDefinition( |
| 673 List<ConstantExpression> defaults) { | 693 List<ConstantExpression> defaults) { |
| 674 FunctionElement element = state.currentElement; | 694 FunctionElement element = state.currentElement; |
| 675 assert(invariant(element, _root == null, | 695 assert(invariant(element, _root == null, |
| 676 message: "Non-empty body for external constructor $element: $_root")); | 696 message: "Non-empty body for external constructor $element: $_root")); |
| 677 assert(invariant(element, state.localConstants.isEmpty, | 697 assert(invariant(element, state.localConstants.isEmpty, |
| 678 message: "Local constants for external constructor $element: " | 698 message: "Local constants for external constructor $element: " |
| 679 "${state.localConstants}")); | 699 "${state.localConstants}")); |
| 680 return new ir.ConstructorDefinition.abstract( | 700 return new ir.ConstructorDefinition.abstract( |
| 681 element, state.functionParameters, defaults); | 701 element, state.functionParameters, defaults); |
| 682 } | 702 } |
| 683 | 703 |
| 684 ir.ConstructorDefinition makeConstructorDefinition( | 704 ir.ConstructorDefinition makeConstructorDefinition( |
| 685 List<ConstantExpression> defaults, List<ir.Initializer> initializers) { | 705 List<ConstantExpression> defaults, List<ir.Initializer> initializers) { |
| 686 FunctionElement element = state.currentElement; | 706 FunctionElement element = state.currentElement; |
| 687 ir.RunnableBody body = makeRunnableBody(); | 707 ir.RunnableBody body = makeRunnableBody(); |
| 688 return new ir.ConstructorDefinition( | 708 return new ir.ConstructorDefinition( |
| 689 element, state.functionParameters, body, initializers, | 709 element, state.thisParameter, state.functionParameters, body, initialize
rs, |
| 690 state.localConstants, defaults); | 710 state.localConstants, defaults); |
| 691 } | 711 } |
| 692 | 712 |
| 693 /// Create a super invocation where the method name and the argument structure | 713 /// Create a super invocation where the method name and the argument structure |
| 694 /// are defined by [selector] and the argument values are defined by | 714 /// are defined by [selector] and the argument values are defined by |
| 695 /// [arguments]. | 715 /// [arguments]. |
| 696 ir.Primitive buildSuperInvocation(Element target, | 716 ir.Primitive buildSuperInvocation(Element target, |
| 697 Selector selector, | 717 Selector selector, |
| 698 List<ir.Primitive> arguments); | 718 List<ir.Primitive> arguments); |
| 699 | 719 |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 bodyBuilder._enterScope(closureScope); | 1160 bodyBuilder._enterScope(closureScope); |
| 1141 if (buildVariableDeclaration != null) { | 1161 if (buildVariableDeclaration != null) { |
| 1142 buildVariableDeclaration(bodyBuilder); | 1162 buildVariableDeclaration(bodyBuilder); |
| 1143 } | 1163 } |
| 1144 | 1164 |
| 1145 ir.Parameter currentValue = new ir.Parameter(null); | 1165 ir.Parameter currentValue = new ir.Parameter(null); |
| 1146 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); | 1166 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); |
| 1147 bodyBuilder.add(new ir.LetCont(currentInvoked, | 1167 bodyBuilder.add(new ir.LetCont(currentInvoked, |
| 1148 new ir.InvokeMethod(iterator, new Selector.getter("current", null), | 1168 new ir.InvokeMethod(iterator, new Selector.getter("current", null), |
| 1149 currentInvoked, emptyArguments))); | 1169 currentInvoked, emptyArguments))); |
| 1170 // TODO(sra): Does this cover all cases? The general setter case include |
| 1171 // super. |
| 1150 if (Elements.isLocal(variableElement)) { | 1172 if (Elements.isLocal(variableElement)) { |
| 1151 bodyBuilder.buildLocalSet(variableElement, currentValue); | 1173 bodyBuilder.buildLocalSet(variableElement, currentValue); |
| 1152 } else if (Elements.isStaticOrTopLevel(variableElement)) { | 1174 } else if (Elements.isStaticOrTopLevel(variableElement) || |
| 1175 Elements.isErroneous(variableElement)) { |
| 1153 bodyBuilder.buildStaticSet( | 1176 bodyBuilder.buildStaticSet( |
| 1154 variableElement, variableSelector, currentValue); | 1177 variableElement, variableSelector, currentValue); |
| 1155 } else { | 1178 } else { |
| 1156 ir.Primitive receiver = bodyBuilder.buildThis(); | 1179 ir.Primitive receiver = bodyBuilder.buildThis(); |
| 1180 assert(receiver != null); |
| 1157 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); | 1181 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); |
| 1158 } | 1182 } |
| 1159 | 1183 |
| 1160 buildBody(bodyBuilder); | 1184 buildBody(bodyBuilder); |
| 1161 assert(state.breakCollectors.last == breakCollector); | 1185 assert(state.breakCollectors.last == breakCollector); |
| 1162 assert(state.continueCollectors.last == continueCollector); | 1186 assert(state.continueCollectors.last == continueCollector); |
| 1163 state.breakCollectors.removeLast(); | 1187 state.breakCollectors.removeLast(); |
| 1164 state.continueCollectors.removeLast(); | 1188 state.continueCollectors.removeLast(); |
| 1165 | 1189 |
| 1166 // Create body entry and loop exit continuations and a branch to them. | 1190 // Create body entry and loop exit continuations and a branch to them. |
| (...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2030 ir.Parameter parameter = new ir.Parameter(parameterElement); | 2054 ir.Parameter parameter = new ir.Parameter(parameterElement); |
| 2031 _parameters.add(parameter); | 2055 _parameters.add(parameter); |
| 2032 if (isInMutableVariable(parameterElement)) { | 2056 if (isInMutableVariable(parameterElement)) { |
| 2033 state.functionParameters.add(getMutableVariable(parameterElement)); | 2057 state.functionParameters.add(getMutableVariable(parameterElement)); |
| 2034 } else { | 2058 } else { |
| 2035 state.functionParameters.add(parameter); | 2059 state.functionParameters.add(parameter); |
| 2036 environment.extend(parameterElement, parameter); | 2060 environment.extend(parameterElement, parameter); |
| 2037 } | 2061 } |
| 2038 } | 2062 } |
| 2039 | 2063 |
| 2064 void _createThisParameter() { |
| 2065 void create() { |
| 2066 ir.Parameter thisParameter = |
| 2067 new ir.Parameter(new ThisParameterLocal(state.currentElement)); |
| 2068 state.thisParameter = thisParameter; |
| 2069 state.enclosingMethodThisParameter = thisParameter; |
| 2070 } |
| 2071 if (state.currentElement.isLocal) return; |
| 2072 if (state.currentElement.isStatic) return; |
| 2073 if (state.currentElement.isGenerativeConstructor) { |
| 2074 create(); |
| 2075 return; |
| 2076 } |
| 2077 if (state.currentElement.isStatic) return; |
| 2078 if (state.currentElement.isInstanceMember) { |
| 2079 create(); |
| 2080 return; |
| 2081 } |
| 2082 } |
| 2083 |
| 2040 void declareLocalVariable(LocalVariableElement variableElement, | 2084 void declareLocalVariable(LocalVariableElement variableElement, |
| 2041 {ir.Primitive initialValue}) { | 2085 {ir.Primitive initialValue}) { |
| 2042 assert(isOpen); | 2086 assert(isOpen); |
| 2043 if (initialValue == null) { | 2087 if (initialValue == null) { |
| 2044 initialValue = buildNullLiteral(); | 2088 initialValue = buildNullLiteral(); |
| 2045 } | 2089 } |
| 2046 if (isInMutableVariable(variableElement)) { | 2090 if (isInMutableVariable(variableElement)) { |
| 2047 add(new ir.LetMutable(getMutableVariable(variableElement), | 2091 add(new ir.LetMutable(getMutableVariable(variableElement), |
| 2048 initialValue)); | 2092 initialValue)); |
| 2049 } else { | 2093 } else { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 assert(isOpen); | 2132 assert(isOpen); |
| 2089 if (isInMutableVariable(local)) { | 2133 if (isInMutableVariable(local)) { |
| 2090 add(new ir.SetMutableVariable(getMutableVariable(local), value)); | 2134 add(new ir.SetMutableVariable(getMutableVariable(local), value)); |
| 2091 } else { | 2135 } else { |
| 2092 value.useElementAsHint(local); | 2136 value.useElementAsHint(local); |
| 2093 environment.update(local, value); | 2137 environment.update(local, value); |
| 2094 } | 2138 } |
| 2095 return value; | 2139 return value; |
| 2096 } | 2140 } |
| 2097 | 2141 |
| 2098 ir.Primitive buildThis() => addPrimitive(new ir.This()); | 2142 ir.Primitive buildThis() { |
| 2143 return state.enclosingMethodThisParameter; |
| 2144 } |
| 2099 | 2145 |
| 2100 ir.Primitive buildSuperInvocation(Element target, | 2146 ir.Primitive buildSuperInvocation(Element target, |
| 2101 Selector selector, | 2147 Selector selector, |
| 2102 List<ir.Primitive> arguments) { | 2148 List<ir.Primitive> arguments) { |
| 2103 return _buildInvokeSuper(target, selector, arguments); | 2149 return _buildInvokeSuper(target, selector, arguments); |
| 2104 } | 2150 } |
| 2105 | 2151 |
| 2106 } | 2152 } |
| 2107 | 2153 |
| 2108 /// State shared between JsIrBuilders within the same function. | 2154 /// State shared between JsIrBuilders within the same function. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2135 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null; | 2181 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null; |
| 2136 Set<Local> get mutableCapturedVariables => null; | 2182 Set<Local> get mutableCapturedVariables => null; |
| 2137 bool isInMutableVariable(Local local) => false; | 2183 bool isInMutableVariable(Local local) => false; |
| 2138 void makeMutableVariable(Local local) {} | 2184 void makeMutableVariable(Local local) {} |
| 2139 void removeMutableVariable(Local local) {} | 2185 void removeMutableVariable(Local local) {} |
| 2140 | 2186 |
| 2141 void _enterClosureEnvironment(ClosureEnvironment env) { | 2187 void _enterClosureEnvironment(ClosureEnvironment env) { |
| 2142 if (env == null) return; | 2188 if (env == null) return; |
| 2143 | 2189 |
| 2144 // Obtain a reference to the function object (this). | 2190 // Obtain a reference to the function object (this). |
| 2145 ir.Primitive thisPrim = addPrimitive(new ir.This()); | 2191 ir.Parameter thisPrim = state.thisParameter; |
| 2146 | 2192 |
| 2147 // Obtain access to the free variables. | 2193 // Obtain access to the free variables. |
| 2148 env.freeVariables.forEach((Local local, ClosureLocation location) { | 2194 env.freeVariables.forEach((Local local, ClosureLocation location) { |
| 2149 if (location.isBox) { | 2195 if (location.isBox) { |
| 2150 // Boxed variables are loaded from their box on-demand. | 2196 // Boxed variables are loaded from their box on-demand. |
| 2151 jsState.boxedVariables[local] = location; | 2197 jsState.boxedVariables[local] = location; |
| 2152 } else { | 2198 } else { |
| 2153 // Unboxed variables are loaded from the function object immediately. | 2199 // Unboxed variables are loaded from the function object immediately. |
| 2154 // This includes BoxLocals which are themselves unboxed variables. | 2200 // This includes BoxLocals which are themselves unboxed variables. |
| 2155 environment.extend(local, | 2201 environment.extend(local, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 ClosureLocation location = jsState.boxedVariables[parameterElement]; | 2242 ClosureLocation location = jsState.boxedVariables[parameterElement]; |
| 2197 if (location != null) { | 2243 if (location != null) { |
| 2198 add(new ir.SetField(environment.lookup(location.box), | 2244 add(new ir.SetField(environment.lookup(location.box), |
| 2199 location.field, | 2245 location.field, |
| 2200 parameter)); | 2246 parameter)); |
| 2201 } else { | 2247 } else { |
| 2202 environment.extend(parameterElement, parameter); | 2248 environment.extend(parameterElement, parameter); |
| 2203 } | 2249 } |
| 2204 } | 2250 } |
| 2205 | 2251 |
| 2252 void _createThisParameter() { |
| 2253 if (Elements.isStaticOrTopLevel(state.currentElement)) return; |
| 2254 if (state.currentElement.isLocal) return; |
| 2255 state.thisParameter = |
| 2256 new ir.Parameter(new ThisParameterLocal(state.currentElement)); |
| 2257 } |
| 2258 |
| 2206 void declareLocalVariable(LocalElement variableElement, | 2259 void declareLocalVariable(LocalElement variableElement, |
| 2207 {ir.Primitive initialValue}) { | 2260 {ir.Primitive initialValue}) { |
| 2208 assert(isOpen); | 2261 assert(isOpen); |
| 2209 if (initialValue == null) { | 2262 if (initialValue == null) { |
| 2210 initialValue = buildNullLiteral(); | 2263 initialValue = buildNullLiteral(); |
| 2211 } | 2264 } |
| 2212 ClosureLocation location = jsState.boxedVariables[variableElement]; | 2265 ClosureLocation location = jsState.boxedVariables[variableElement]; |
| 2213 if (location != null) { | 2266 if (location != null) { |
| 2214 add(new ir.SetField(environment.lookup(location.box), | 2267 add(new ir.SetField(environment.lookup(location.box), |
| 2215 location.field, | 2268 location.field, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 for (VariableElement loopVar in scope.boxedLoopVariables) { | 2352 for (VariableElement loopVar in scope.boxedLoopVariables) { |
| 2300 ClosureLocation location = scope.capturedVariables[loopVar]; | 2353 ClosureLocation location = scope.capturedVariables[loopVar]; |
| 2301 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); | 2354 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); |
| 2302 add(new ir.SetField(newBox, location.field, value)); | 2355 add(new ir.SetField(newBox, location.field, value)); |
| 2303 } | 2356 } |
| 2304 environment.update(scope.box, newBox); | 2357 environment.update(scope.box, newBox); |
| 2305 } | 2358 } |
| 2306 | 2359 |
| 2307 ir.Primitive buildThis() { | 2360 ir.Primitive buildThis() { |
| 2308 if (jsState.receiver != null) return jsState.receiver; | 2361 if (jsState.receiver != null) return jsState.receiver; |
| 2309 return addPrimitive(new ir.This()); | 2362 return state.thisParameter; |
| 2310 } | 2363 } |
| 2311 | 2364 |
| 2312 ir.Primitive buildSuperInvocation(Element target, | 2365 ir.Primitive buildSuperInvocation(Element target, |
| 2313 Selector selector, | 2366 Selector selector, |
| 2314 List<ir.Primitive> arguments) { | 2367 List<ir.Primitive> arguments) { |
| 2315 // Direct calls to FieldElements are currently problematic because the | 2368 // Direct calls to FieldElements are currently problematic because the |
| 2316 // backend will not issue a getter for the field unless it finds a dynamic | 2369 // backend will not issue a getter for the field unless it finds a dynamic |
| 2317 // access that matches its getter. | 2370 // access that matches its getter. |
| 2318 // As a workaround, we generate GetField for this case, although ideally | 2371 // As a workaround, we generate GetField for this case, although ideally |
| 2319 // this should be the result of inlining the field's getter. | 2372 // this should be the result of inlining the field's getter. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2341 receiver, target, selector, k, arguments)); | 2394 receiver, target, selector, k, arguments)); |
| 2342 } | 2395 } |
| 2343 | 2396 |
| 2344 /// Loads parameters to a constructor body into the environment. | 2397 /// Loads parameters to a constructor body into the environment. |
| 2345 /// | 2398 /// |
| 2346 /// The header for a constructor body differs from other functions in that | 2399 /// The header for a constructor body differs from other functions in that |
| 2347 /// some parameters are already boxed, and the box is passed as an argument | 2400 /// some parameters are already boxed, and the box is passed as an argument |
| 2348 /// instead of being created in the header. | 2401 /// instead of being created in the header. |
| 2349 void buildConstructorBodyHeader(Iterable<Local> parameters, | 2402 void buildConstructorBodyHeader(Iterable<Local> parameters, |
| 2350 ClosureScope closureScope) { | 2403 ClosureScope closureScope) { |
| 2404 _createThisParameter(); |
| 2351 for (Local param in parameters) { | 2405 for (Local param in parameters) { |
| 2352 ir.Parameter parameter = createLocalParameter(param); | 2406 ir.Parameter parameter = createLocalParameter(param); |
| 2353 state.functionParameters.add(parameter); | 2407 state.functionParameters.add(parameter); |
| 2354 } | 2408 } |
| 2355 if (closureScope != null) { | 2409 if (closureScope != null) { |
| 2356 jsState.boxedVariables.addAll(closureScope.capturedVariables); | 2410 jsState.boxedVariables.addAll(closureScope.capturedVariables); |
| 2357 } | 2411 } |
| 2358 } | 2412 } |
| 2359 } | 2413 } |
| 2360 | 2414 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 // TODO(johnniwinther): Support passing of [DartType] for the exception. | 2474 // TODO(johnniwinther): Support passing of [DartType] for the exception. |
| 2421 class CatchClauseInfo { | 2475 class CatchClauseInfo { |
| 2422 final LocalVariableElement exceptionVariable; | 2476 final LocalVariableElement exceptionVariable; |
| 2423 final LocalVariableElement stackTraceVariable; | 2477 final LocalVariableElement stackTraceVariable; |
| 2424 final SubbuildFunction buildCatchBlock; | 2478 final SubbuildFunction buildCatchBlock; |
| 2425 | 2479 |
| 2426 CatchClauseInfo({this.exceptionVariable, | 2480 CatchClauseInfo({this.exceptionVariable, |
| 2427 this.stackTraceVariable, | 2481 this.stackTraceVariable, |
| 2428 this.buildCatchBlock}); | 2482 this.buildCatchBlock}); |
| 2429 } | 2483 } |
| OLD | NEW |