| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library tree_ir_tracer; | 5 library tree_ir_tracer; |
| 6 | 6 |
| 7 import 'dart:async' show EventSink; | 7 import 'dart:async' show EventSink; |
| 8 import '../tracer.dart'; | 8 import '../tracer.dart'; |
| 9 import 'tree_ir_nodes.dart'; | 9 import 'tree_ir_nodes.dart'; |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 void _addGotoStatement(Block target) { | 54 void _addGotoStatement(Block target) { |
| 55 blocks.last.statements.add(target); | 55 blocks.last.statements.add(target); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void _addBlock(Block block) { | 58 void _addBlock(Block block) { |
| 59 block.index = blocks.length; | 59 block.index = blocks.length; |
| 60 block.catcher = catcher; | 60 block.catcher = catcher; |
| 61 blocks.add(block); | 61 blocks.add(block); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void collect(RootNode node) { | 64 void collect(FunctionDefinition node) { |
| 65 node.forEachBody((Statement body) { | 65 _addBlock(new Block()..isEntryPoint = true); |
| 66 _addBlock(new Block()..isEntryPoint = true); | 66 visitStatement(node.body); |
| 67 visitStatement(body); | |
| 68 }); | |
| 69 } | 67 } |
| 70 | 68 |
| 71 visitLabeledStatement(LabeledStatement node) { | 69 visitLabeledStatement(LabeledStatement node) { |
| 72 Block target = new Block(node.label); | 70 Block target = new Block(node.label); |
| 73 breakTargets[node.label] = target; | 71 breakTargets[node.label] = target; |
| 74 visitStatement(node.body); | 72 visitStatement(node.body); |
| 75 _addBlock(target); | 73 _addBlock(target); |
| 76 visitStatement(node.next); | 74 visitStatement(node.next); |
| 77 } | 75 } |
| 78 | 76 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 visitStatement(node.catchBody); | 161 visitStatement(node.catchBody); |
| 164 | 162 |
| 165 substatements[node.tryBody] = tryBlock; | 163 substatements[node.tryBody] = tryBlock; |
| 166 substatements[node.catchBody] = catchBlock; | 164 substatements[node.catchBody] = catchBlock; |
| 167 } | 165 } |
| 168 | 166 |
| 169 visitExpressionStatement(ExpressionStatement node) { | 167 visitExpressionStatement(ExpressionStatement node) { |
| 170 _addStatement(node); | 168 _addStatement(node); |
| 171 visitStatement(node.next); | 169 visitStatement(node.next); |
| 172 } | 170 } |
| 173 | |
| 174 visitFunctionDeclaration(FunctionDeclaration node) { | |
| 175 _addStatement(node); | |
| 176 visitStatement(node.next); | |
| 177 } | |
| 178 | |
| 179 visitVariableDeclaration(VariableDeclaration node) { | |
| 180 _addStatement(node); | |
| 181 visitStatement(node.next); | |
| 182 } | |
| 183 } | 171 } |
| 184 | 172 |
| 185 class TreeTracer extends TracerUtil with StatementVisitor { | 173 class TreeTracer extends TracerUtil with StatementVisitor { |
| 186 String get passName => null; | 174 String get passName => null; |
| 187 | 175 |
| 188 final EventSink<String> output; | 176 final EventSink<String> output; |
| 189 | 177 |
| 190 TreeTracer(this.output); | 178 TreeTracer(this.output); |
| 191 | 179 |
| 192 List<Variable> parameters; | 180 List<Variable> parameters; |
| 193 Names names; | 181 Names names; |
| 194 BlockCollector collector; | 182 BlockCollector collector; |
| 195 int statementCounter; | 183 int statementCounter; |
| 196 | 184 |
| 197 void traceGraph(String name, RootNode node) { | 185 void traceGraph(String name, FunctionDefinition node) { |
| 198 if (node.isEmpty) return; | |
| 199 parameters = node.parameters; | 186 parameters = node.parameters; |
| 200 tag("cfg", () { | 187 tag("cfg", () { |
| 201 printProperty("name", name); | 188 printProperty("name", name); |
| 202 printRootNode(node); | 189 names = new Names(); |
| 190 statementCounter = 0; |
| 191 collector = new BlockCollector(); |
| 192 collector.collect(node); |
| 203 collector.blocks.forEach(printBlock); | 193 collector.blocks.forEach(printBlock); |
| 204 }); | 194 }); |
| 205 } | 195 } |
| 206 | 196 |
| 207 void printRootNode(RootNode node) { | |
| 208 collector = new BlockCollector(); | |
| 209 names = new Names(); | |
| 210 statementCounter = 0; | |
| 211 collector = new BlockCollector(); | |
| 212 collector.collect(node); | |
| 213 collector.blocks.forEach(printBlock); | |
| 214 } | |
| 215 | |
| 216 void printBlock(Block block) { | 197 void printBlock(Block block) { |
| 217 tag("block", () { | 198 tag("block", () { |
| 218 printProperty("name", block.name); | 199 printProperty("name", block.name); |
| 219 printProperty("from_bci", -1); | 200 printProperty("from_bci", -1); |
| 220 printProperty("to_bci", -1); | 201 printProperty("to_bci", -1); |
| 221 printProperty("predecessors", block.predecessors.map((b) => b.name)); | 202 printProperty("predecessors", block.predecessors.map((b) => b.name)); |
| 222 printProperty("successors", block.successors.map((b) => b.name)); | 203 printProperty("successors", block.successors.map((b) => b.name)); |
| 223 printEmptyProperty("xhandlers"); | 204 printEmptyProperty("xhandlers"); |
| 224 printEmptyProperty("flags"); | 205 printEmptyProperty("flags"); |
| 225 tag("states", () { | 206 tag("states", () { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 String tryTarget = collector.substatements[node.tryBody].name; | 293 String tryTarget = collector.substatements[node.tryBody].name; |
| 313 String catchParams = node.catchParameters.map(names.varName).join(','); | 294 String catchParams = node.catchParameters.map(names.varName).join(','); |
| 314 String catchTarget = collector.substatements[node.catchBody].name; | 295 String catchTarget = collector.substatements[node.catchBody].name; |
| 315 printStatement(null, 'try $tryTarget catch($catchParams) $catchTarget'); | 296 printStatement(null, 'try $tryTarget catch($catchParams) $catchTarget'); |
| 316 } | 297 } |
| 317 | 298 |
| 318 visitExpressionStatement(ExpressionStatement node) { | 299 visitExpressionStatement(ExpressionStatement node) { |
| 319 printStatement(null, expr(node.expression)); | 300 printStatement(null, expr(node.expression)); |
| 320 } | 301 } |
| 321 | 302 |
| 322 visitFunctionDeclaration(FunctionDeclaration node) { | |
| 323 printStatement(null, 'function ${node.definition.element.name}'); | |
| 324 } | |
| 325 | |
| 326 visitVariableDeclaration(VariableDeclaration node) { | |
| 327 String variable = names.varName(node.variable); | |
| 328 String value = expr(node.value); | |
| 329 printStatement(null, 'declare $variable = $value'); | |
| 330 } | |
| 331 | |
| 332 visitSetField(SetField node) { | 303 visitSetField(SetField node) { |
| 333 String object = expr(node.object); | 304 String object = expr(node.object); |
| 334 String field = node.field.name; | 305 String field = node.field.name; |
| 335 String value = expr(node.value); | 306 String value = expr(node.value); |
| 336 if (SubexpressionVisitor.usesInfixNotation(node.object)) { | 307 if (SubexpressionVisitor.usesInfixNotation(node.object)) { |
| 337 object = '($object)'; | 308 object = '($object)'; |
| 338 } | 309 } |
| 339 printStatement(null, '$object.$field = $value'); | 310 printStatement(null, '$object.$field = $value'); |
| 340 } | 311 } |
| 341 | 312 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 } | 389 } |
| 419 | 390 |
| 420 String visitConstant(Constant node) { | 391 String visitConstant(Constant node) { |
| 421 return "${node.value.toStructuredString()}"; | 392 return "${node.value.toStructuredString()}"; |
| 422 } | 393 } |
| 423 | 394 |
| 424 String visitThis(This node) { | 395 String visitThis(This node) { |
| 425 return "this"; | 396 return "this"; |
| 426 } | 397 } |
| 427 | 398 |
| 428 String visitReifyTypeVar(ReifyTypeVar node) { | |
| 429 return "typevar [${node.typeVariable.name}]"; | |
| 430 } | |
| 431 | |
| 432 static bool usesInfixNotation(Expression node) { | 399 static bool usesInfixNotation(Expression node) { |
| 433 return node is Conditional || | 400 return node is Conditional || |
| 434 node is LogicalOperator || | 401 node is LogicalOperator || |
| 435 node is Assign || | 402 node is Assign || |
| 436 node is SetField; | 403 node is SetField; |
| 437 } | 404 } |
| 438 | 405 |
| 439 String visitConditional(Conditional node) { | 406 String visitConditional(Conditional node) { |
| 440 String condition = visitExpression(node.condition); | 407 String condition = visitExpression(node.condition); |
| 441 String thenExpr = visitExpression(node.thenExpression); | 408 String thenExpr = visitExpression(node.thenExpression); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 466 if (usesInfixNotation(node.operand)) { | 433 if (usesInfixNotation(node.operand)) { |
| 467 operand = '($operand)'; | 434 operand = '($operand)'; |
| 468 } | 435 } |
| 469 return '!$operand'; | 436 return '!$operand'; |
| 470 } | 437 } |
| 471 | 438 |
| 472 String visitFunctionExpression(FunctionExpression node) { | 439 String visitFunctionExpression(FunctionExpression node) { |
| 473 return "function ${node.definition.element.name}"; | 440 return "function ${node.definition.element.name}"; |
| 474 } | 441 } |
| 475 | 442 |
| 476 String visitFieldInitializer(FieldInitializer node) { | |
| 477 throw "$node should not be visited by $this"; | |
| 478 } | |
| 479 | |
| 480 String visitSuperInitializer(SuperInitializer node) { | |
| 481 throw "$node should not be visited by $this"; | |
| 482 } | |
| 483 | |
| 484 String visitGetField(GetField node) { | 443 String visitGetField(GetField node) { |
| 485 String object = visitExpression(node.object); | 444 String object = visitExpression(node.object); |
| 486 String field = node.field.name; | 445 String field = node.field.name; |
| 487 if (usesInfixNotation(node.object)) { | 446 if (usesInfixNotation(node.object)) { |
| 488 object = '($object)'; | 447 object = '($object)'; |
| 489 } | 448 } |
| 490 return '$object.$field'; | 449 return '$object.$field'; |
| 491 } | 450 } |
| 492 | 451 |
| 493 String visitSetField(SetField node) { | 452 String visitSetField(SetField node) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 String prefix = v.element == null ? 'v' : '${v.element.name}_'; | 521 String prefix = v.element == null ? 'v' : '${v.element.name}_'; |
| 563 while (name == null || _usedNames.contains(name)) { | 522 while (name == null || _usedNames.contains(name)) { |
| 564 name = "$prefix${_counter++}"; | 523 name = "$prefix${_counter++}"; |
| 565 } | 524 } |
| 566 _names[v] = name; | 525 _names[v] = name; |
| 567 _usedNames.add(name); | 526 _usedNames.add(name); |
| 568 } | 527 } |
| 569 return name; | 528 return name; |
| 570 } | 529 } |
| 571 } | 530 } |
| OLD | NEW |