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

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2985383002: Add partial support for TryFinally and TryCatch statements (Closed)
Patch Set: Merge Created 3 years, 4 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
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/try_catch_finally_test.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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 library kernel.interpreter; 4 library kernel.interpreter;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../ast.dart' as ast show Class; 7 import '../ast.dart' as ast show Class;
8 8
9 import '../log.dart'; 9 import '../log.dart';
10 export '../log.dart'; 10 export '../log.dart';
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 323 }
324 324
325 State withReturnContinuation(ExpressionContinuation returnCont) { 325 State withReturnContinuation(ExpressionContinuation returnCont) {
326 return new State(labels, exceptionComponents, returnCont, continuation); 326 return new State(labels, exceptionComponents, returnCont, continuation);
327 } 327 }
328 328
329 State withContinuation(StatementContinuation cont) { 329 State withContinuation(StatementContinuation cont) {
330 return new State(labels, exceptionComponents, returnContinuation, cont); 330 return new State(labels, exceptionComponents, returnContinuation, cont);
331 } 331 }
332 332
333 State withException(ExceptionComponents state) { 333 State withException(ExceptionComponents ecs) {
334 return new State(labels, state, returnContinuation, continuation); 334 return new State(labels, ecs, returnContinuation, continuation);
335 } 335 }
336 336
337 Label lookupLabel(LabeledStatement s) { 337 Label lookupLabel(LabeledStatement s) {
338 assert(labels != null); 338 assert(labels != null);
339 return labels.lookupLabel(s); 339 return labels.lookupLabel(s);
340 } 340 }
341 } 341 }
342 342
343 /// Represents a labeled statement, the corresponding continuation and the 343 /// Represents a labeled statement, the corresponding continuation and the
344 /// enclosing label. 344 /// enclosing label.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 /// `List<InterpreterValue>`. 437 /// `List<InterpreterValue>`.
438 class ApplicationConfiguration extends Configuration { 438 class ApplicationConfiguration extends Configuration {
439 final ApplicationContinuation continuation; 439 final ApplicationContinuation continuation;
440 final List<InterpreterValue> values; 440 final List<InterpreterValue> values;
441 441
442 ApplicationConfiguration(this.continuation, this.values); 442 ApplicationConfiguration(this.continuation, this.values);
443 443
444 Configuration step(StatementExecuter _) => continuation(values); 444 Configuration step(StatementExecuter _) => continuation(values);
445 } 445 }
446 446
447 /// Configuration for applying an [ExceptionHandler] to an exception and a
448 /// stack trace.
447 class ThrowConfiguration extends Configuration { 449 class ThrowConfiguration extends Configuration {
448 final ExceptionHandler handler; 450 final ExceptionHandler handler;
449 final Value exception; 451 final Value exception;
450 final StackTrace stacktrace; 452 final StackTrace stacktrace;
451 453
452 ThrowConfiguration(this.handler, this.exception, this.stacktrace); 454 ThrowConfiguration(this.handler, this.exception, this.stacktrace);
453 455
454 Configuration step(StatementExecuter _) => handler(exception, stacktrace); 456 Configuration step(StatementExecuter _) => handler(exception, stacktrace);
455 } 457 }
456 458
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 601
600 ConstructorBodySK( 602 ConstructorBodySK(
601 this.body, this.environment, this.exceptionComponents, this.continuation); 603 this.body, this.environment, this.exceptionComponents, this.continuation);
602 604
603 Configuration call(Environment _) { 605 Configuration call(Environment _) {
604 return new ExecConfiguration(body, environment, 606 return new ExecConfiguration(body, environment,
605 new State(null, exceptionComponents, null, continuation)); 607 new State(null, exceptionComponents, null, continuation));
606 } 608 }
607 } 609 }
608 610
611 /// Represents the statement continuation for execution of the finalizer
612 /// statement.
613 class FinallySK extends StatementContinuation {
614 final Statement finallyStatement;
615 final Environment environment;
616 final State state;
617
618 FinallySK(this.finallyStatement, this.environment, this.state);
619 Configuration call(Environment _) {
620 return new ExecConfiguration(finallyStatement, environment, state);
621 }
622 }
623
624 /// Represents the statement continuation that applies the captured handler to
625 /// the current exception.
626 ///
627 /// It is used as next statement continuation for the execution of the finalizer
628 /// statement in [TryFinally] to ensure the finalizer is executed before
629 /// applying the next handler to the current exception.
630 class RethrowSK extends StatementContinuation {
631 final ExceptionHandler handler;
632 final Value exception;
633 final StackTrace stackTrace;
634
635 RethrowSK(this.handler, this.exception, this.stackTrace);
636
637 Configuration call(Environment _) {
638 return new ThrowConfiguration(handler, exception, stackTrace);
639 }
640 }
641
609 // ------------------------------------------------------------------------ 642 // ------------------------------------------------------------------------
610 // Application Continuations 643 // Application Continuations
611 // ------------------------------------------------------------------------ 644 // ------------------------------------------------------------------------
612
613 /// Represents the continuation called after the evaluation of argument 645 /// Represents the continuation called after the evaluation of argument
614 /// expressions. 646 /// expressions.
615 /// 647 ///
616 /// There are various kinds of [ApplicationContinuation] and their names are 648 /// There are various kinds of [ApplicationContinuation] and their names are
617 /// suffixed with "A". 649 /// suffixed with "A".
618 abstract class ApplicationContinuation extends Continuation { 650 abstract class ApplicationContinuation extends Continuation {
619 Configuration call(List<InterpreterValue> values); 651 Configuration call(List<InterpreterValue> values);
620 652
621 /// Binds actual argument values to formal parameters of the function in a 653 /// Binds actual argument values to formal parameters of the function in a
622 /// new environment or in the provided initial environment. 654 /// new environment or in the provided initial environment.
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 final ExceptionComponents exceptionComponents; 1265 final ExceptionComponents exceptionComponents;
1234 1266
1235 ThrowEK(this.exceptionComponents); 1267 ThrowEK(this.exceptionComponents);
1236 1268
1237 Configuration call(Value value) { 1269 Configuration call(Value value) {
1238 return new ThrowConfiguration( 1270 return new ThrowConfiguration(
1239 exceptionComponents.handler, value, exceptionComponents.stackTrace); 1271 exceptionComponents.handler, value, exceptionComponents.stackTrace);
1240 } 1272 }
1241 } 1273 }
1242 1274
1275 /// Represents the expression continuation that ensures the finalizer of a
1276 /// [TryFinally] node is executed before applying the return continuation to
1277 /// the given value.
1278 ///
1279 /// It executes the captured finalizer statement and adds a statement
1280 /// continuation that will apply the return continuation to the given value
1281 /// when/if reached.
1282 class FinallyReturnEK extends ExpressionContinuation {
1283 final Statement statement;
1284 final Environment environment;
1285 final State state;
1286
1287 FinallyReturnEK(this.statement, this.environment, this.state);
1288
1289 Configuration call(Value value) {
1290 return new ExecConfiguration(statement, environment,
1291 state.withContinuation(new ExitSK(state.returnContinuation, value)));
1292 }
1293 }
1294
1243 // ------------------------------------------------------------------------ 1295 // ------------------------------------------------------------------------
1244 // Exceptions Handlers 1296 // Exceptions Handlers
1245 // ------------------------------------------------------------------------ 1297 // ------------------------------------------------------------------------
1246 1298
1247 abstract class ExceptionHandler extends Continuation { 1299 abstract class ExceptionHandler extends Continuation {
1248 ExceptionHandler get nextHandler; 1300 Configuration call(Value exception, StackTrace stacktrace);
1249 1301
1250 Configuration call(Value exception, StackTrace stacktrace); 1302 static String errorMessage(Value exception, StackTrace stacktrace) {
1303 return 'Uncaught exception '
1304 '"${exception.value.runtimeType} : ${exception.value}"\n'
1305 '${stacktrace.toString()}';
1306 }
1251 } 1307 }
1252 1308
1253 /// Handler for showing an exception to the user and returning a halting the 1309 /// Handler for showing an exception to the user and returning a halting the
1254 /// execution of the program when an exception is not handled. 1310 /// execution of the program when an exception is not handled.
1255 class MainHandler extends ExceptionHandler { 1311 class MainHandler extends ExceptionHandler {
1256 ExceptionHandler get nextHandler => 1312 Configuration call(Value exception, StackTrace stacktrace) {
1257 throw 'The current handler is the main exception handler'; 1313 var message = ExceptionHandler.errorMessage(exception, stacktrace);
1314 log.info(message);
1315 print(message);
1316 return null;
1317 }
1318 }
1258 1319
1259 Configuration call(Value exception, StackTrace stacktrace) { 1320 /// Represents the handler that either executes a matching catch clause or
1260 var errorMessage = 'Uncaught exception ' 1321 /// applies the next handler to the given exception.
1261 '"${exception.value.runtimeType} : ${exception.value}"\n' 1322 class CatchHandler extends ExceptionHandler {
1262 '${stacktrace.toString()}'; 1323 final List<Catch> catches;
1263 log.info(errorMessage); 1324 final Environment environment;
1264 print(errorMessage); 1325 final State state;
1265 return null; 1326
1327 CatchHandler(this.catches, this.environment, this.state);
1328
1329 Configuration call(Value exception, StackTrace stackTrace) {
1330 // TODO(zhivkag): Check if there is a matching catch clause instead.
1331 return new ThrowConfiguration(
1332 state.exceptionComponents.handler, exception, stackTrace);
1333 }
1334 }
1335
1336 /// Represents the handler that executes the corresponding finalizer before
1337 /// applying the next handler to the given exception.
1338 ///
1339 /// Applying the next handler to the given exception is supported with adding
1340 /// [RethrowSK] as next statement continuation.
1341 class FinallyHandler extends ExceptionHandler {
1342 final Statement finallyStatement;
1343 final Environment environment;
1344 final Label labels;
1345 final ExceptionComponents exceptionComponents;
1346 final ExpressionContinuation expressionContinuation;
1347
1348 FinallyHandler(this.finallyStatement, this.environment, this.labels,
1349 this.exceptionComponents, this.expressionContinuation);
1350
1351 Configuration call(Value exception, StackTrace stackTrace) {
1352 // A finally handler can't handle an exception, only execute the
1353 // corresponding finally statement and rethrow.
1354 var cont =
1355 new RethrowSK(exceptionComponents.handler, exception, stackTrace);
1356 var state =
1357 new State(labels, exceptionComponents, expressionContinuation, cont);
1358 return new ExecConfiguration(finallyStatement, environment, state);
1266 } 1359 }
1267 } 1360 }
1268 1361
1269 // ------------------------------------------------------------------------ 1362 // ------------------------------------------------------------------------
1270 // Exceptions 1363 // Exceptions
1271 // ------------------------------------------------------------------------ 1364 // ------------------------------------------------------------------------
1272 /// Represents the components for Exception handling. 1365 /// Represents the components for Exception handling.
1273 /// 1366 ///
1274 /// It contains the list of exception handlers, a stack trace and optional 1367 /// It contains the list of exception handlers, a stack trace and optional
1275 /// components, current stacktrace and exception. 1368 /// components, current stacktrace and exception.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 assert(conf.state.returnContinuation != null); 1508 assert(conf.state.returnContinuation != null);
1416 log.info('return\n'); 1509 log.info('return\n');
1417 if (node.expression == null) { 1510 if (node.expression == null) {
1418 return new ValuePassingConfiguration( 1511 return new ValuePassingConfiguration(
1419 conf.state.returnContinuation, Value.nullInstance); 1512 conf.state.returnContinuation, Value.nullInstance);
1420 } 1513 }
1421 return new EvalConfiguration(node.expression, conf.environment, 1514 return new EvalConfiguration(node.expression, conf.environment,
1422 conf.state.exceptionComponents, conf.state.returnContinuation); 1515 conf.state.exceptionComponents, conf.state.returnContinuation);
1423 } 1516 }
1424 1517
1518 Configuration visitTryCatch(TryCatch node, ExecConfiguration conf) {
1519 var handler = new CatchHandler(node.catches, conf.environment, conf.state);
1520 var handlers = new ExceptionComponents(
1521 handler,
1522 conf.state.exceptionComponents.stackTrace,
1523 conf.state.exceptionComponents.currentStackTrace,
1524 conf.state.exceptionComponents.currentException);
1525 var state = conf.state.withException(handlers);
1526 return new ExecConfiguration(node.body, conf.environment, state);
1527 }
1528
1529 Configuration visitTryFinally(TryFinally node, ExecConfiguration conf) {
1530 // TODO(zhivkag): Add FinallyBreak to break labels.
1531 var cont = new FinallySK(node.finalizer, conf.environment, conf.state);
1532 var returnCont =
1533 new FinallyReturnEK(node.finalizer, conf.environment, conf.state);
1534 return new ExecConfiguration(node.body, conf.environment,
1535 conf.state.withContinuation(cont).withReturnContinuation(returnCont));
1536 }
1537
1425 Configuration visitVariableDeclaration( 1538 Configuration visitVariableDeclaration(
1426 VariableDeclaration node, ExecConfiguration conf) { 1539 VariableDeclaration node, ExecConfiguration conf) {
1427 if (node.initializer != null) { 1540 if (node.initializer != null) {
1428 var cont = new VariableInitializerEK( 1541 var cont = new VariableInitializerEK(
1429 node, conf.environment, conf.state.continuation); 1542 node, conf.environment, conf.state.continuation);
1430 return new EvalConfiguration(node.initializer, conf.environment, 1543 return new EvalConfiguration(node.initializer, conf.environment,
1431 conf.state.exceptionComponents, cont); 1544 conf.state.exceptionComponents, cont);
1432 } 1545 }
1433 return new ForwardConfiguration(conf.state.continuation, 1546 return new ForwardConfiguration(conf.state.continuation,
1434 conf.environment.extend(node, Value.nullInstance)); 1547 conf.environment.extend(node, Value.nullInstance));
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 /// Initializes all non initialized fields from the provided class to 1840 /// Initializes all non initialized fields from the provided class to
1728 /// `Value.nullInstance` in the provided value. 1841 /// `Value.nullInstance` in the provided value.
1729 void _initializeNullFields(Class class_, Value value) { 1842 void _initializeNullFields(Class class_, Value value) {
1730 int startIndex = class_.superclass?.instanceSize ?? 0; 1843 int startIndex = class_.superclass?.instanceSize ?? 0;
1731 for (int i = startIndex; i < class_.instanceSize; i++) { 1844 for (int i = startIndex; i < class_.instanceSize; i++) {
1732 if (value.fields[i].value == null) { 1845 if (value.fields[i].value == null) {
1733 value.fields[i].value = Value.nullInstance; 1846 value.fields[i].value = Value.nullInstance;
1734 } 1847 }
1735 } 1848 }
1736 } 1849 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/try_catch_finally_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698