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

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

Issue 2988153002: Add components for handling of exceptions (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 | no next file » | 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 13 matching lines...) Expand all
24 Interpreter(this.program); 24 Interpreter(this.program);
25 25
26 void run() { 26 void run() {
27 assert(program.libraries.isEmpty); 27 assert(program.libraries.isEmpty);
28 Procedure mainMethod = program.mainMethod; 28 Procedure mainMethod = program.mainMethod;
29 29
30 if (mainMethod == null) return; 30 if (mainMethod == null) return;
31 31
32 Statement statementBlock = mainMethod.function.body; 32 Statement statementBlock = mainMethod.function.body;
33 ExecConfiguration configuration = new ExecConfiguration( 33 ExecConfiguration configuration = new ExecConfiguration(
34 statementBlock, new Environment.empty(), const State.initial()); 34 statementBlock, new Environment.empty(), new State.initial());
35 visitor.trampolinedExecution(configuration); 35 visitor.trampolinedExecution(configuration);
36 } 36 }
37 } 37 }
38 38
39 class Location { 39 class Location {
40 Value value; 40 Value value;
41 41
42 Location.empty(); 42 Location.empty();
43 Location(this.value); 43 Location(this.value);
44 } 44 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 return extend(new VariableDeclaration('this'), v); 113 return extend(new VariableDeclaration('this'), v);
114 } 114 }
115 } 115 }
116 116
117 /// Evaluate expressions. 117 /// Evaluate expressions.
118 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { 118 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
119 Configuration eval(Expression expr, EvalConfiguration config) => 119 Configuration eval(Expression expr, EvalConfiguration config) =>
120 expr.accept1(this, config); 120 expr.accept1(this, config);
121 121
122 Configuration evalList(List<InterpreterExpression> list, Environment env, 122 Configuration evalList(List<InterpreterExpression> list, Environment env,
123 ApplicationContinuation cont) { 123 Handlers handlers, ApplicationContinuation cont) {
124 if (list.isNotEmpty) { 124 if (list.isNotEmpty) {
125 return new EvalConfiguration(list.first.expression, env, 125 return new EvalConfiguration(list.first.expression, env, handlers,
126 new ExpressionListEK(list.first, list.skip(1), env, cont)); 126 new ExpressionListEK(list.first, list.skip(1), env, handlers, cont));
127 } 127 }
128 return new ApplicationConfiguration(cont, <InterpreterValue>[]); 128 return new ApplicationConfiguration(cont, <InterpreterValue>[]);
129 } 129 }
130 130
131 Configuration defaultExpression(Expression node, EvalConfiguration config) { 131 Configuration defaultExpression(Expression node, EvalConfiguration config) {
132 throw new NotImplemented('Evaluation for expressions of type ' 132 throw new NotImplemented('Evaluation for expressions of type '
133 '${node.runtimeType} is not implemented.'); 133 '${node.runtimeType} is not implemented.');
134 } 134 }
135 135
136 Configuration visitInvalidExpression1( 136 Configuration visitInvalidExpression1(
137 InvalidExpression node, EvalConfiguration config) { 137 InvalidExpression node, EvalConfiguration config) {
138 throw 'Invalid expression at ${node.location.toString()}'; 138 throw 'Invalid expression at ${node.location.toString()}';
139 } 139 }
140 140
141 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) { 141 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) {
142 Value value = config.environment.lookup(node.variable); 142 Value value = config.environment.lookup(node.variable);
143 return new ValuePassingConfiguration(config.continuation, value); 143 return new ValuePassingConfiguration(config.continuation, value);
144 } 144 }
145 145
146 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { 146 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) {
147 var cont = new VariableSetEK( 147 var cont = new VariableSetEK(
148 node.variable, config.environment, config.continuation); 148 node.variable, config.environment, config.continuation);
149 return new EvalConfiguration(node.value, config.environment, cont); 149 return new EvalConfiguration(
150 node.value, config.environment, config.handlers, cont);
150 } 151 }
151 152
152 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { 153 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) {
153 var cont = new PropertyGetEK(node.name, config.continuation); 154 var cont = new PropertyGetEK(node.name, config.continuation);
154 return new EvalConfiguration(node.receiver, config.environment, cont); 155 return new EvalConfiguration(
156 node.receiver, config.environment, config.handlers, cont);
155 } 157 }
156 158
157 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { 159 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) {
158 var cont = new PropertySetEK( 160 var cont = new PropertySetEK(node.value, node.name, config.environment,
159 node.value, node.name, config.environment, config.continuation); 161 config.handlers, config.continuation);
160 return new EvalConfiguration(node.receiver, config.environment, cont); 162 return new EvalConfiguration(
163 node.receiver, config.environment, config.handlers, cont);
161 } 164 }
162 165
163 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => 166 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) =>
164 defaultExpression(node, config); 167 defaultExpression(node, config);
165 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => 168 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) =>
166 defaultExpression(node, config); 169 defaultExpression(node, config);
167 170
168 Configuration visitStaticInvocation( 171 Configuration visitStaticInvocation(
169 StaticInvocation node, EvalConfiguration config) { 172 StaticInvocation node, EvalConfiguration config) {
170 if ('print' == node.name.toString()) { 173 if ('print' == node.name.toString()) {
171 var cont = new PrintEK(config.continuation); 174 var cont = new PrintEK(config.continuation);
172 return new EvalConfiguration( 175 return new EvalConfiguration(node.arguments.positional.first,
173 node.arguments.positional.first, config.environment, cont); 176 config.environment, config.handlers, cont);
174 } else { 177 } else {
175 log.info('static-invocation-${node.target.name.toString()}\n'); 178 log.info('static-invocation-${node.target.name.toString()}\n');
176 179
177 List<InterpreterExpression> args = 180 List<InterpreterExpression> args =
178 _getArgumentExpressions(node.arguments, node.target.function); 181 _getArgumentExpressions(node.arguments, node.target.function);
179 ApplicationContinuation cont = 182 ApplicationContinuation cont = new StaticInvocationA(
180 new StaticInvocationA(node.target.function, config.continuation); 183 node.target.function, config.handlers, config.continuation);
181 return new EvalListConfiguration(args, config.environment, cont); 184 return new EvalListConfiguration(
185 args, config.environment, config.handlers, cont);
182 } 186 }
183 } 187 }
184 188
185 Configuration visitMethodInvocation( 189 Configuration visitMethodInvocation(
186 MethodInvocation node, EvalConfiguration config) { 190 MethodInvocation node, EvalConfiguration config) {
187 // Currently supports only method invocation with <2 arguments and is used 191 // Currently supports only method invocation with <2 arguments and is used
188 // to evaluate implemented operators for int, double and String values. 192 // to evaluate implemented operators for int, double and String values.
189 var cont = new MethodInvocationEK( 193 var cont = new MethodInvocationEK(node.arguments, node.name,
190 node.arguments, node.name, config.environment, config.continuation); 194 config.environment, config.handlers, config.continuation);
191 195
192 return new EvalConfiguration(node.receiver, config.environment, cont); 196 return new EvalConfiguration(
197 node.receiver, config.environment, config.handlers, cont);
193 } 198 }
194 199
195 Configuration visitConstructorInvocation( 200 Configuration visitConstructorInvocation(
196 ConstructorInvocation node, EvalConfiguration config) { 201 ConstructorInvocation node, EvalConfiguration config) {
197 ApplicationContinuation cont = 202 ApplicationContinuation cont = new ConstructorInvocationA(
198 new ConstructorInvocationA(node.target, config.continuation); 203 node.target, config.handlers, config.continuation);
199 var args = _getArgumentExpressions(node.arguments, node.target.function); 204 var args = _getArgumentExpressions(node.arguments, node.target.function);
200 205
201 return new EvalListConfiguration(args, config.environment, cont); 206 return new EvalListConfiguration(
207 args, config.environment, config.handlers, cont);
202 } 208 }
203 209
204 Configuration visitNot(Not node, EvalConfiguration config) { 210 Configuration visitNot(Not node, EvalConfiguration config) {
205 return new EvalConfiguration( 211 return new EvalConfiguration(node.operand, config.environment,
206 node.operand, config.environment, new NotEK(config.continuation)); 212 config.handlers, new NotEK(config.continuation));
207 } 213 }
208 214
209 Configuration visitLogicalExpression( 215 Configuration visitLogicalExpression(
210 LogicalExpression node, EvalConfiguration config) { 216 LogicalExpression node, EvalConfiguration config) {
211 if ('||' == node.operator) { 217 if ('||' == node.operator) {
212 var cont = new OrEK(node.right, config.environment, config.continuation); 218 var cont = new OrEK(
213 return new EvalConfiguration(node.left, config.environment, cont); 219 node.right, config.environment, config.handlers, config.continuation);
220 return new EvalConfiguration(
221 node.left, config.environment, config.handlers, cont);
214 } else { 222 } else {
215 assert('&&' == node.operator); 223 assert('&&' == node.operator);
216 var cont = new AndEK(node.right, config.environment, config.continuation); 224 var cont = new AndEK(
217 return new EvalConfiguration(node.left, config.environment, cont); 225 node.right, config.environment, config.handlers, config.continuation);
226 return new EvalConfiguration(
227 node.left, config.environment, config.handlers, cont);
218 } 228 }
219 } 229 }
220 230
221 Configuration visitConditionalExpression( 231 Configuration visitConditionalExpression(
222 ConditionalExpression node, EvalConfiguration config) { 232 ConditionalExpression node, EvalConfiguration config) {
223 var cont = new ConditionalEK( 233 var cont = new ConditionalEK(node.then, node.otherwise, config.environment,
224 node.then, node.otherwise, config.environment, config.continuation); 234 config.handlers, config.continuation);
225 return new EvalConfiguration(node.condition, config.environment, cont); 235 return new EvalConfiguration(
236 node.condition, config.environment, config.handlers, cont);
226 } 237 }
227 238
228 Configuration visitStringConcatenation( 239 Configuration visitStringConcatenation(
229 StringConcatenation node, EvalConfiguration config) { 240 StringConcatenation node, EvalConfiguration config) {
230 var cont = new StringConcatenationA(config.continuation); 241 var cont = new StringConcatenationA(config.continuation);
231 var expressions = node.expressions 242 var expressions = node.expressions
232 .map((Expression e) => new PositionalExpression(e)) 243 .map((Expression e) => new PositionalExpression(e))
233 .toList(); 244 .toList();
234 return new EvalListConfiguration(expressions, config.environment, cont); 245 return new EvalListConfiguration(
246 expressions, config.environment, config.handlers, cont);
235 } 247 }
236 248
237 Configuration visitThisExpression( 249 Configuration visitThisExpression(
238 ThisExpression node, EvalConfiguration config) { 250 ThisExpression node, EvalConfiguration config) {
239 return new ValuePassingConfiguration( 251 return new ValuePassingConfiguration(
240 config.continuation, config.environment.thisInstance); 252 config.continuation, config.environment.thisInstance);
241 } 253 }
242 254
243 // Evaluation of BasicLiterals. 255 // Evaluation of BasicLiterals.
244 Configuration visitStringLiteral( 256 Configuration visitStringLiteral(
(...skipping 17 matching lines...) Expand all
262 Value value = node.value ? Value.trueInstance : Value.falseInstance; 274 Value value = node.value ? Value.trueInstance : Value.falseInstance;
263 return new ValuePassingConfiguration(config.continuation, value); 275 return new ValuePassingConfiguration(config.continuation, value);
264 } 276 }
265 277
266 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) { 278 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) {
267 return new ValuePassingConfiguration( 279 return new ValuePassingConfiguration(
268 config.continuation, Value.nullInstance); 280 config.continuation, Value.nullInstance);
269 } 281 }
270 282
271 Configuration visitLet(Let node, EvalConfiguration config) { 283 Configuration visitLet(Let node, EvalConfiguration config) {
272 var letCont = new LetEK( 284 var letCont = new LetEK(node.variable, node.body, config.environment,
273 node.variable, node.body, config.environment, config.continuation); 285 config.handlers, config.continuation);
274 return new EvalConfiguration( 286 return new EvalConfiguration(node.variable.initializer, config.environment,
275 node.variable.initializer, config.environment, letCont); 287 config.handlers, letCont);
276 } 288 }
277 } 289 }
278 290
279 /// Represents a state for statement execution. 291 /// Represents a state for statement execution.
280 class State { 292 class State {
281 final Label labels; 293 final Label labels;
282 // TODO: Add switch labels. 294 // TODO: Add switch labels.
283 // TODO: Add component for exception support. 295 final Handlers handlers;
284 final ExpressionContinuation returnContinuation; 296 final ExpressionContinuation returnContinuation;
285 final StatementContinuation continuation; 297 final StatementContinuation continuation;
286 298
287 State(this.labels, this.returnContinuation, this.continuation); 299 State(this.labels, this.handlers, this.returnContinuation, this.continuation);
288 300
289 const State.initial() 301 State.initial()
290 : labels = null, 302 : labels = null,
303 handlers = new Handlers.initial(),
291 returnContinuation = null, 304 returnContinuation = null,
292 continuation = null; 305 continuation = null;
293 306
294 State withBreak(Statement stmt, Environment env) { 307 State withBreak(Statement stmt, Environment env) {
295 Label breakLabels = new Label(stmt, env, continuation, labels); 308 Label breakLabels = new Label(stmt, env, continuation, labels);
296 return new State(breakLabels, returnContinuation, continuation); 309 return new State(breakLabels, handlers, returnContinuation, continuation);
297 } 310 }
298 311
299 State withReturnContinuation(ExpressionContinuation returnCont) { 312 State withReturnContinuation(ExpressionContinuation returnCont) {
300 return new State(labels, returnCont, continuation); 313 return new State(labels, handlers, returnCont, continuation);
301 } 314 }
302 315
303 State withContinuation(StatementContinuation cont) { 316 State withContinuation(StatementContinuation cont) {
304 return new State(labels, returnContinuation, cont); 317 return new State(labels, handlers, returnContinuation, cont);
318 }
319
320 State withException(Handlers state) {
321 return new State(labels, state, returnContinuation, continuation);
305 } 322 }
306 323
307 Label lookupLabel(LabeledStatement s) { 324 Label lookupLabel(LabeledStatement s) {
308 assert(labels != null); 325 assert(labels != null);
309 return labels.lookupLabel(s); 326 return labels.lookupLabel(s);
310 } 327 }
311 } 328 }
312 329
313 /// Represents a labeled statement, the corresponding continuation and the 330 /// Represents a labeled statement, the corresponding continuation and the
314 /// enclosing label. 331 /// enclosing label.
(...skipping 22 matching lines...) Expand all
337 Configuration step(StatementExecuter executer); 354 Configuration step(StatementExecuter executer);
338 } 355 }
339 356
340 /// Configuration for evaluating an [Expression]. 357 /// Configuration for evaluating an [Expression].
341 class EvalConfiguration extends Configuration { 358 class EvalConfiguration extends Configuration {
342 final Expression expression; 359 final Expression expression;
343 360
344 /// Environment in which the expression is evaluated. 361 /// Environment in which the expression is evaluated.
345 final Environment environment; 362 final Environment environment;
346 363
364 /// Exception handlers.
365 final Handlers handlers;
366
347 /// Next continuation to be applied. 367 /// Next continuation to be applied.
348 final Continuation continuation; 368 final Continuation continuation;
349 369
350 EvalConfiguration(this.expression, this.environment, this.continuation); 370 EvalConfiguration(
371 this.expression, this.environment, this.handlers, this.continuation);
351 372
352 Configuration step(StatementExecuter executer) => 373 Configuration step(StatementExecuter executer) =>
353 executer.eval(expression, this); 374 executer.eval(expression, this);
354 } 375 }
355 376
356 /// Configuration for evaluating a `List<InterpreterExpression>`. 377 /// Configuration for evaluating a `List<InterpreterExpression>`.
357 class EvalListConfiguration extends Configuration { 378 class EvalListConfiguration extends Configuration {
358 final List<InterpreterExpression> expressions; 379 final List<InterpreterExpression> expressions;
359 final Environment environment; 380 final Environment environment;
381 final Handlers handlers;
360 final ApplicationContinuation continuation; 382 final ApplicationContinuation continuation;
361 383
362 EvalListConfiguration(this.expressions, this.environment, this.continuation); 384 EvalListConfiguration(
385 this.expressions, this.environment, this.handlers, this.continuation);
363 386
364 Configuration step(StatementExecuter executer) => 387 Configuration step(StatementExecuter executer) =>
365 executer.evalList(expressions, environment, continuation); 388 executer.evalList(expressions, environment, handlers, continuation);
366 } 389 }
367 390
368 /// Configuration for execution of a [Statement]. 391 /// Configuration for execution of a [Statement].
369 class ExecConfiguration extends Configuration { 392 class ExecConfiguration extends Configuration {
370 final Statement currentStatement; 393 final Statement currentStatement;
371 final Environment environment; 394 final Environment environment;
372 final State state; 395 final State state;
373 396
374 ExecConfiguration(this.currentStatement, this.environment, this.state); 397 ExecConfiguration(this.currentStatement, this.environment, this.state);
375 398
(...skipping 25 matching lines...) Expand all
401 /// `List<InterpreterValue>`. 424 /// `List<InterpreterValue>`.
402 class ApplicationConfiguration extends Configuration { 425 class ApplicationConfiguration extends Configuration {
403 final ApplicationContinuation continuation; 426 final ApplicationContinuation continuation;
404 final List<InterpreterValue> values; 427 final List<InterpreterValue> values;
405 428
406 ApplicationConfiguration(this.continuation, this.values); 429 ApplicationConfiguration(this.continuation, this.values);
407 430
408 Configuration step(StatementExecuter _) => continuation(values); 431 Configuration step(StatementExecuter _) => continuation(values);
409 } 432 }
410 433
434 class ThrowConfiguration extends Configuration {
435 final ExceptionHandler handler;
436 final Value exception;
437 final StackTrace stacktrace;
438
439 ThrowConfiguration(this.handler, this.exception, this.stacktrace);
440
441 Configuration step(StatementExecuter _) => handler(exception, stacktrace);
442 }
443
411 // ------------------------------------------------------------------------ 444 // ------------------------------------------------------------------------
412 // Interpreter Expressions and Values 445 // Interpreter Expressions and Values
413 // ------------------------------------------------------------------------ 446 // ------------------------------------------------------------------------
414 447
415 abstract class InterpreterExpression { 448 abstract class InterpreterExpression {
416 Expression get expression; 449 Expression get expression;
417 450
418 InterpreterValue assignValue(Value v); 451 InterpreterValue assignValue(Value v);
419 } 452 }
420 453
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 final Expression condition; 555 final Expression condition;
523 final Statement body; 556 final Statement body;
524 final Environment enclosingEnv; 557 final Environment enclosingEnv;
525 final State state; 558 final State state;
526 559
527 WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state); 560 WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state);
528 561
529 Configuration call(Environment _) { 562 Configuration call(Environment _) {
530 // Evaluate the condition for the while loop execution. 563 // Evaluate the condition for the while loop execution.
531 var cont = new WhileConditionEK(condition, body, enclosingEnv, state); 564 var cont = new WhileConditionEK(condition, body, enclosingEnv, state);
532 return new EvalConfiguration(condition, enclosingEnv, cont); 565 return new EvalConfiguration(condition, enclosingEnv, state.handlers, cont);
533 } 566 }
534 } 567 }
535 568
536 /// Applies the expression continuation to the provided value. 569 /// Applies the expression continuation to the provided value.
537 class NewSK extends StatementContinuation { 570 class NewSK extends StatementContinuation {
538 final ExpressionContinuation continuation; 571 final ExpressionContinuation continuation;
539 final Location location; 572 final Location location;
540 573
541 NewSK(this.continuation, this.location); 574 NewSK(this.continuation, this.location);
542 575
543 Configuration call(Environment _) => 576 Configuration call(Environment _) =>
544 new ValuePassingConfiguration(continuation, location.value); 577 new ValuePassingConfiguration(continuation, location.value);
545 } 578 }
546 579
547 class ConstructorBodySK extends StatementContinuation { 580 class ConstructorBodySK extends StatementContinuation {
548 final Statement body; 581 final Statement body;
549 final Environment environment; 582 final Environment environment;
550 // TODO(zhivkag): Add component for exception handler. 583 final Handlers handlers;
551 final StatementContinuation continuation; 584 final StatementContinuation continuation;
552 585
553 ConstructorBodySK(this.body, this.environment, this.continuation); 586 ConstructorBodySK(
587 this.body, this.environment, this.handlers, this.continuation);
554 588
555 Configuration call(Environment _) { 589 Configuration call(Environment _) {
556 return new ExecConfiguration( 590 return new ExecConfiguration(
557 body, environment, new State(null, null, continuation)); 591 body, environment, new State(null, handlers, null, continuation));
558 } 592 }
559 } 593 }
560 594
561 // ------------------------------------------------------------------------ 595 // ------------------------------------------------------------------------
562 // Application Continuations 596 // Application Continuations
563 // ------------------------------------------------------------------------ 597 // ------------------------------------------------------------------------
564 598
565 /// Represents the continuation called after the evaluation of argument 599 /// Represents the continuation called after the evaluation of argument
566 /// expressions. 600 /// expressions.
567 /// 601 ///
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 result.write(v.value.value); 661 result.write(v.value.value);
628 } 662 }
629 return new ValuePassingConfiguration( 663 return new ValuePassingConfiguration(
630 continuation, new StringValue(result.toString())); 664 continuation, new StringValue(result.toString()));
631 } 665 }
632 } 666 }
633 667
634 /// Represents the application continuation for static invocation. 668 /// Represents the application continuation for static invocation.
635 class StaticInvocationA extends ApplicationContinuation { 669 class StaticInvocationA extends ApplicationContinuation {
636 final FunctionNode function; 670 final FunctionNode function;
671 final Handlers handlers;
637 final ExpressionContinuation continuation; 672 final ExpressionContinuation continuation;
638 673
639 StaticInvocationA(this.function, this.continuation); 674 StaticInvocationA(this.function, this.handlers, this.continuation);
640 675
641 Configuration call(List<InterpreterValue> argValues) { 676 Configuration call(List<InterpreterValue> argValues) {
642 Environment functionEnv = 677 Environment functionEnv =
643 ApplicationContinuation.createEnvironment(function, argValues); 678 ApplicationContinuation.createEnvironment(function, argValues);
644 State bodyState = new State( 679 State bodyState = new State(null, handlers, continuation,
645 null, continuation, new ExitSK(continuation, Value.nullInstance)); 680 new ExitSK(continuation, Value.nullInstance));
646 681
647 return new ExecConfiguration(function.body, functionEnv, bodyState); 682 return new ExecConfiguration(function.body, functionEnv, bodyState);
648 } 683 }
649 } 684 }
650 685
651 /// Represents the application continuation for constructor invocation applied 686 /// Represents the application continuation for constructor invocation applied
652 /// on the list of evaluated arguments when a constructor is invoked with new. 687 /// on the list of evaluated arguments when a constructor is invoked with new.
653 /// 688 ///
654 /// It creates the newly allocated object instance. 689 /// It creates the newly allocated object instance.
655 class ConstructorInvocationA extends ApplicationContinuation { 690 class ConstructorInvocationA extends ApplicationContinuation {
656 final Constructor constructor; 691 final Constructor constructor;
692 final Handlers handlers;
657 final ExpressionContinuation continuation; 693 final ExpressionContinuation continuation;
658 694
659 ConstructorInvocationA(this.constructor, this.continuation); 695 ConstructorInvocationA(this.constructor, this.handlers, this.continuation);
660 696
661 Configuration call(List<InterpreterValue> argValues) { 697 Configuration call(List<InterpreterValue> argValues) {
662 Environment ctrEnv = ApplicationContinuation.createEnvironment( 698 Environment ctrEnv = ApplicationContinuation.createEnvironment(
663 constructor.function, argValues); 699 constructor.function, argValues);
664 var class_ = new Class(constructor.enclosingClass.reference); 700 var class_ = new Class(constructor.enclosingClass.reference);
665 var newObject = new ObjectValue(class_); 701 var newObject = new ObjectValue(class_);
666 var cont = new InitializationEK( 702 var cont = new InitializationEK(constructor, ctrEnv, handlers,
667 constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); 703 new NewSK(continuation, new Location(newObject)));
668 704
669 return new ValuePassingConfiguration(cont, newObject); 705 return new ValuePassingConfiguration(cont, newObject);
670 } 706 }
671 } 707 }
672 708
673 /// Represents the application continuation for constructor invocation applied 709 /// Represents the application continuation for constructor invocation applied
674 /// on the list of evaluated arguments when a constructor is invoked in a 710 /// on the list of evaluated arguments when a constructor is invoked in a
675 /// constructor initializer list with a [RedirectingInitializer] or 711 /// constructor initializer list with a [RedirectingInitializer] or
676 /// [SuperInitializer]. 712 /// [SuperInitializer].
677 class ConstructorInitializerA extends ApplicationContinuation { 713 class ConstructorInitializerA extends ApplicationContinuation {
678 final Constructor constructor; 714 final Constructor constructor;
679 final Location location; 715 final Location location;
716 final Handlers handlers;
680 final ConstructorBodySK continuation; 717 final ConstructorBodySK continuation;
681 718
682 ConstructorInitializerA(this.constructor, this.location, this.continuation); 719 ConstructorInitializerA(
720 this.constructor, this.location, this.handlers, this.continuation);
683 721
684 Configuration call(List<InterpreterValue> vs) { 722 Configuration call(List<InterpreterValue> vs) {
685 Environment ctrEnv = 723 Environment ctrEnv =
686 ApplicationContinuation.createEnvironment(constructor.function, vs); 724 ApplicationContinuation.createEnvironment(constructor.function, vs);
687 var cont = new InitializationEK(constructor, ctrEnv, continuation); 725 var cont =
726 new InitializationEK(constructor, ctrEnv, handlers, continuation);
688 727
689 return new ValuePassingConfiguration(cont, location.value); 728 return new ValuePassingConfiguration(cont, location.value);
690 } 729 }
691 } 730 }
692 731
693 /// Represents the application continuation applied on the list of evaluated 732 /// Represents the application continuation applied on the list of evaluated
694 /// field initializer expressions. 733 /// field initializer expressions.
695 class InstanceFieldsA extends ApplicationContinuation { 734 class InstanceFieldsA extends ApplicationContinuation {
696 final Constructor constructor; 735 final Constructor constructor;
697 final Location location; 736 final Location location;
698 final Environment environment; 737 final Environment environment;
738 final Handlers handlers;
699 final ConstructorBodySK continuation; 739 final ConstructorBodySK continuation;
700 740
701 final Class _currentClass; 741 final Class _currentClass;
702 742
703 InstanceFieldsA( 743 InstanceFieldsA(this.constructor, this.location, this.environment,
704 this.constructor, this.location, this.environment, this.continuation) 744 this.handlers, this.continuation)
705 : _currentClass = new Class(constructor.enclosingClass.reference); 745 : _currentClass = new Class(constructor.enclosingClass.reference);
706 746
707 Configuration call(List<InterpreterValue> fieldValues) { 747 Configuration call(List<InterpreterValue> fieldValues) {
708 for (FieldInitializerValue f in fieldValues) { 748 for (FieldInitializerValue f in fieldValues) {
709 // Directly set the field with the corresponding implicit setter. 749 // Directly set the field with the corresponding implicit setter.
710 _currentClass.implicitSetters[f.field.name](location.value, f.value); 750 _currentClass.implicitSetters[f.field.name](location.value, f.value);
711 } 751 }
712 752
713 if (constructor.initializers.length == 0) { 753 if (constructor.initializers.length == 0) {
714 // This can happen when initializing fields of Ctr with empty initializer 754 // This can happen when initializing fields of Ctr with empty initializer
(...skipping 14 matching lines...) Expand all
729 } 769 }
730 770
731 // Otherwise, the next expression from Field or Local initializers will be 771 // Otherwise, the next expression from Field or Local initializers will be
732 // evaluated. 772 // evaluated.
733 return _createEvalConfig(constructor.initializers.first); 773 return _createEvalConfig(constructor.initializers.first);
734 } 774 }
735 775
736 Configuration _createEvalListConfig(SuperInitializer initializer) { 776 Configuration _createEvalListConfig(SuperInitializer initializer) {
737 List<InterpreterExpression> args = _getArgumentExpressions( 777 List<InterpreterExpression> args = _getArgumentExpressions(
738 initializer.arguments, initializer.target.function); 778 initializer.arguments, initializer.target.function);
739 var cont = 779 var cont = new ConstructorInitializerA(
740 new ConstructorInitializerA(initializer.target, location, continuation); 780 initializer.target, location, handlers, continuation);
741 781
742 return new EvalListConfiguration(args, environment, cont); 782 return new EvalListConfiguration(args, environment, handlers, cont);
743 } 783 }
744 784
745 EvalConfiguration _createEvalConfig(Initializer initializer) { 785 EvalConfiguration _createEvalConfig(Initializer initializer) {
746 Expression expr = (initializer is FieldInitializer) 786 Expression expr = (initializer is FieldInitializer)
747 ? initializer.value 787 ? initializer.value
748 : (initializer as LocalInitializer).variable.initializer; 788 : (initializer as LocalInitializer).variable.initializer;
749 789
750 // We start with index = 0 since we are evaluating the expression for the 790 // We start with index = 0 since we are evaluating the expression for the
751 // first initializer in the initializer list. 791 // first initializer in the initializer list.
752 var cont = new InitializerListEK( 792 var cont = new InitializerListEK(
753 constructor, 0, location, environment, continuation); 793 constructor, 0, location, environment, handlers, continuation);
754 return new EvalConfiguration(expr, environment, cont); 794 return new EvalConfiguration(expr, environment, handlers, cont);
755 } 795 }
756 } 796 }
757 // ------------------------------------------------------------------------ 797 // ------------------------------------------------------------------------
758 // Expression Continuations 798 // Expression Continuations
759 // ------------------------------------------------------------------------ 799 // ------------------------------------------------------------------------
760 800
761 /// Represents an expression continuation. 801 /// Represents an expression continuation.
762 /// 802 ///
763 /// There are various kinds of [ExpressionContinuation]s and their names are 803 /// There are various kinds of [ExpressionContinuation]s and their names are
764 /// suffixed with "EK". 804 /// suffixed with "EK".
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 Configuration call(Value receiver) { 840 Configuration call(Value receiver) {
801 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver); 841 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver);
802 return new ValuePassingConfiguration(continuation, propertyValue); 842 return new ValuePassingConfiguration(continuation, propertyValue);
803 } 843 }
804 } 844 }
805 845
806 class PropertySetEK extends ExpressionContinuation { 846 class PropertySetEK extends ExpressionContinuation {
807 final Expression value; 847 final Expression value;
808 final Name setterName; 848 final Name setterName;
809 final Environment environment; 849 final Environment environment;
850 final Handlers handlers;
810 final ExpressionContinuation continuation; 851 final ExpressionContinuation continuation;
811 852
812 PropertySetEK( 853 PropertySetEK(this.value, this.setterName, this.environment, this.handlers,
813 this.value, this.setterName, this.environment, this.continuation); 854 this.continuation);
814 855
815 Configuration call(Value receiver) { 856 Configuration call(Value receiver) {
816 var cont = new SetterEK(receiver, setterName, continuation); 857 var cont = new SetterEK(receiver, setterName, continuation);
817 return new EvalConfiguration(value, environment, cont); 858 return new EvalConfiguration(value, environment, handlers, cont);
818 } 859 }
819 } 860 }
820 861
821 class SetterEK extends ExpressionContinuation { 862 class SetterEK extends ExpressionContinuation {
822 final Value receiver; 863 final Value receiver;
823 final Name name; 864 final Name name;
824 final ExpressionContinuation continuation; 865 final ExpressionContinuation continuation;
825 866
826 SetterEK(this.receiver, this.name, this.continuation); 867 SetterEK(this.receiver, this.name, this.continuation);
827 868
828 Configuration call(Value v) { 869 Configuration call(Value v) {
829 Setter setter = receiver.class_.lookupImplicitSetter(name); 870 Setter setter = receiver.class_.lookupImplicitSetter(name);
830 setter(receiver, v); 871 setter(receiver, v);
831 return new ValuePassingConfiguration(continuation, v); 872 return new ValuePassingConfiguration(continuation, v);
832 } 873 }
833 } 874 }
834 875
835 /// Represents a continuation to be called after the evaluation of an actual 876 /// Represents a continuation to be called after the evaluation of an actual
836 /// argument for function invocation. 877 /// argument for function invocation.
837 class ExpressionListEK extends ExpressionContinuation { 878 class ExpressionListEK extends ExpressionContinuation {
838 final InterpreterExpression currentExpression; 879 final InterpreterExpression currentExpression;
839 final List<InterpreterExpression> expressions; 880 final List<InterpreterExpression> expressions;
840 final Environment environment; 881 final Environment environment;
882 final Handlers handlers;
841 final ApplicationContinuation applicationContinuation; 883 final ApplicationContinuation applicationContinuation;
842 884
843 ExpressionListEK(this.currentExpression, this.expressions, this.environment, 885 ExpressionListEK(this.currentExpression, this.expressions, this.environment,
844 this.applicationContinuation); 886 this.handlers, this.applicationContinuation);
845 887
846 Configuration call(Value v) { 888 Configuration call(Value v) {
847 ValueA app = 889 ValueA app =
848 new ValueA(currentExpression.assignValue(v), applicationContinuation); 890 new ValueA(currentExpression.assignValue(v), applicationContinuation);
849 return new EvalListConfiguration(expressions, environment, app); 891 return new EvalListConfiguration(expressions, environment, handlers, app);
850 } 892 }
851 } 893 }
852 894
853 class MethodInvocationEK extends ExpressionContinuation { 895 class MethodInvocationEK extends ExpressionContinuation {
854 final Arguments arguments; 896 final Arguments arguments;
855 final Name methodName; 897 final Name methodName;
856 final Environment environment; 898 final Environment environment;
899 final Handlers handlers;
857 final ExpressionContinuation continuation; 900 final ExpressionContinuation continuation;
858 901
859 MethodInvocationEK( 902 MethodInvocationEK(this.arguments, this.methodName, this.environment,
860 this.arguments, this.methodName, this.environment, this.continuation); 903 this.handlers, this.continuation);
861 904
862 Configuration call(Value receiver) { 905 Configuration call(Value receiver) {
863 if (arguments.positional.isEmpty) { 906 if (arguments.positional.isEmpty) {
864 Value returnValue = receiver.invokeMethod(methodName); 907 Value returnValue = receiver.invokeMethod(methodName);
865 return new ValuePassingConfiguration(continuation, returnValue); 908 return new ValuePassingConfiguration(continuation, returnValue);
866 } 909 }
867 var cont = new ArgumentsEK( 910 var cont = new ArgumentsEK(
868 receiver, methodName, arguments, environment, continuation); 911 receiver, methodName, arguments, environment, continuation);
869 912
870 return new EvalConfiguration(arguments.positional.first, environment, cont); 913 return new EvalConfiguration(
914 arguments.positional.first, environment, handlers, cont);
871 } 915 }
872 } 916 }
873 917
874 class ArgumentsEK extends ExpressionContinuation { 918 class ArgumentsEK extends ExpressionContinuation {
875 final Value receiver; 919 final Value receiver;
876 final Name methodName; 920 final Name methodName;
877 final Arguments arguments; 921 final Arguments arguments;
878 final Environment environment; 922 final Environment environment;
879 final ExpressionContinuation continuation; 923 final ExpressionContinuation continuation;
880 924
(...skipping 30 matching lines...) Expand all
911 Value notValue = identical(Value.trueInstance, value) 955 Value notValue = identical(Value.trueInstance, value)
912 ? Value.falseInstance 956 ? Value.falseInstance
913 : Value.trueInstance; 957 : Value.trueInstance;
914 return new ValuePassingConfiguration(continuation, notValue); 958 return new ValuePassingConfiguration(continuation, notValue);
915 } 959 }
916 } 960 }
917 961
918 class OrEK extends ExpressionContinuation { 962 class OrEK extends ExpressionContinuation {
919 final Expression right; 963 final Expression right;
920 final Environment environment; 964 final Environment environment;
965 final Handlers handlers;
921 final ExpressionContinuation continuation; 966 final ExpressionContinuation continuation;
922 967
923 OrEK(this.right, this.environment, this.continuation); 968 OrEK(this.right, this.environment, this.handlers, this.continuation);
924 969
925 Configuration call(Value left) { 970 Configuration call(Value left) {
926 return identical(Value.trueInstance, left) 971 return identical(Value.trueInstance, left)
927 ? new ValuePassingConfiguration(continuation, Value.trueInstance) 972 ? new ValuePassingConfiguration(continuation, Value.trueInstance)
928 : new EvalConfiguration(right, environment, continuation); 973 : new EvalConfiguration(right, environment, handlers, continuation);
929 } 974 }
930 } 975 }
931 976
932 class AndEK extends ExpressionContinuation { 977 class AndEK extends ExpressionContinuation {
933 final Expression right; 978 final Expression right;
934 final Environment environment; 979 final Environment environment;
980 final Handlers handlers;
935 final ExpressionContinuation continuation; 981 final ExpressionContinuation continuation;
936 982
937 AndEK(this.right, this.environment, this.continuation); 983 AndEK(this.right, this.environment, this.handlers, this.continuation);
938 984
939 Configuration call(Value left) { 985 Configuration call(Value left) {
940 return identical(Value.falseInstance, left) 986 return identical(Value.falseInstance, left)
941 ? new ValuePassingConfiguration(continuation, Value.falseInstance) 987 ? new ValuePassingConfiguration(continuation, Value.falseInstance)
942 : new EvalConfiguration(right, environment, continuation); 988 : new EvalConfiguration(right, environment, handlers, continuation);
943 } 989 }
944 } 990 }
945 991
946 class ConditionalEK extends ExpressionContinuation { 992 class ConditionalEK extends ExpressionContinuation {
947 final Expression then; 993 final Expression then;
948 final Expression otherwise; 994 final Expression otherwise;
949 final Environment environment; 995 final Environment environment;
996 final Handlers handlers;
950 final ExpressionContinuation continuation; 997 final ExpressionContinuation continuation;
951 998
952 ConditionalEK(this.then, this.otherwise, this.environment, this.continuation); 999 ConditionalEK(this.then, this.otherwise, this.environment, this.handlers,
1000 this.continuation);
953 1001
954 Configuration call(Value value) { 1002 Configuration call(Value value) {
955 return identical(Value.trueInstance, value) 1003 return identical(Value.trueInstance, value)
956 ? new EvalConfiguration(then, environment, continuation) 1004 ? new EvalConfiguration(then, environment, handlers, continuation)
957 : new EvalConfiguration(otherwise, environment, continuation); 1005 : new EvalConfiguration(otherwise, environment, handlers, continuation);
958 } 1006 }
959 } 1007 }
960 1008
961 class LetEK extends ExpressionContinuation { 1009 class LetEK extends ExpressionContinuation {
962 final VariableDeclaration variable; 1010 final VariableDeclaration variable;
963 final Expression letBody; 1011 final Expression letBody;
964 final Environment environment; 1012 final Environment environment;
1013 final Handlers handlers;
965 final ExpressionContinuation continuation; 1014 final ExpressionContinuation continuation;
966 1015
967 LetEK(this.variable, this.letBody, this.environment, this.continuation); 1016 LetEK(this.variable, this.letBody, this.environment, this.handlers,
1017 this.continuation);
968 1018
969 Configuration call(Value value) { 1019 Configuration call(Value value) {
970 var letEnv = new Environment(environment); 1020 var letEnv = new Environment(environment);
971 letEnv.extend(variable, value); 1021 letEnv.extend(variable, value);
972 return new EvalConfiguration(letBody, letEnv, continuation); 1022 return new EvalConfiguration(letBody, letEnv, handlers, continuation);
973 } 1023 }
974 } 1024 }
975 1025
976 /// Represents the continuation for the condition expression in [WhileStatement] . 1026 /// Represents the continuation for the condition expression in [WhileStatement] .
977 class WhileConditionEK extends ExpressionContinuation { 1027 class WhileConditionEK extends ExpressionContinuation {
978 final Expression condition; 1028 final Expression condition;
979 final Statement body; 1029 final Statement body;
980 final Environment enclosingEnv; 1030 final Environment enclosingEnv;
981 final State state; 1031 final State state;
982 1032
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 return new ForwardConfiguration( 1075 return new ForwardConfiguration(
1026 continuation, environment.extend(variable, v)); 1076 continuation, environment.extend(variable, v));
1027 } 1077 }
1028 } 1078 }
1029 1079
1030 /// Expression continuation that further initializes the newly allocated object 1080 /// Expression continuation that further initializes the newly allocated object
1031 /// instance with running the constructor. 1081 /// instance with running the constructor.
1032 class InitializationEK extends ExpressionContinuation { 1082 class InitializationEK extends ExpressionContinuation {
1033 final Constructor constructor; 1083 final Constructor constructor;
1034 final Environment environment; 1084 final Environment environment;
1035 // TODO(zhivkag): Add components for exception handling support 1085 final Handlers handlers;
1036 final StatementContinuation continuation; 1086 final StatementContinuation continuation;
1037 1087
1038 InitializationEK(this.constructor, this.environment, this.continuation); 1088 InitializationEK(
1089 this.constructor, this.environment, this.handlers, this.continuation);
1039 1090
1040 Configuration call(Value value) { 1091 Configuration call(Value value) {
1041 Location location = new Location(value); 1092 Location location = new Location(value);
1042 1093
1043 if (constructor.initializers.isNotEmpty && 1094 if (constructor.initializers.isNotEmpty &&
1044 constructor.initializers.last is RedirectingInitializer) { 1095 constructor.initializers.last is RedirectingInitializer) {
1045 return _createRedirectingInitializerConfig( 1096 return _createRedirectingInitializerConfig(
1046 constructor.initializers.first, location); 1097 constructor.initializers.first, location);
1047 } 1098 }
1048 // The statement body is captured by the next statement continuation and 1099 // The statement body is captured by the next statement continuation and
1049 // expressions for field initialization are evaluated. 1100 // expressions for field initialization are evaluated.
1050 var ctrEnv = environment.extendWithThis(value); 1101 var ctrEnv = environment.extendWithThis(value);
1051 var bodyCont = 1102 var bodyCont = new ConstructorBodySK(
1052 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); 1103 constructor.function.body, ctrEnv, handlers, continuation);
1053 var initializers = _getFieldInitializers(constructor.enclosingClass); 1104 var initializers = _getFieldInitializers(constructor.enclosingClass);
1054 var fieldsCont = 1105 var fieldsCont =
1055 new InstanceFieldsA(constructor, location, ctrEnv, bodyCont); 1106 new InstanceFieldsA(constructor, location, ctrEnv, handlers, bodyCont);
1056 return new EvalListConfiguration( 1107 return new EvalListConfiguration(
1057 initializers, new Environment.empty(), fieldsCont); 1108 initializers, new Environment.empty(), handlers, fieldsCont);
1058 } 1109 }
1059 1110
1060 /// Creates the next configuration to further initializer the value for 1111 /// Creates the next configuration to further initializer the value for
1061 /// redirecting constructors. 1112 /// redirecting constructors.
1062 Configuration _createRedirectingInitializerConfig( 1113 Configuration _createRedirectingInitializerConfig(
1063 Initializer initializer, Location location) { 1114 Initializer initializer, Location location) {
1064 Initializer current = constructor.initializers.first; 1115 Initializer current = constructor.initializers.first;
1065 if (current is RedirectingInitializer) { 1116 if (current is RedirectingInitializer) {
1066 // eval list of args with current env 1117 // eval list of args with current env
1067 List<InterpreterExpression> exprs = 1118 List<InterpreterExpression> exprs =
1068 _getArgumentExpressions(current.arguments, current.target.function); 1119 _getArgumentExpressions(current.arguments, current.target.function);
1069 var cont = 1120 var cont = new ConstructorInitializerA(
1070 new ConstructorInitializerA(current.target, location, continuation); 1121 current.target, location, handlers, continuation);
1071 return new EvalListConfiguration(exprs, environment, cont); 1122 return new EvalListConfiguration(exprs, environment, handlers, cont);
1072 } 1123 }
1073 Expression expr = (current is FieldInitializer) 1124 Expression expr = (current is FieldInitializer)
1074 ? current.value 1125 ? current.value
1075 : (current as LocalInitializer).variable.initializer; 1126 : (current as LocalInitializer).variable.initializer;
1076 1127
1077 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, 1128 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/,
1078 location, environment, continuation); 1129 location, environment, handlers, continuation);
1079 return new EvalConfiguration(expr, environment, cont); 1130 return new EvalConfiguration(expr, environment, handlers, cont);
1080 } 1131 }
1081 } 1132 }
1082 1133
1083 class InitializerListEK extends ExpressionContinuation { 1134 class InitializerListEK extends ExpressionContinuation {
1084 final Constructor constructor; 1135 final Constructor constructor;
1085 final int initializerIndex; 1136 final int initializerIndex;
1086 final Location location; 1137 final Location location;
1087 final Environment environment; 1138 final Environment environment;
1088 // TODO(zhivkag): Add componnents for exception handling. 1139 final Handlers handlers;
1089 final ConstructorBodySK continuation; 1140 final ConstructorBodySK continuation;
1141
1090 final Class _currentClass; 1142 final Class _currentClass;
1091 1143
1092 InitializerListEK(this.constructor, this.initializerIndex, this.location, 1144 InitializerListEK(this.constructor, this.initializerIndex, this.location,
1093 this.environment, this.continuation) 1145 this.environment, this.handlers, this.continuation)
1094 : _currentClass = new Class(constructor.enclosingClass.reference); 1146 : _currentClass = new Class(constructor.enclosingClass.reference);
1095 1147
1096 /// Creates a continuation for the evaluation of the initializer at position 1148 /// Creates a continuation for the evaluation of the initializer at position
1097 /// [index]. 1149 /// [index].
1098 InitializerListEK withInitializerIndex(int index) { 1150 InitializerListEK withInitializerIndex(int index) {
1099 return new InitializerListEK( 1151 return new InitializerListEK(
1100 constructor, index, location, environment, continuation); 1152 constructor, index, location, environment, handlers, continuation);
1101 } 1153 }
1102 1154
1103 Configuration call(Value value) { 1155 Configuration call(Value value) {
1104 Initializer current = constructor.initializers[initializerIndex]; 1156 Initializer current = constructor.initializers[initializerIndex];
1105 if (current is FieldInitializer) { 1157 if (current is FieldInitializer) {
1106 _currentClass.lookupImplicitSetter(current.field.name)( 1158 _currentClass.lookupImplicitSetter(current.field.name)(
1107 location.value, value); 1159 location.value, value);
1108 return _createNextConfiguration(environment); 1160 return _createNextConfiguration(environment);
1109 } 1161 }
1110 if (current is LocalInitializer) { 1162 if (current is LocalInitializer) {
(...skipping 18 matching lines...) Expand all
1129 1181
1130 if (next is RedirectingInitializer) { 1182 if (next is RedirectingInitializer) {
1131 return _createEvalListConfig(next.arguments, next.target, env); 1183 return _createEvalListConfig(next.arguments, next.target, env);
1132 } 1184 }
1133 1185
1134 Expression nextExpr = (next is FieldInitializer) 1186 Expression nextExpr = (next is FieldInitializer)
1135 ? next.value 1187 ? next.value
1136 : (next as LocalInitializer).variable.initializer; 1188 : (next as LocalInitializer).variable.initializer;
1137 1189
1138 var cont = withInitializerIndex(initializerIndex + 1); 1190 var cont = withInitializerIndex(initializerIndex + 1);
1139 return new EvalConfiguration(nextExpr, env, cont); 1191 return new EvalConfiguration(nextExpr, env, handlers, cont);
1140 } 1192 }
1141 1193
1142 Configuration _createEvalListConfig( 1194 Configuration _createEvalListConfig(
1143 Arguments args, Constructor ctr, Environment env) { 1195 Arguments args, Constructor ctr, Environment env) {
1144 List<InterpreterExpression> exprs = 1196 List<InterpreterExpression> exprs =
1145 _getArgumentExpressions(args, ctr.function); 1197 _getArgumentExpressions(args, ctr.function);
1146 var cont = new ConstructorInitializerA(ctr, location, continuation); 1198 var cont =
1147 return new EvalListConfiguration(exprs, env, cont); 1199 new ConstructorInitializerA(ctr, location, handlers, continuation);
1200 return new EvalListConfiguration(exprs, env, handlers, cont);
1148 } 1201 }
1149 } 1202 }
1150 1203
1204 // ------------------------------------------------------------------------
1205 // Exceptions Handlers
1206 // ------------------------------------------------------------------------
1207
1208 abstract class ExceptionHandler extends Continuation {
1209 ExceptionHandler get nextHandler;
1210
1211 Configuration call(Value exception, StackTrace stacktrace);
1212 }
1213
1214 // ------------------------------------------------------------------------
1215 // Exceptions
1216 // ------------------------------------------------------------------------
1217 /// Represents the components for Exception handling.
1218 ///
1219 /// It contains the list of exception handlers, a stack trace and optional
1220 /// components, current stacktrace and exception.
1221 class Handlers {
Dmitry Stefantsov 2017/08/03 08:45:17 I get it that [Handlers] contains all the informat
1222 final ExceptionHandler handler;
1223 final StackTrace stackTrace;
1224
1225 /// Current exception and stack trace.
1226 ///
1227 /// Components enabling support for `rethrow` expressions and set only in
1228 /// catch clauses.
1229 final StackTrace currentStackTrace;
1230 final Value currentException;
1231
1232 Handlers(this.handler, this.stackTrace, this.currentStackTrace,
1233 this.currentException);
1234
1235 // TODO(zhivkag): Add a top level handler for initial exception state.
1236 Handlers.initial()
1237 : handler = null,
1238 stackTrace = null,
1239 currentStackTrace = null,
1240 currentException = null;
1241 }
1242
1243 class StackTrace {
1244 final Expression expression;
1245 final StackTrace stackTrace;
1246
1247 StackTrace(this.expression, this.stackTrace);
1248 }
1249
1151 /// Executes statements. 1250 /// Executes statements.
1152 /// 1251 ///
1153 /// Execution of a statement completes in one of the following ways: 1252 /// Execution of a statement completes in one of the following ways:
1154 /// - It completes normally, in which case the execution proceeds to applying 1253 /// - It completes normally, in which case the execution proceeds to applying
1155 /// the next continuation. 1254 /// the next continuation.
1156 /// - It breaks with a label, in which case the corresponding continuation is 1255 /// - It breaks with a label, in which case the corresponding continuation is
1157 /// returned and applied. 1256 /// returned and applied.
1158 /// - It returns with or without value, in which case the return continuation is 1257 /// - It returns with or without value, in which case the return continuation is
1159 /// returned and applied accordingly. 1258 /// returned and applied accordingly.
1160 /// - It throws, in which case the handler is returned and applied accordingly. 1259 /// - It throws, in which case the handler is returned and applied accordingly.
1161 class StatementExecuter 1260 class StatementExecuter
1162 extends StatementVisitor1<Configuration, ExecConfiguration> { 1261 extends StatementVisitor1<Configuration, ExecConfiguration> {
1163 Evaluator evaluator = new Evaluator(); 1262 Evaluator evaluator = new Evaluator();
1164 1263
1165 void trampolinedExecution(Configuration configuration) { 1264 void trampolinedExecution(Configuration configuration) {
1166 while (configuration != null) { 1265 while (configuration != null) {
1167 configuration = configuration.step(this); 1266 configuration = configuration.step(this);
1168 } 1267 }
1169 } 1268 }
1170 1269
1171 Configuration exec(Statement statement, ExecConfiguration conf) => 1270 Configuration exec(Statement statement, ExecConfiguration conf) =>
1172 statement.accept1(this, conf); 1271 statement.accept1(this, conf);
1173 Configuration eval(Expression expression, EvalConfiguration config) => 1272 Configuration eval(Expression expression, EvalConfiguration config) =>
1174 evaluator.eval(expression, config); 1273 evaluator.eval(expression, config);
1175 Configuration evalList( 1274 Configuration evalList(List<InterpreterExpression> es, Environment env,
1176 List<InterpreterExpression> es, Environment env, Continuation cont) => 1275 Handlers handlers, Continuation cont) =>
1177 evaluator.evalList(es, env, cont); 1276 evaluator.evalList(es, env, handlers, cont);
1178 1277
1179 Configuration defaultStatement(Statement node, ExecConfiguration conf) { 1278 Configuration defaultStatement(Statement node, ExecConfiguration conf) {
1180 throw notImplemented( 1279 throw notImplemented(
1181 m: "Execution is not implemented for statement:\n$node "); 1280 m: "Execution is not implemented for statement:\n$node ");
1182 } 1281 }
1183 1282
1184 Configuration visitInvalidStatement( 1283 Configuration visitInvalidStatement(
1185 InvalidStatement node, ExecConfiguration conf) { 1284 InvalidStatement node, ExecConfiguration conf) {
1186 throw "Invalid statement at ${node.location}"; 1285 throw "Invalid statement at ${node.location}";
1187 } 1286 }
1188 1287
1189 Configuration visitExpressionStatement( 1288 Configuration visitExpressionStatement(
1190 ExpressionStatement node, ExecConfiguration conf) { 1289 ExpressionStatement node, ExecConfiguration conf) {
1191 var cont = new ExpressionEK(conf.state.continuation, conf.environment); 1290 var cont = new ExpressionEK(conf.state.continuation, conf.environment);
1192 return new EvalConfiguration(node.expression, conf.environment, cont); 1291 return new EvalConfiguration(
1292 node.expression, conf.environment, conf.state.handlers, cont);
1193 } 1293 }
1194 1294
1195 Configuration visitBlock(Block node, ExecConfiguration conf) { 1295 Configuration visitBlock(Block node, ExecConfiguration conf) {
1196 if (node.statements.isEmpty) { 1296 if (node.statements.isEmpty) {
1197 return new ForwardConfiguration( 1297 return new ForwardConfiguration(
1198 conf.state.continuation, conf.environment); 1298 conf.state.continuation, conf.environment);
1199 } 1299 }
1200 1300
1201 var env = new Environment(conf.environment); 1301 var env = new Environment(conf.environment);
1202 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); 1302 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf);
1203 return new ExecConfiguration( 1303 return new ExecConfiguration(
1204 node.statements.first, env, conf.state.withContinuation(cont)); 1304 node.statements.first, env, conf.state.withContinuation(cont));
1205 } 1305 }
1206 1306
1207 Configuration visitEmptyStatement( 1307 Configuration visitEmptyStatement(
1208 EmptyStatement node, ExecConfiguration conf) { 1308 EmptyStatement node, ExecConfiguration conf) {
1209 return new ForwardConfiguration(conf.state.continuation, conf.environment); 1309 return new ForwardConfiguration(conf.state.continuation, conf.environment);
1210 } 1310 }
1211 1311
1212 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { 1312 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) {
1213 var cont = new IfConditionEK( 1313 var cont = new IfConditionEK(
1214 node.then, node.otherwise, conf.environment, conf.state); 1314 node.then, node.otherwise, conf.environment, conf.state);
1215 1315
1216 return new EvalConfiguration(node.condition, conf.environment, cont); 1316 return new EvalConfiguration(
1317 node.condition, conf.environment, conf.state.handlers, cont);
1217 } 1318 }
1218 1319
1219 Configuration visitLabeledStatement( 1320 Configuration visitLabeledStatement(
1220 LabeledStatement node, ExecConfiguration conf) { 1321 LabeledStatement node, ExecConfiguration conf) {
1221 return new ExecConfiguration(node.body, conf.environment, 1322 return new ExecConfiguration(node.body, conf.environment,
1222 conf.state.withBreak(node, conf.environment)); 1323 conf.state.withBreak(node, conf.environment));
1223 } 1324 }
1224 1325
1225 Configuration visitBreakStatement( 1326 Configuration visitBreakStatement(
1226 BreakStatement node, ExecConfiguration conf) { 1327 BreakStatement node, ExecConfiguration conf) {
1227 Label l = conf.state.lookupLabel(node.target); 1328 Label l = conf.state.lookupLabel(node.target);
1228 return new ForwardConfiguration(l.continuation, l.environment); 1329 return new ForwardConfiguration(l.continuation, l.environment);
1229 } 1330 }
1230 1331
1231 Configuration visitWhileStatement( 1332 Configuration visitWhileStatement(
1232 WhileStatement node, ExecConfiguration conf) { 1333 WhileStatement node, ExecConfiguration conf) {
1233 var cont = new WhileConditionEK( 1334 var cont = new WhileConditionEK(
1234 node.condition, node.body, conf.environment, conf.state); 1335 node.condition, node.body, conf.environment, conf.state);
1235 1336
1236 return new EvalConfiguration(node.condition, conf.environment, cont); 1337 return new EvalConfiguration(
1338 node.condition, conf.environment, conf.state.handlers, cont);
1237 } 1339 }
1238 1340
1239 Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) { 1341 Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) {
1240 var cont = new WhileConditionSK( 1342 var cont = new WhileConditionSK(
1241 node.condition, node.body, conf.environment, conf.state); 1343 node.condition, node.body, conf.environment, conf.state);
1242 1344
1243 return new ExecConfiguration( 1345 return new ExecConfiguration(
1244 node.body, conf.environment, conf.state.withContinuation(cont)); 1346 node.body, conf.environment, conf.state.withContinuation(cont));
1245 } 1347 }
1246 1348
1247 Configuration visitReturnStatement( 1349 Configuration visitReturnStatement(
1248 ReturnStatement node, ExecConfiguration conf) { 1350 ReturnStatement node, ExecConfiguration conf) {
1249 assert(conf.state.returnContinuation != null); 1351 assert(conf.state.returnContinuation != null);
1250 log.info('return\n'); 1352 log.info('return\n');
1251 if (node.expression == null) { 1353 if (node.expression == null) {
1252 return new ValuePassingConfiguration( 1354 return new ValuePassingConfiguration(
1253 conf.state.returnContinuation, Value.nullInstance); 1355 conf.state.returnContinuation, Value.nullInstance);
1254 } 1356 }
1255 1357 return new EvalConfiguration(node.expression, conf.environment,
1256 return new EvalConfiguration( 1358 conf.state.handlers, conf.state.returnContinuation);
1257 node.expression, conf.environment, conf.state.returnContinuation);
1258 } 1359 }
1259 1360
1260 Configuration visitVariableDeclaration( 1361 Configuration visitVariableDeclaration(
1261 VariableDeclaration node, ExecConfiguration conf) { 1362 VariableDeclaration node, ExecConfiguration conf) {
1262 if (node.initializer != null) { 1363 if (node.initializer != null) {
1263 var cont = new VariableInitializerEK( 1364 var cont = new VariableInitializerEK(
1264 node, conf.environment, conf.state.continuation); 1365 node, conf.environment, conf.state.continuation);
1265 return new EvalConfiguration(node.initializer, conf.environment, cont); 1366 return new EvalConfiguration(
1367 node.initializer, conf.environment, conf.state.handlers, cont);
1266 } 1368 }
1267 return new ForwardConfiguration(conf.state.continuation, 1369 return new ForwardConfiguration(conf.state.continuation,
1268 conf.environment.extend(node, Value.nullInstance)); 1370 conf.environment.extend(node, Value.nullInstance));
1269 } 1371 }
1270 } 1372 }
1271 1373
1272 // ------------------------------------------------------------------------ 1374 // ------------------------------------------------------------------------
1273 // VALUES 1375 // VALUES
1274 // ------------------------------------------------------------------------ 1376 // ------------------------------------------------------------------------
1275 1377
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 /// Initializes all non initialized fields from the provided class to 1663 /// Initializes all non initialized fields from the provided class to
1562 /// `Value.nullInstance` in the provided value. 1664 /// `Value.nullInstance` in the provided value.
1563 void _initializeNullFields(Class class_, Value value) { 1665 void _initializeNullFields(Class class_, Value value) {
1564 int startIndex = class_.superclass?.instanceSize ?? 0; 1666 int startIndex = class_.superclass?.instanceSize ?? 0;
1565 for (int i = startIndex; i < class_.instanceSize; i++) { 1667 for (int i = startIndex; i < class_.instanceSize; i++) {
1566 if (value.fields[i].value == null) { 1668 if (value.fields[i].value == null) {
1567 value.fields[i].value = Value.nullInstance; 1669 value.fields[i].value = Value.nullInstance;
1568 } 1670 }
1569 } 1671 }
1570 } 1672 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698