Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |