Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1011383003: Use an explicit 'this' parameter instead of 'This' nodes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: test updates Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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;
222 223
223 final List<ir.Definition> functionParameters = <ir.Definition>[]; 224 final List<ir.Definition> functionParameters = <ir.Definition>[];
224 225
225 IrBuilderDelimitedState(this.constantSystem, this.currentElement); 226 IrBuilderDelimitedState(this.constantSystem, this.currentElement);
227
228 ir.Parameter get thisParameter => _thisParameter;
229 void set thisParameter(ir.Parameter value) {
230 assert(_thisParameter == null);
231 _thisParameter = value;
232 }
233 }
234
235 class ThisParameterLocal implements Local {
236 final ExecutableElement executableContext;
237 ThisParameterLocal(this.executableContext);
238 String get name => 'this';
239 toString() => 'ThisParameterLocal($executableContext)';
226 } 240 }
227 241
228 /// A factory for building the cps IR. 242 /// A factory for building the cps IR.
229 /// 243 ///
230 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured 244 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured
231 /// variables in different ways. 245 /// variables in different ways.
232 abstract class IrBuilder { 246 abstract class IrBuilder {
233 IrBuilder _makeInstance(); 247 IrBuilder _makeInstance();
234 248
235 // TODO(johnniwinther): Remove this from the [IrBuilder]. 249 // TODO(johnniwinther): Remove this from the [IrBuilder].
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 void _enterForLoopBody(ClosureScope scope, 303 void _enterForLoopBody(ClosureScope scope,
290 List<LocalElement> loopVariables); 304 List<LocalElement> loopVariables);
291 305
292 /// Called before building the update of a for-loop. 306 /// Called before building the update of a for-loop.
293 void _enterForLoopUpdate(ClosureScope scope, 307 void _enterForLoopUpdate(ClosureScope scope,
294 List<LocalElement> loopVariables); 308 List<LocalElement> loopVariables);
295 309
296 /// Add the given function parameter to the IR, and bind it in the environment 310 /// Add the given function parameter to the IR, and bind it in the environment
297 /// or put it in its box, if necessary. 311 /// or put it in its box, if necessary.
298 void _createFunctionParameter(ParameterElement parameterElement); 312 void _createFunctionParameter(ParameterElement parameterElement);
313 void _createThisParameter();
299 314
300 /// Creates an access to the receiver from the current (or enclosing) method. 315 /// Creates an access to the receiver from the current (or enclosing) method.
301 /// 316 ///
302 /// If inside a closure class, [buildThis] will redirect access through 317 /// If inside a closure class, [buildThis] will redirect access through
303 /// closure fields in order to access the receiver from the enclosing method. 318 /// closure fields in order to access the receiver from the enclosing method.
304 ir.Primitive buildThis(); 319 ir.Primitive buildThis();
305 320
306 // TODO(johnniwinther): Make these field final and remove the default values 321 // TODO(johnniwinther): Make these field final and remove the default values
307 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. 322 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin.
308 323
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 bool get isOpen => _root == null || _current != null; 410 bool get isOpen => _root == null || _current != null;
396 411
397 412
398 void buildFieldInitializerHeader({ClosureScope closureScope}) { 413 void buildFieldInitializerHeader({ClosureScope closureScope}) {
399 _enterScope(closureScope); 414 _enterScope(closureScope);
400 } 415 }
401 416
402 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters, 417 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters,
403 {ClosureScope closureScope, 418 {ClosureScope closureScope,
404 ClosureEnvironment env}) { 419 ClosureEnvironment env}) {
420 _createThisParameter();
405 _enterClosureEnvironment(env); 421 _enterClosureEnvironment(env);
406 _enterScope(closureScope); 422 _enterScope(closureScope);
407 parameters.forEach(_createFunctionParameter); 423 parameters.forEach(_createFunctionParameter);
408 return _parameters; 424 return _parameters;
409 } 425 }
410 426
411 /// Creates a parameter for [local] and adds it to the current environment. 427 /// Creates a parameter for [local] and adds it to the current environment.
412 ir.Parameter createLocalParameter(Local local) { 428 ir.Parameter createLocalParameter(Local local) {
413 ir.Parameter parameter = new ir.Parameter(local); 429 ir.Parameter parameter = new ir.Parameter(local);
414 _parameters.add(parameter); 430 _parameters.add(parameter);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 ir.FunctionDefinition makeFunctionDefinition( 667 ir.FunctionDefinition makeFunctionDefinition(
652 List<ConstantExpression> defaults) { 668 List<ConstantExpression> defaults) {
653 FunctionElement element = state.currentElement; 669 FunctionElement element = state.currentElement;
654 if (element.isAbstract || element.isExternal) { 670 if (element.isAbstract || element.isExternal) {
655 assert(invariant(element, _root == null, 671 assert(invariant(element, _root == null,
656 message: "Non-empty body for abstract method $element: $_root")); 672 message: "Non-empty body for abstract method $element: $_root"));
657 assert(invariant(element, state.localConstants.isEmpty, 673 assert(invariant(element, state.localConstants.isEmpty,
658 message: "Local constants for abstract method $element: " 674 message: "Local constants for abstract method $element: "
659 "${state.localConstants}")); 675 "${state.localConstants}"));
660 return new ir.FunctionDefinition.abstract( 676 return new ir.FunctionDefinition.abstract(
661 element, state.functionParameters, defaults); 677 element, state.thisParameter, state.functionParameters, defaults);
662 } else { 678 } else {
663 ir.RunnableBody body = makeRunnableBody(); 679 ir.RunnableBody body = makeRunnableBody();
664 return new ir.FunctionDefinition( 680 return new ir.FunctionDefinition(
665 element, state.functionParameters, body, 681 element, state.thisParameter, state.functionParameters, body,
666 state.localConstants, defaults); 682 state.localConstants, defaults);
667 } 683 }
668 } 684 }
669 685
670 /// Create a constructor definition without a body, for representing 686 /// Create a constructor definition without a body, for representing
671 /// external constructors declarations. 687 /// external constructors declarations.
672 ir.ConstructorDefinition makeAbstractConstructorDefinition( 688 ir.ConstructorDefinition makeAbstractConstructorDefinition(
673 List<ConstantExpression> defaults) { 689 List<ConstantExpression> defaults) {
674 FunctionElement element = state.currentElement; 690 FunctionElement element = state.currentElement;
675 assert(invariant(element, _root == null, 691 assert(invariant(element, _root == null,
676 message: "Non-empty body for external constructor $element: $_root")); 692 message: "Non-empty body for external constructor $element: $_root"));
677 assert(invariant(element, state.localConstants.isEmpty, 693 assert(invariant(element, state.localConstants.isEmpty,
678 message: "Local constants for external constructor $element: " 694 message: "Local constants for external constructor $element: "
679 "${state.localConstants}")); 695 "${state.localConstants}"));
680 return new ir.ConstructorDefinition.abstract( 696 return new ir.ConstructorDefinition.abstract(
681 element, state.functionParameters, defaults); 697 element, state.functionParameters, defaults);
682 } 698 }
683 699
684 ir.ConstructorDefinition makeConstructorDefinition( 700 ir.ConstructorDefinition makeConstructorDefinition(
685 List<ConstantExpression> defaults, List<ir.Initializer> initializers) { 701 List<ConstantExpression> defaults, List<ir.Initializer> initializers) {
686 FunctionElement element = state.currentElement; 702 FunctionElement element = state.currentElement;
687 ir.RunnableBody body = makeRunnableBody(); 703 ir.RunnableBody body = makeRunnableBody();
688 return new ir.ConstructorDefinition( 704 return new ir.ConstructorDefinition(
689 element, state.functionParameters, body, initializers, 705 element, state.thisParameter, state.functionParameters, body, initialize rs,
690 state.localConstants, defaults); 706 state.localConstants, defaults);
691 } 707 }
692 708
693 /// Create a super invocation where the method name and the argument structure 709 /// Create a super invocation where the method name and the argument structure
694 /// are defined by [selector] and the argument values are defined by 710 /// are defined by [selector] and the argument values are defined by
695 /// [arguments]. 711 /// [arguments].
696 ir.Primitive buildSuperInvocation(Element target, 712 ir.Primitive buildSuperInvocation(Element target,
697 Selector selector, 713 Selector selector,
698 List<ir.Primitive> arguments); 714 List<ir.Primitive> arguments);
699 715
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 ir.Parameter parameter = new ir.Parameter(parameterElement); 2046 ir.Parameter parameter = new ir.Parameter(parameterElement);
2031 _parameters.add(parameter); 2047 _parameters.add(parameter);
2032 if (isInMutableVariable(parameterElement)) { 2048 if (isInMutableVariable(parameterElement)) {
2033 state.functionParameters.add(getMutableVariable(parameterElement)); 2049 state.functionParameters.add(getMutableVariable(parameterElement));
2034 } else { 2050 } else {
2035 state.functionParameters.add(parameter); 2051 state.functionParameters.add(parameter);
2036 environment.extend(parameterElement, parameter); 2052 environment.extend(parameterElement, parameter);
2037 } 2053 }
2038 } 2054 }
2039 2055
2056 void _createThisParameter() {
2057 if (state.currentElement.isGenerativeConstructor ||
2058 !(Elements.isStaticOrTopLevel(state.currentElement) ||
2059 state.currentElement.isLocal)) {
2060 state.thisParameter =
2061 new ir.Parameter(new ThisParameterLocal(state.currentElement));
2062 }
2063 }
2064
2040 void declareLocalVariable(LocalVariableElement variableElement, 2065 void declareLocalVariable(LocalVariableElement variableElement,
2041 {ir.Primitive initialValue}) { 2066 {ir.Primitive initialValue}) {
2042 assert(isOpen); 2067 assert(isOpen);
2043 if (initialValue == null) { 2068 if (initialValue == null) {
2044 initialValue = buildNullLiteral(); 2069 initialValue = buildNullLiteral();
2045 } 2070 }
2046 if (isInMutableVariable(variableElement)) { 2071 if (isInMutableVariable(variableElement)) {
2047 add(new ir.LetMutable(getMutableVariable(variableElement), 2072 add(new ir.LetMutable(getMutableVariable(variableElement),
2048 initialValue)); 2073 initialValue));
2049 } else { 2074 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2095 if (isInMutableVariable(local)) { 2120 if (isInMutableVariable(local)) {
2096 add(new ir.SetMutableVariable(getMutableVariable(local), value)); 2121 add(new ir.SetMutableVariable(getMutableVariable(local), value));
2097 } else { 2122 } else {
2098 value.useElementAsHint(local); 2123 value.useElementAsHint(local);
2099 environment.update(local, value); 2124 environment.update(local, value);
2100 } 2125 }
2101 return value; 2126 return value;
2102 } 2127 }
2103 2128
2104 ir.Primitive buildThis() { 2129 ir.Primitive buildThis() {
2105 ir.Primitive thisPrim = new ir.This(); 2130 return state.thisParameter;
2106 add(new ir.LetPrim(thisPrim));
2107 return thisPrim;
2108 } 2131 }
2109 2132
2110 ir.Primitive buildSuperInvocation(Element target, 2133 ir.Primitive buildSuperInvocation(Element target,
2111 Selector selector, 2134 Selector selector,
2112 List<ir.Primitive> arguments) { 2135 List<ir.Primitive> arguments) {
2113 return _buildInvokeSuper(target, selector, arguments); 2136 return _buildInvokeSuper(target, selector, arguments);
2114 } 2137 }
2115 2138
2116 } 2139 }
2117 2140
(...skipping 27 matching lines...) Expand all
2145 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null; 2168 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null;
2146 Set<Local> get mutableCapturedVariables => null; 2169 Set<Local> get mutableCapturedVariables => null;
2147 bool isInMutableVariable(Local local) => false; 2170 bool isInMutableVariable(Local local) => false;
2148 void makeMutableVariable(Local local) {} 2171 void makeMutableVariable(Local local) {}
2149 void removeMutableVariable(Local local) {} 2172 void removeMutableVariable(Local local) {}
2150 2173
2151 void _enterClosureEnvironment(ClosureEnvironment env) { 2174 void _enterClosureEnvironment(ClosureEnvironment env) {
2152 if (env == null) return; 2175 if (env == null) return;
2153 2176
2154 // Obtain a reference to the function object (this). 2177 // Obtain a reference to the function object (this).
2155 ir.Primitive thisPrim = new ir.This(); 2178 ir.Parameter thisPrim = state.thisParameter;
2156 add(new ir.LetPrim(thisPrim));
2157 2179
2158 // Obtain access to the free variables. 2180 // Obtain access to the free variables.
2159 env.freeVariables.forEach((Local local, ClosureLocation location) { 2181 env.freeVariables.forEach((Local local, ClosureLocation location) {
2160 if (location.isBox) { 2182 if (location.isBox) {
2161 // Boxed variables are loaded from their box on-demand. 2183 // Boxed variables are loaded from their box on-demand.
2162 jsState.boxedVariables[local] = location; 2184 jsState.boxedVariables[local] = location;
2163 } else { 2185 } else {
2164 // Unboxed variables are loaded from the function object immediately. 2186 // Unboxed variables are loaded from the function object immediately.
2165 // This includes BoxLocals which are themselves unboxed variables. 2187 // This includes BoxLocals which are themselves unboxed variables.
2166 ir.Primitive load = new ir.GetField(thisPrim, location.field); 2188 ir.Primitive load = new ir.GetField(thisPrim, location.field);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 ClosureLocation location = jsState.boxedVariables[parameterElement]; 2231 ClosureLocation location = jsState.boxedVariables[parameterElement];
2210 if (location != null) { 2232 if (location != null) {
2211 add(new ir.SetField(environment.lookup(location.box), 2233 add(new ir.SetField(environment.lookup(location.box),
2212 location.field, 2234 location.field,
2213 parameter)); 2235 parameter));
2214 } else { 2236 } else {
2215 environment.extend(parameterElement, parameter); 2237 environment.extend(parameterElement, parameter);
2216 } 2238 }
2217 } 2239 }
2218 2240
2241 void _createThisParameter() {
2242 if (Element.isStaticOrTopLevel(state.currentElement)) return;
2243 if (state.currentElement.isLocal) return;
2244 state.thisParameter =
2245 new ir.Parameter(new ThisParameterLocal(state.currentElement));
2246 }
2247
2219 void declareLocalVariable(LocalElement variableElement, 2248 void declareLocalVariable(LocalElement variableElement,
2220 {ir.Primitive initialValue}) { 2249 {ir.Primitive initialValue}) {
2221 assert(isOpen); 2250 assert(isOpen);
2222 if (initialValue == null) { 2251 if (initialValue == null) {
2223 initialValue = buildNullLiteral(); 2252 initialValue = buildNullLiteral();
2224 } 2253 }
2225 ClosureLocation location = jsState.boxedVariables[variableElement]; 2254 ClosureLocation location = jsState.boxedVariables[variableElement];
2226 if (location != null) { 2255 if (location != null) {
2227 add(new ir.SetField(environment.lookup(location.box), 2256 add(new ir.SetField(environment.lookup(location.box),
2228 location.field, 2257 location.field,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 ClosureLocation location = scope.capturedVariables[loopVar]; 2346 ClosureLocation location = scope.capturedVariables[loopVar];
2318 ir.Primitive get = new ir.GetField(box, location.field); 2347 ir.Primitive get = new ir.GetField(box, location.field);
2319 add(new ir.LetPrim(get)); 2348 add(new ir.LetPrim(get));
2320 add(new ir.SetField(newBox, location.field, get)); 2349 add(new ir.SetField(newBox, location.field, get));
2321 } 2350 }
2322 environment.update(scope.box, newBox); 2351 environment.update(scope.box, newBox);
2323 } 2352 }
2324 2353
2325 ir.Primitive buildThis() { 2354 ir.Primitive buildThis() {
2326 if (jsState.receiver != null) return jsState.receiver; 2355 if (jsState.receiver != null) return jsState.receiver;
2327 ir.Primitive thisPrim = new ir.This(); 2356 return state.thisParameter;
2328 add(new ir.LetPrim(thisPrim));
2329 return thisPrim;
2330 } 2357 }
2331 2358
2332 ir.Primitive buildSuperInvocation(Element target, 2359 ir.Primitive buildSuperInvocation(Element target,
2333 Selector selector, 2360 Selector selector,
2334 List<ir.Primitive> arguments) { 2361 List<ir.Primitive> arguments) {
2335 // Direct calls to FieldElements are currently problematic because the 2362 // Direct calls to FieldElements are currently problematic because the
2336 // backend will not issue a getter for the field unless it finds a dynamic 2363 // backend will not issue a getter for the field unless it finds a dynamic
2337 // access that matches its getter. 2364 // access that matches its getter.
2338 // As a workaround, we generate GetField for this case, although ideally 2365 // As a workaround, we generate GetField for this case, although ideally
2339 // this should be the result of inlining the field's getter. 2366 // this should be the result of inlining the field's getter.
(...skipping 23 matching lines...) Expand all
2363 receiver, target, selector, k, arguments)); 2390 receiver, target, selector, k, arguments));
2364 } 2391 }
2365 2392
2366 /// Loads parameters to a constructor body into the environment. 2393 /// Loads parameters to a constructor body into the environment.
2367 /// 2394 ///
2368 /// The header for a constructor body differs from other functions in that 2395 /// The header for a constructor body differs from other functions in that
2369 /// some parameters are already boxed, and the box is passed as an argument 2396 /// some parameters are already boxed, and the box is passed as an argument
2370 /// instead of being created in the header. 2397 /// instead of being created in the header.
2371 void buildConstructorBodyHeader(Iterable<Local> parameters, 2398 void buildConstructorBodyHeader(Iterable<Local> parameters,
2372 ClosureScope closureScope) { 2399 ClosureScope closureScope) {
2400 _createThisParameter();
2373 for (Local param in parameters) { 2401 for (Local param in parameters) {
2374 ir.Parameter parameter = createLocalParameter(param); 2402 ir.Parameter parameter = createLocalParameter(param);
2375 state.functionParameters.add(parameter); 2403 state.functionParameters.add(parameter);
2376 } 2404 }
2377 if (closureScope != null) { 2405 if (closureScope != null) {
2378 jsState.boxedVariables.addAll(closureScope.capturedVariables); 2406 jsState.boxedVariables.addAll(closureScope.capturedVariables);
2379 } 2407 }
2380 } 2408 }
2381 } 2409 }
2382 2410
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 // TODO(johnniwinther): Support passing of [DartType] for the exception. 2470 // TODO(johnniwinther): Support passing of [DartType] for the exception.
2443 class CatchClauseInfo { 2471 class CatchClauseInfo {
2444 final LocalVariableElement exceptionVariable; 2472 final LocalVariableElement exceptionVariable;
2445 final LocalVariableElement stackTraceVariable; 2473 final LocalVariableElement stackTraceVariable;
2446 final SubbuildFunction buildCatchBlock; 2474 final SubbuildFunction buildCatchBlock;
2447 2475
2448 CatchClauseInfo({this.exceptionVariable, 2476 CatchClauseInfo({this.exceptionVariable,
2449 this.stackTraceVariable, 2477 this.stackTraceVariable,
2450 this.buildCatchBlock}); 2478 this.buildCatchBlock});
2451 } 2479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698