| 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 '../compile_time_constants.dart' show BackendConstantEnvironment; | 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; |
| 8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
| 9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; | 9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 /// [function]. | 1007 /// [function]. |
| 1008 ir.Primitive buildStaticFunctionGet(MethodElement function, | 1008 ir.Primitive buildStaticFunctionGet(MethodElement function, |
| 1009 {SourceInformation sourceInformation}) { | 1009 {SourceInformation sourceInformation}) { |
| 1010 return addPrimitive(new ir.GetStatic(function, sourceInformation)); | 1010 return addPrimitive(new ir.GetStatic(function, sourceInformation)); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 /// Create a write access to the static [field] with the [value]. | 1013 /// Create a write access to the static [field] with the [value]. |
| 1014 ir.Primitive buildStaticFieldSet(FieldElement field, | 1014 ir.Primitive buildStaticFieldSet(FieldElement field, |
| 1015 ir.Primitive value, | 1015 ir.Primitive value, |
| 1016 [SourceInformation sourceInformation]) { | 1016 [SourceInformation sourceInformation]) { |
| 1017 add(new ir.SetStatic(field, value, sourceInformation)); | 1017 addPrimitive(new ir.SetStatic(field, value, sourceInformation)); |
| 1018 return value; | 1018 return value; |
| 1019 } | 1019 } |
| 1020 | 1020 |
| 1021 /// Create a setter invocation of the static [setter] with the [value]. | 1021 /// Create a setter invocation of the static [setter] with the [value]. |
| 1022 ir.Primitive buildStaticSetterSet(MethodElement setter, | 1022 ir.Primitive buildStaticSetterSet(MethodElement setter, |
| 1023 ir.Primitive value, | 1023 ir.Primitive value, |
| 1024 {SourceInformation sourceInformation}) { | 1024 {SourceInformation sourceInformation}) { |
| 1025 Selector selector = new Selector.setter(setter.name, setter.library); | 1025 Selector selector = new Selector.setter(setter.name, setter.library); |
| 1026 _buildInvokeStatic( | 1026 _buildInvokeStatic( |
| 1027 setter, selector, <ir.Primitive>[value], sourceInformation); | 1027 setter, selector, <ir.Primitive>[value], sourceInformation); |
| (...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2284 } | 2284 } |
| 2285 | 2285 |
| 2286 /// Add the given function parameter to the IR, and bind it in the environment | 2286 /// Add the given function parameter to the IR, and bind it in the environment |
| 2287 /// or put it in its box, if necessary. | 2287 /// or put it in its box, if necessary. |
| 2288 void _createFunctionParameter(Local parameterElement) { | 2288 void _createFunctionParameter(Local parameterElement) { |
| 2289 ir.Parameter parameter = new ir.Parameter(parameterElement); | 2289 ir.Parameter parameter = new ir.Parameter(parameterElement); |
| 2290 _parameters.add(parameter); | 2290 _parameters.add(parameter); |
| 2291 state.functionParameters.add(parameter); | 2291 state.functionParameters.add(parameter); |
| 2292 ClosureLocation location = state.boxedVariables[parameterElement]; | 2292 ClosureLocation location = state.boxedVariables[parameterElement]; |
| 2293 if (location != null) { | 2293 if (location != null) { |
| 2294 add(new ir.SetField(environment.lookup(location.box), | 2294 addPrimitive(new ir.SetField( |
| 2295 location.field, | 2295 environment.lookup(location.box), |
| 2296 parameter)); | 2296 location.field, |
| 2297 parameter)); |
| 2297 } else { | 2298 } else { |
| 2298 environment.extend(parameterElement, parameter); | 2299 environment.extend(parameterElement, parameter); |
| 2299 } | 2300 } |
| 2300 } | 2301 } |
| 2301 | 2302 |
| 2302 void _createThisParameter() { | 2303 void _createThisParameter() { |
| 2303 assert(state.thisParameter == null); | 2304 assert(state.thisParameter == null); |
| 2304 if (Elements.isStaticOrTopLevel(state.currentElement)) return; | 2305 if (Elements.isStaticOrTopLevel(state.currentElement)) return; |
| 2305 if (state.currentElement.isLocal) return; | 2306 if (state.currentElement.isLocal) return; |
| 2306 state.thisParameter = | 2307 state.thisParameter = |
| 2307 new ir.Parameter(new ThisParameterLocal(state.currentElement)); | 2308 new ir.Parameter(new ThisParameterLocal(state.currentElement)); |
| 2308 } | 2309 } |
| 2309 | 2310 |
| 2310 void declareLocalVariable(LocalElement variableElement, | 2311 void declareLocalVariable(LocalElement variableElement, |
| 2311 {ir.Primitive initialValue}) { | 2312 {ir.Primitive initialValue}) { |
| 2312 assert(isOpen); | 2313 assert(isOpen); |
| 2313 if (initialValue == null) { | 2314 if (initialValue == null) { |
| 2314 initialValue = buildNullConstant(); | 2315 initialValue = buildNullConstant(); |
| 2315 } | 2316 } |
| 2316 ClosureLocation location = state.boxedVariables[variableElement]; | 2317 ClosureLocation location = state.boxedVariables[variableElement]; |
| 2317 if (location != null) { | 2318 if (location != null) { |
| 2318 add(new ir.SetField(environment.lookup(location.box), | 2319 addPrimitive(new ir.SetField( |
| 2319 location.field, | 2320 environment.lookup(location.box), |
| 2320 initialValue)); | 2321 location.field, |
| 2322 initialValue)); |
| 2321 } else if (isInMutableVariable(variableElement)) { | 2323 } else if (isInMutableVariable(variableElement)) { |
| 2322 add(new ir.LetMutable(getMutableVariable(variableElement), | 2324 add(new ir.LetMutable( |
| 2323 initialValue)); | 2325 getMutableVariable(variableElement), |
| 2326 initialValue)); |
| 2324 } else { | 2327 } else { |
| 2325 initialValue.useElementAsHint(variableElement); | 2328 initialValue.useElementAsHint(variableElement); |
| 2326 environment.extend(variableElement, initialValue); | 2329 environment.extend(variableElement, initialValue); |
| 2327 } | 2330 } |
| 2328 } | 2331 } |
| 2329 | 2332 |
| 2330 /// Add [functionElement] to the environment with provided [definition]. | 2333 /// Add [functionElement] to the environment with provided [definition]. |
| 2331 void declareLocalFunction(LocalFunctionElement functionElement, | 2334 void declareLocalFunction(LocalFunctionElement functionElement, |
| 2332 ClosureClassElement classElement, | 2335 ClosureClassElement classElement, |
| 2333 SourceInformation sourceInformation) { | 2336 SourceInformation sourceInformation) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 return environment.lookup(local); | 2369 return environment.lookup(local); |
| 2367 } | 2370 } |
| 2368 } | 2371 } |
| 2369 | 2372 |
| 2370 /// Create a write access to [local] variable or parameter with the provided | 2373 /// Create a write access to [local] variable or parameter with the provided |
| 2371 /// [value]. | 2374 /// [value]. |
| 2372 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) { | 2375 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) { |
| 2373 assert(isOpen); | 2376 assert(isOpen); |
| 2374 ClosureLocation location = state.boxedVariables[local]; | 2377 ClosureLocation location = state.boxedVariables[local]; |
| 2375 if (location != null) { | 2378 if (location != null) { |
| 2376 add(new ir.SetField(environment.lookup(location.box), | 2379 addPrimitive(new ir.SetField( |
| 2377 location.field, | 2380 environment.lookup(location.box), |
| 2378 value)); | 2381 location.field, |
| 2382 value)); |
| 2379 } else if (isInMutableVariable(local)) { | 2383 } else if (isInMutableVariable(local)) { |
| 2380 add(new ir.SetMutableVariable(getMutableVariable(local), value)); | 2384 addPrimitive(new ir.SetMutableVariable( |
| 2385 getMutableVariable(local), value)); |
| 2381 } else { | 2386 } else { |
| 2382 value.useElementAsHint(local); | 2387 value.useElementAsHint(local); |
| 2383 environment.update(local, value); | 2388 environment.update(local, value); |
| 2384 } | 2389 } |
| 2385 return value; | 2390 return value; |
| 2386 } | 2391 } |
| 2387 | 2392 |
| 2388 /// Called before building the initializer of a for-loop. | 2393 /// Called before building the initializer of a for-loop. |
| 2389 /// | 2394 /// |
| 2390 /// The loop variables will subsequently be declared using | 2395 /// The loop variables will subsequently be declared using |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2414 if (scope == null) return; | 2419 if (scope == null) return; |
| 2415 // If there are no boxed loop variables, then the box is created inside the | 2420 // If there are no boxed loop variables, then the box is created inside the |
| 2416 // body, so there is no need to explicitly renew it. | 2421 // body, so there is no need to explicitly renew it. |
| 2417 if (scope.boxedLoopVariables.isEmpty) return; | 2422 if (scope.boxedLoopVariables.isEmpty) return; |
| 2418 ir.Primitive box = environment.lookup(scope.box); | 2423 ir.Primitive box = environment.lookup(scope.box); |
| 2419 ir.Primitive newBox = addPrimitive(new ir.CreateBox()); | 2424 ir.Primitive newBox = addPrimitive(new ir.CreateBox()); |
| 2420 newBox.useElementAsHint(scope.box); | 2425 newBox.useElementAsHint(scope.box); |
| 2421 for (VariableElement loopVar in scope.boxedLoopVariables) { | 2426 for (VariableElement loopVar in scope.boxedLoopVariables) { |
| 2422 ClosureLocation location = scope.capturedVariables[loopVar]; | 2427 ClosureLocation location = scope.capturedVariables[loopVar]; |
| 2423 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); | 2428 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); |
| 2424 add(new ir.SetField(newBox, location.field, value)); | 2429 addPrimitive(new ir.SetField(newBox, location.field, value)); |
| 2425 } | 2430 } |
| 2426 environment.update(scope.box, newBox); | 2431 environment.update(scope.box, newBox); |
| 2427 } | 2432 } |
| 2428 | 2433 |
| 2429 /// Creates an access to the receiver from the current (or enclosing) method. | 2434 /// Creates an access to the receiver from the current (or enclosing) method. |
| 2430 /// | 2435 /// |
| 2431 /// If inside a closure class, [buildThis] will redirect access through | 2436 /// If inside a closure class, [buildThis] will redirect access through |
| 2432 /// closure fields in order to access the receiver from the enclosing method. | 2437 /// closure fields in order to access the receiver from the enclosing method. |
| 2433 ir.Primitive buildThis() { | 2438 ir.Primitive buildThis() { |
| 2434 if (state.enclosingThis != null) return state.enclosingThis; | 2439 if (state.enclosingThis != null) return state.enclosingThis; |
| 2435 assert(state.thisParameter != null); | 2440 assert(state.thisParameter != null); |
| 2436 return state.thisParameter; | 2441 return state.thisParameter; |
| 2437 } | 2442 } |
| 2438 | 2443 |
| 2439 ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) { | 2444 ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) { |
| 2440 return addPrimitive(new ir.GetField(receiver, target)); | 2445 return addPrimitive(new ir.GetField(receiver, target)); |
| 2441 } | 2446 } |
| 2442 | 2447 |
| 2443 void buildFieldSet(ir.Primitive receiver, | 2448 void buildFieldSet(ir.Primitive receiver, |
| 2444 FieldElement target, | 2449 FieldElement target, |
| 2445 ir.Primitive value) { | 2450 ir.Primitive value) { |
| 2446 add(new ir.SetField(receiver, target, value)); | 2451 addPrimitive(new ir.SetField(receiver, target, value)); |
| 2447 } | 2452 } |
| 2448 | 2453 |
| 2449 ir.Primitive buildSuperFieldGet(FieldElement target) { | 2454 ir.Primitive buildSuperFieldGet(FieldElement target) { |
| 2450 return addPrimitive(new ir.GetField(buildThis(), target)); | 2455 return addPrimitive(new ir.GetField(buildThis(), target)); |
| 2451 } | 2456 } |
| 2452 | 2457 |
| 2453 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2458 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { |
| 2454 add(new ir.SetField(buildThis(), target, value)); | 2459 addPrimitive(new ir.SetField(buildThis(), target, value)); |
| 2455 return value; | 2460 return value; |
| 2456 } | 2461 } |
| 2457 | 2462 |
| 2458 ir.Primitive buildInvokeDirectly(FunctionElement target, | 2463 ir.Primitive buildInvokeDirectly(FunctionElement target, |
| 2459 ir.Primitive receiver, | 2464 ir.Primitive receiver, |
| 2460 List<ir.Primitive> arguments, | 2465 List<ir.Primitive> arguments, |
| 2461 {SourceInformation sourceInformation}) { | 2466 {SourceInformation sourceInformation}) { |
| 2462 assert(isOpen); | 2467 assert(isOpen); |
| 2463 Selector selector = | 2468 Selector selector = |
| 2464 new Selector.call(target.name, target.library, arguments.length); | 2469 new Selector.call(target.name, target.library, arguments.length); |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2755 } | 2760 } |
| 2756 | 2761 |
| 2757 class SwitchCaseInfo { | 2762 class SwitchCaseInfo { |
| 2758 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2763 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2759 final SubbuildFunction buildBody; | 2764 final SubbuildFunction buildBody; |
| 2760 | 2765 |
| 2761 SwitchCaseInfo(this.buildBody); | 2766 SwitchCaseInfo(this.buildBody); |
| 2762 | 2767 |
| 2763 void addConstant(ir.Primitive constant) => constants.add(constant); | 2768 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2764 } | 2769 } |
| OLD | NEW |