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 |