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

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

Issue 1001793002: dart2js: Add support for do/while loops to the CPS backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Ummm, semicolon? 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 SubbuildFunction buildBody, 1218 SubbuildFunction buildBody,
1219 JumpTarget target, 1219 JumpTarget target,
1220 ClosureScope closureScope}) { 1220 ClosureScope closureScope}) {
1221 assert(isOpen); 1221 assert(isOpen);
1222 // While loops use four named continuations: the entry to the body, the 1222 // While loops use four named continuations: the entry to the body, the
1223 // loop exit, the loop back edge (continue), and the loop exit (break). 1223 // loop exit, the loop back edge (continue), and the loop exit (break).
1224 // The CPS translation of [[while (condition) body; successor]] is: 1224 // The CPS translation of [[while (condition) body; successor]] is:
1225 // 1225 //
1226 // let cont continue(x, ...) = 1226 // let cont continue(x, ...) =
1227 // let prim cond = [[condition]] in 1227 // let prim cond = [[condition]] in
1228 // let cont break() = [[successor]] in 1228 // let cont break(x, ...) = [[successor]] in
1229 // let cont exit() = break(v, ...) in 1229 // let cont exit() = break(v, ...)
1230 // let cont body() = [[body]]; continue(v, ...) in 1230 // and body() = [[body]]; continue(v, ...)
1231 // branch cond (body, exit) in 1231 // in branch cond (body, exit)
1232 // continue(v, ...) 1232 // in continue(v, ...)
1233 // 1233 //
1234 // If there are no breaks in the body, the break continuation is inlined 1234 // If there are no breaks in the body, the break continuation is inlined
1235 // in the exit continuation (i.e., the translation of the successor 1235 // in the exit continuation (i.e., the translation of the successor
1236 // statement occurs in the exit continuation). 1236 // statement occurs in the exit continuation).
1237 1237
1238 // The condition and body are delimited. 1238 // The condition and body are delimited.
1239 IrBuilder condBuilder = makeRecursiveBuilder(); 1239 IrBuilder condBuilder = makeRecursiveBuilder();
1240 ir.Primitive condition = buildCondition(condBuilder); 1240 ir.Primitive condition = buildCondition(condBuilder);
1241 1241
1242 JumpCollector breakCollector = new JumpCollector(target); 1242 JumpCollector breakCollector = new JumpCollector(target);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 breakCollector.addJump(this); 1290 breakCollector.addJump(this);
1291 letJoin.continuations = 1291 letJoin.continuations =
1292 <ir.Continuation>[createJoin(environment.length, breakCollector)]; 1292 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1293 _current = letJoin; 1293 _current = letJoin;
1294 } else { 1294 } else {
1295 _current = condBuilder._current; 1295 _current = condBuilder._current;
1296 environment = condBuilder.environment; 1296 environment = condBuilder.environment;
1297 } 1297 }
1298 } 1298 }
1299 1299
1300
1301 /// Creates a do-while loop.
1302 ///
1303 /// The body and condition are created by [buildBody] and [buildCondition].
1304 /// The jump target [target] is the target of `break` and `continue`
1305 /// statements in the body that have the loop as their target.
1306 /// [closureScope] contains all the variables declared in the loop (but not
1307 /// declared in some inner closure scope).
1308 void buildDoWhile({SubbuildFunction buildBody,
1309 SubbuildFunction buildCondition,
1310 JumpTarget target,
1311 ClosureScope closureScope}) {
1312 assert(isOpen);
1313 // The CPS translation of [[do body; while (condition); successor]] is:
1314 //
1315 // let cont break(x, ...) = [[successor]] in
1316 // let cont rec loop(x, ...) =
1317 // let cont continue(x, ...) =
1318 // let prim cond = [[condition]] in
1319 // let cont exit() = break(v, ...)
1320 // and repeat() = loop(v, ...)
1321 // in branch cond (repeat, exit)
1322 // in [[body]]; continue(v, ...)
1323 // in loop(v, ...)
1324 IrBuilder bodyBuilder = makeRecursiveBuilder();
1325 IrBuilder continueBuilder = bodyBuilder.makeRecursiveBuilder();
1326
1327 // Construct the continue continuation (i.e., the condition).
1328 // <Continue> =
1329 // let prim cond = [[condition]] in
1330 // let cont exit() = break(v, ...)
1331 // and repeat() = loop(v, ...)
1332 // in branch cond (repeat, exit)
1333 ir.Primitive condition = buildCondition(continueBuilder);
1334 // Use a delimited IrBuilder for the exit continuation's body so that
1335 // we can capture the break with the body's break collector.
1336 ir.Continuation exitContinuation = new ir.Continuation([]);
1337 IrBuilder exitBuilder = continueBuilder.makeDelimitedBuilder();
1338 ir.Continuation repeatContinuation = new ir.Continuation([]);
1339 ir.InvokeContinuation invokeLoop =
1340 new ir.InvokeContinuation.uninitialized(recursive: true);
1341 invokeLoop.arguments =
1342 continueBuilder.environment.index2value.map(
1343 (ir.Primitive value) => new ir.Reference(value)).toList();
1344 repeatContinuation.body = invokeLoop;
1345 continueBuilder.add(
1346 new ir.LetCont.many(<ir.Continuation>[exitContinuation,
1347 repeatContinuation],
1348 new ir.Branch(new ir.IsTrue(condition),
1349 repeatContinuation,
1350 exitContinuation)));
1351 ir.Continuation continueContinuation =
1352 new ir.Continuation(continueBuilder._parameters);
1353 continueContinuation.body = continueBuilder._root;
1354
1355 // Construct the loop continuation (i.e., the body and condition).
1356 // <Loop> =
1357 // let cont continue(x, ...) =
1358 // <Continue>
1359 // in [[body]]; continue(v, ...)
1360 JumpCollector breakCollector = new JumpCollector(target);
1361 JumpCollector continueCollector = new JumpCollector(target);
1362 state.breakCollectors.add(breakCollector);
1363 state.continueCollectors.add(continueCollector);
1364 bodyBuilder._enterScope(closureScope);
1365 buildBody(bodyBuilder);
1366 assert(state.breakCollectors.last == breakCollector);
1367 assert(state.continueCollectors.last == continueCollector);
1368 state.breakCollectors.removeLast();
1369 state.continueCollectors.removeLast();
1370 // Add the jump from the loop's exit to the break condition. It is only
1371 // here where the exitBuilder's root is non-null and we can set the
1372 // exitContinuation's body.
1373 breakCollector.addJump(exitBuilder);
1374 exitContinuation.body = exitBuilder._root;
1375 if (bodyBuilder.isOpen) {
1376 continueCollector.addJump(bodyBuilder);
1377 }
1378 invokeFullJoin(continueContinuation, continueCollector, recursive: false);
1379 ir.Continuation loopContinuation =
1380 new ir.Continuation(bodyBuilder._parameters);
1381 loopContinuation.isRecursive = true;
1382 loopContinuation.body =
1383 new ir.LetCont(continueContinuation, bodyBuilder._root);
1384 invokeLoop.continuation =
1385 new ir.Reference<ir.Continuation>(loopContinuation);
1386 ir.LetCont letLoop =
1387 new ir.LetCont(loopContinuation,
1388 new ir.InvokeContinuation(loopContinuation,
1389 environment.index2value));
1390
1391 // Add the break condition.
1392 ir.Continuation breakContinuation;
1393 if (breakCollector.length == 1) {
1394 // createJoin only works when there is more than one jump to a join-point
1395 // continuation. This is to potentially catch errors in the case that
1396 // a join was intended and at least one jump is missing. Unfortunately
1397 // we have the explicit code below for the (common?) case that the
1398 // only break from the do-while is the implicit one when the condition
1399 // is false.
1400 List<ir.Parameter> parameters = <ir.Parameter>[];
1401 List<ir.Reference> arguments = <ir.Reference>[];
1402 for (int i = 0; i < environment.length; ++i) {
1403 ir.Parameter parameter =
1404 new ir.Parameter(environment.index2variable[i]);
1405 parameters.add(parameter);
1406 environment.index2value[i] = parameter;
1407 arguments.add(new ir.Reference(breakCollector.environments.first[i]));
1408 }
1409 breakContinuation = new ir.Continuation(parameters);
1410 breakCollector.invocations.first.arguments = arguments;
1411 breakCollector.invocations.first.continuation =
1412 new ir.Reference(breakContinuation);
1413 } else {
1414 breakContinuation = createJoin(environment.length, breakCollector);
1415 }
1416 add(new ir.LetCont(breakContinuation, letLoop));
1417 }
1418
1300 /// Creates a try-statement. 1419 /// Creates a try-statement.
1301 /// 1420 ///
1302 /// [tryInfo] provides information on local variables declared and boxed 1421 /// [tryInfo] provides information on local variables declared and boxed
1303 /// within this try statement. 1422 /// within this try statement.
1304 /// [buildTryBlock] builds the try block. 1423 /// [buildTryBlock] builds the try block.
1305 /// [catchClauseInfos] provides access to the catch type, exception variable, 1424 /// [catchClauseInfos] provides access to the catch type, exception variable,
1306 /// and stack trace variable, and a function for building the catch block. 1425 /// and stack trace variable, and a function for building the catch block.
1307 void buildTry( 1426 void buildTry(
1308 {TryStatementInfo tryStatementInfo, 1427 {TryStatementInfo tryStatementInfo,
1309 SubbuildFunction buildTryBlock, 1428 SubbuildFunction buildTryBlock,
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
2323 // TODO(johnniwinther): Support passing of [DartType] for the exception. 2442 // TODO(johnniwinther): Support passing of [DartType] for the exception.
2324 class CatchClauseInfo { 2443 class CatchClauseInfo {
2325 final LocalVariableElement exceptionVariable; 2444 final LocalVariableElement exceptionVariable;
2326 final LocalVariableElement stackTraceVariable; 2445 final LocalVariableElement stackTraceVariable;
2327 final SubbuildFunction buildCatchBlock; 2446 final SubbuildFunction buildCatchBlock;
2328 2447
2329 CatchClauseInfo({this.exceptionVariable, 2448 CatchClauseInfo({this.exceptionVariable,
2330 this.stackTraceVariable, 2449 this.stackTraceVariable,
2331 this.buildCatchBlock}); 2450 this.buildCatchBlock});
2332 } 2451 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698