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

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

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