OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 | 878 |
879 void close() { | 879 void close() { |
880 // The mapping from TargetElement to JumpHandler is no longer needed. | 880 // The mapping from TargetElement to JumpHandler is no longer needed. |
881 for (TargetElement target in targetIndexMap.keys) { | 881 for (TargetElement target in targetIndexMap.keys) { |
882 builder.jumpTargets.remove(target); | 882 builder.jumpTargets.remove(target); |
883 } | 883 } |
884 super.close(); | 884 super.close(); |
885 } | 885 } |
886 } | 886 } |
887 | 887 |
888 class SsaBuilder extends ResolvedVisitor implements Visitor { | 888 class SsaGraphBuilderMixin { |
889 final SsaBuilderTask builder; | 889 final HGraph graph = new HGraph(); |
890 final JavaScriptBackend backend; | |
891 final CodegenWorkItem work; | |
892 final ConstantSystem constantSystem; | |
893 HGraph graph; | |
894 LocalsHandler localsHandler; | |
895 HInstruction rethrowableException; | |
896 Map<Element, HInstruction> parameters; | |
897 final RuntimeTypes rti; | |
898 HParameterValue lastAddedParameter; | |
899 | |
900 Map<TargetElement, JumpHandler> jumpTargets; | |
901 | |
902 /** | |
903 * Variables stored in the current activation. These variables are | |
904 * being updated in try/catch blocks, and should be | |
905 * accessed indirectly through [HLocalGet] and [HLocalSet]. | |
906 */ | |
907 Map<Element, HLocalValue> activationVariables; | |
908 | |
909 // We build the Ssa graph by simulating a stack machine. | |
910 List<HInstruction> stack; | |
911 | 890 |
912 /** | 891 /** |
913 * The current block to add instructions to. Might be null, if we are | 892 * The current block to add instructions to. Might be null, if we are |
914 * visiting dead code, but see [isReachable]. | 893 * visiting dead code, but see [isReachable]. |
915 */ | 894 */ |
916 HBasicBlock _current; | 895 HBasicBlock _current; |
917 | 896 |
918 /** | 897 /** |
919 * The most recently opened block. Has the same value as [_current] while | 898 * The most recently opened block. Has the same value as [_current] while |
920 * the block is open, but unlike [_current], it isn't cleared when the | 899 * the block is open, but unlike [_current], it isn't cleared when the |
921 * current block is closed. | 900 * current block is closed. |
922 */ | 901 */ |
923 HBasicBlock lastOpenedBlock; | 902 HBasicBlock lastOpenedBlock; |
924 | 903 |
925 /** | 904 /** |
926 * Indicates whether the current block is dead (because it has a throw or a | 905 * Indicates whether the current block is dead (because it has a throw or a |
927 * return further up). If this is false, then [_current] may be null. If the | 906 * return further up). If this is false, then [_current] may be null. If the |
928 * block is dead then it may also be aborted, but for simplicity we only | 907 * block is dead then it may also be aborted, but for simplicity we only |
929 * abort on statement boundaries, not in the middle of expressions. See | 908 * abort on statement boundaries, not in the middle of expressions. See |
930 * isAborted. | 909 * isAborted. |
931 */ | 910 */ |
932 bool isReachable = true; | 911 bool isReachable = true; |
933 | 912 |
913 HBasicBlock get current => _current; | |
914 void set current(c) { | |
915 isReachable = c != null; | |
916 _current = c; | |
917 } | |
918 | |
919 HBasicBlock addNewBlock() { | |
920 HBasicBlock block = graph.addNewBlock(); | |
921 // If adding a new block during building of an expression, it is due to | |
922 // conditional expressions or short-circuit logical operators. | |
923 return block; | |
924 } | |
925 | |
926 void open(HBasicBlock block) { | |
927 block.open(); | |
928 current = block; | |
929 lastOpenedBlock = block; | |
930 } | |
931 | |
932 HBasicBlock close(HControlFlow end) { | |
933 HBasicBlock result = current; | |
934 current.close(end); | |
935 current = null; | |
936 return result; | |
937 } | |
938 | |
939 HBasicBlock closeAndGotoExit(HControlFlow end) { | |
940 HBasicBlock result = current; | |
941 current.close(end); | |
942 current = null; | |
943 result.addSuccessor(graph.exit); | |
944 return result; | |
945 } | |
946 | |
947 void goto(HBasicBlock from, HBasicBlock to) { | |
948 from.close(new HGoto()); | |
949 from.addSuccessor(to); | |
950 } | |
951 | |
952 bool isAborted() { | |
953 return _current == null; | |
954 } | |
955 | |
956 /** | |
957 * Creates a new block, transitions to it from any current block, and | |
958 * opens the new block. | |
959 */ | |
960 HBasicBlock openNewBlock() { | |
961 HBasicBlock newBlock = addNewBlock(); | |
962 if (!isAborted()) goto(current, newBlock); | |
963 open(newBlock); | |
964 return newBlock; | |
965 } | |
966 | |
967 void add(HInstruction instruction) { | |
968 current.add(instruction); | |
969 } | |
970 } | |
971 | |
972 class SsaBuilder extends ResolvedVisitor with SsaGraphBuilderMixin { | |
973 final SsaBuilderTask builder; | |
974 final JavaScriptBackend backend; | |
975 final CodegenWorkItem work; | |
976 final ConstantSystem constantSystem; | |
977 LocalsHandler localsHandler; | |
978 HInstruction rethrowableException; | |
979 Map<Element, HInstruction> parameters; | |
980 final RuntimeTypes rti; | |
981 HParameterValue lastAddedParameter; | |
982 | |
983 Map<TargetElement, JumpHandler> jumpTargets; | |
984 | |
985 /** | |
986 * Variables stored in the current activation. These variables are | |
987 * being updated in try/catch blocks, and should be | |
988 * accessed indirectly through [HLocalGet] and [HLocalSet]. | |
989 */ | |
990 Map<Element, HLocalValue> activationVariables; | |
991 | |
992 // We build the Ssa graph by simulating a stack machine. | |
993 List<HInstruction> stack; | |
994 | |
934 /** | 995 /** |
935 * True if we are visiting the expression of a throw expression. | 996 * True if we are visiting the expression of a throw expression. |
936 */ | 997 */ |
937 bool inThrowExpression = false; | 998 bool inThrowExpression = false; |
938 | 999 |
939 final List<Element> sourceElementStack; | 1000 final List<Element> sourceElementStack; |
940 | 1001 |
941 Element get currentElement => sourceElementStack.last.declaration; | 1002 Element get currentElement => sourceElementStack.last.declaration; |
942 Element get currentNonClosureClass { | 1003 Element get currentNonClosureClass { |
943 ClassElement cls = currentElement.getEnclosingClass(); | 1004 ClassElement cls = currentElement.getEnclosingClass(); |
(...skipping 20 matching lines...) Expand all Loading... | |
964 // types of the type variables in an environment (like the [LocalsHandler]). | 1025 // types of the type variables in an environment (like the [LocalsHandler]). |
965 final List<DartType> currentInlinedInstantiations = <DartType>[]; | 1026 final List<DartType> currentInlinedInstantiations = <DartType>[]; |
966 | 1027 |
967 Compiler get compiler => builder.compiler; | 1028 Compiler get compiler => builder.compiler; |
968 CodeEmitterTask get emitter => builder.emitter; | 1029 CodeEmitterTask get emitter => builder.emitter; |
969 | 1030 |
970 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work) | 1031 SsaBuilder(this.constantSystem, SsaBuilderTask builder, CodegenWorkItem work) |
971 : this.builder = builder, | 1032 : this.builder = builder, |
972 this.backend = builder.backend, | 1033 this.backend = builder.backend, |
973 this.work = work, | 1034 this.work = work, |
974 graph = new HGraph(), | |
975 stack = new List<HInstruction>(), | 1035 stack = new List<HInstruction>(), |
976 activationVariables = new Map<Element, HLocalValue>(), | 1036 activationVariables = new Map<Element, HLocalValue>(), |
977 jumpTargets = new Map<TargetElement, JumpHandler>(), | 1037 jumpTargets = new Map<TargetElement, JumpHandler>(), |
978 parameters = new Map<Element, HInstruction>(), | 1038 parameters = new Map<Element, HInstruction>(), |
979 sourceElementStack = <Element>[work.element], | 1039 sourceElementStack = <Element>[work.element], |
980 inliningStack = <InliningState>[], | 1040 inliningStack = <InliningState>[], |
981 rti = builder.backend.rti, | 1041 rti = builder.backend.rti, |
982 super(work.resolutionTree, builder.compiler) { | 1042 super(work.resolutionTree, builder.compiler) { |
983 localsHandler = new LocalsHandler(this); | 1043 localsHandler = new LocalsHandler(this); |
984 } | 1044 } |
985 | 1045 |
986 List<InliningState> inliningStack; | 1046 List<InliningState> inliningStack; |
987 | 1047 |
988 Element returnElement; | 1048 Element returnElement; |
989 DartType returnType; | 1049 DartType returnType; |
990 | 1050 |
991 bool inTryStatement = false; | 1051 bool inTryStatement = false; |
992 int loopNesting = 0; | 1052 int loopNesting = 0; |
993 | 1053 |
994 HBasicBlock get current => _current; | |
995 void set current(c) { | |
996 isReachable = c != null; | |
997 _current = c; | |
998 } | |
999 | |
1000 Constant getConstantForNode(Node node) { | 1054 Constant getConstantForNode(Node node) { |
1001 ConstantHandler handler = compiler.constantHandler; | 1055 ConstantHandler handler = compiler.constantHandler; |
1002 Constant constant = elements.getConstant(node); | 1056 Constant constant = elements.getConstant(node); |
1003 assert(invariant(node, constant != null, | 1057 assert(invariant(node, constant != null, |
1004 message: 'No constant computed for $node')); | 1058 message: 'No constant computed for $node')); |
1005 return constant; | 1059 return constant; |
1006 } | 1060 } |
1007 | 1061 |
1008 HInstruction addConstant(Node node) { | 1062 HInstruction addConstant(Node node) { |
1009 return graph.addConstant(getConstantForNode(node), compiler); | 1063 return graph.addConstant(getConstantForNode(node), compiler); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 assert(succeeded); | 1272 assert(succeeded); |
1219 } | 1273 } |
1220 | 1274 |
1221 // Create the inlining state after evaluating the arguments, that | 1275 // Create the inlining state after evaluating the arguments, that |
1222 // may have an impact on the state of the current method. | 1276 // may have an impact on the state of the current method. |
1223 InliningState state = new InliningState( | 1277 InliningState state = new InliningState( |
1224 function, returnElement, returnType, elements, stack, | 1278 function, returnElement, returnType, elements, stack, |
1225 localsHandler, inTryStatement); | 1279 localsHandler, inTryStatement); |
1226 inTryStatement = false; | 1280 inTryStatement = false; |
1227 LocalsHandler newLocalsHandler = new LocalsHandler(this); | 1281 LocalsHandler newLocalsHandler = new LocalsHandler(this); |
1228 newLocalsHandler.closureData = | 1282 if (function.hasIrNode(compiler)) { |
1229 compiler.closureToClassMapper.computeClosureToClassMapping( | 1283 // TODO(lry): handle ir functions with nested closure definitions. |
ngeoffray
2013/11/20 14:55:27
Why can't you call computeClosureToClassMapping?
lukas
2013/11/20 15:13:26
It is an AST visitor, but we don't have a tree ava
| |
1230 function, function.parseNode(compiler), elements); | 1284 newLocalsHandler.closureData = |
1285 new ClosureClassMap(null, null, null, new ThisElement(function)); | |
1286 } else { | |
1287 newLocalsHandler.closureData = | |
1288 compiler.closureToClassMapper.computeClosureToClassMapping( | |
1289 function, function.parseNode(compiler), elements); | |
1290 } | |
1231 int argumentIndex = 0; | 1291 int argumentIndex = 0; |
1232 if (isInstanceMember) { | 1292 if (isInstanceMember) { |
1233 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, | 1293 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, |
1234 compiledArguments[argumentIndex++]); | 1294 compiledArguments[argumentIndex++]); |
1235 } | 1295 } |
1236 | 1296 |
1237 FunctionSignature signature = function.computeSignature(compiler); | 1297 FunctionSignature signature = function.computeSignature(compiler); |
1238 signature.orderedForEachParameter((Element parameter) { | 1298 signature.orderedForEachParameter((Element parameter) { |
1239 HInstruction argument = compiledArguments[argumentIndex++]; | 1299 HInstruction argument = compiledArguments[argumentIndex++]; |
1240 newLocalsHandler.updateLocal(parameter, argument); | 1300 newLocalsHandler.updateLocal(parameter, argument); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1343 && returnType.isEmpty | 1403 && returnType.isEmpty |
1344 && !returnType.isNullable) { | 1404 && !returnType.isNullable) { |
1345 isReachable = false; | 1405 isReachable = false; |
1346 return false; | 1406 return false; |
1347 } | 1407 } |
1348 } | 1408 } |
1349 | 1409 |
1350 return true; | 1410 return true; |
1351 } | 1411 } |
1352 | 1412 |
1353 bool heuristicSayGoodToGo(FunctionExpression functionExpression) { | 1413 bool heuristicSayGoodToGo(bool canBeInlined(int maxNodes)) { |
1354 // Don't inline recursivly | 1414 // Don't inline recursivly |
1355 if (inliningStack.any((entry) => entry.function == function)) { | 1415 if (inliningStack.any((entry) => entry.function == function)) { |
1356 return false; | 1416 return false; |
1357 } | 1417 } |
1358 | 1418 |
1359 if (element.isSynthesized) return true; | 1419 if (element.isSynthesized) return true; |
1360 | 1420 |
1361 if (cachedCanBeInlined == true) return cachedCanBeInlined; | 1421 if (cachedCanBeInlined == true) return cachedCanBeInlined; |
1362 | 1422 |
1363 if (inThrowExpression) return false; | 1423 if (inThrowExpression) return false; |
1364 | 1424 |
1365 int numParameters = function.functionSignature.parameterCount; | 1425 int numParameters = function.functionSignature.parameterCount; |
1366 int maxInliningNodes; | 1426 int maxInliningNodes; |
1367 if (insideLoop) { | 1427 if (insideLoop) { |
1368 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + | 1428 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + |
1369 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; | 1429 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; |
1370 } else { | 1430 } else { |
1371 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + | 1431 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + |
1372 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; | 1432 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; |
1373 } | 1433 } |
1374 bool canBeInlined = InlineWeeder.canBeInlined( | 1434 bool canInline = canBeInlined(maxInliningNodes); |
1375 functionExpression, maxInliningNodes); | 1435 if (canInline) { |
1376 if (canBeInlined) { | |
1377 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); | 1436 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); |
1378 } else { | 1437 } else { |
1379 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); | 1438 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); |
1380 } | 1439 } |
1381 return canBeInlined; | 1440 return canInline; |
1382 } | 1441 } |
1383 | 1442 |
1384 void doInlining(FunctionExpression functionExpression) { | 1443 void doInlining(void visitBody()) { |
1385 // Add an explicit null check on the receiver before doing the | 1444 // Add an explicit null check on the receiver before doing the |
1386 // inlining. We use [element] to get the same name in the | 1445 // inlining. We use [element] to get the same name in the |
1387 // NoSuchMethodError message as if we had called it. | 1446 // NoSuchMethodError message as if we had called it. |
1388 if (element.isInstanceMember() | 1447 if (element.isInstanceMember() |
1389 && !element.isGenerativeConstructorBody() | 1448 && !element.isGenerativeConstructorBody() |
1390 && (selector.mask == null || selector.mask.isNullable)) { | 1449 && (selector.mask == null || selector.mask.isNullable)) { |
1391 addWithPosition( | 1450 addWithPosition( |
1392 new HFieldGet(null, providedArguments[0], backend.dynamicType, | 1451 new HFieldGet(null, providedArguments[0], backend.dynamicType, |
1393 isAssignable: false), | 1452 isAssignable: false), |
1394 currentNode); | 1453 currentNode); |
1395 } | 1454 } |
1396 InliningState state = enterInlinedMethod( | 1455 InliningState state = enterInlinedMethod( |
1397 function, selector, providedArguments, currentNode); | 1456 function, selector, providedArguments, currentNode); |
1398 | 1457 |
1399 inlinedFrom(element, () { | 1458 inlinedFrom(element, () { |
1400 FunctionElement function = element; | 1459 FunctionElement function = element; |
1401 FunctionSignature signature = function.computeSignature(compiler); | 1460 FunctionSignature signature = function.computeSignature(compiler); |
1402 signature.orderedForEachParameter((Element parameter) { | 1461 signature.orderedForEachParameter((Element parameter) { |
1403 HInstruction argument = localsHandler.readLocal(parameter); | 1462 HInstruction argument = localsHandler.readLocal(parameter); |
1404 potentiallyCheckType(argument, parameter.computeType(compiler)); | 1463 potentiallyCheckType(argument, parameter.computeType(compiler)); |
1405 }); | 1464 }); |
1406 addInlinedInstantiation(instantiatedType); | 1465 addInlinedInstantiation(instantiatedType); |
1407 if (element.isGenerativeConstructor()) { | 1466 if (element.isGenerativeConstructor()) { |
1408 buildFactory(element); | 1467 buildFactory(element); |
1409 } else { | 1468 } else { |
1410 functionExpression.body.accept(this); | 1469 visitBody(); |
1411 } | 1470 } |
1412 removeInlinedInstantiation(instantiatedType); | 1471 removeInlinedInstantiation(instantiatedType); |
1413 }); | 1472 }); |
1414 leaveInlinedMethod(state); | 1473 leaveInlinedMethod(state); |
1415 } | 1474 } |
1416 | 1475 |
1417 if (meetsHardConstraints()) { | 1476 if (meetsHardConstraints()) { |
1418 FunctionExpression functionExpression = function.parseNode(compiler); | 1477 if (function.hasIrNode(compiler)) { |
1419 | 1478 IrFunction irFunction = function.irNode(compiler); |
1420 if (heuristicSayGoodToGo(functionExpression)) { | 1479 bool canInline(int n) => IrInlineWeeder.canBeInlined(irFunction, n); |
1421 doInlining(functionExpression); | 1480 if (heuristicSayGoodToGo(canInline)) { |
1422 return true; | 1481 SsaFromIrInliner irInliner = new SsaFromIrInliner(this); |
1482 doInlining(() => irInliner.visitAll(irFunction.statements)); | |
1483 return true; | |
1484 } | |
1485 } else { | |
1486 FunctionExpression functionNode = function.parseNode(compiler); | |
1487 bool canInline(int n) => InlineWeeder.canBeInlined(functionNode, n); | |
1488 if (heuristicSayGoodToGo(canInline)) { | |
1489 doInlining(() => functionNode.body.accept(this)); | |
1490 return true; | |
1491 } | |
1423 } | 1492 } |
1424 } | 1493 } |
1425 | 1494 |
1426 return false; | 1495 return false; |
1427 } | 1496 } |
1428 | 1497 |
1429 addInlinedInstantiation(DartType type) { | 1498 addInlinedInstantiation(DartType type) { |
1430 if (type != null) { | 1499 if (type != null) { |
1431 currentInlinedInstantiations.add(type); | 1500 currentInlinedInstantiations.add(type); |
1432 } | 1501 } |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2040 add(assertIsSubtype); | 2109 add(assertIsSubtype); |
2041 } | 2110 } |
2042 | 2111 |
2043 HGraph closeFunction() { | 2112 HGraph closeFunction() { |
2044 // TODO(kasperl): Make this goto an implicit return. | 2113 // TODO(kasperl): Make this goto an implicit return. |
2045 if (!isAborted()) closeAndGotoExit(new HGoto()); | 2114 if (!isAborted()) closeAndGotoExit(new HGoto()); |
2046 graph.finalize(); | 2115 graph.finalize(); |
2047 return graph; | 2116 return graph; |
2048 } | 2117 } |
2049 | 2118 |
2050 HBasicBlock addNewBlock() { | |
2051 HBasicBlock block = graph.addNewBlock(); | |
2052 // If adding a new block during building of an expression, it is due to | |
2053 // conditional expressions or short-circuit logical operators. | |
2054 return block; | |
2055 } | |
2056 | |
2057 void open(HBasicBlock block) { | |
2058 block.open(); | |
2059 current = block; | |
2060 lastOpenedBlock = block; | |
2061 } | |
2062 | |
2063 HBasicBlock close(HControlFlow end) { | |
2064 HBasicBlock result = current; | |
2065 current.close(end); | |
2066 current = null; | |
2067 return result; | |
2068 } | |
2069 | |
2070 HBasicBlock closeAndGotoExit(HControlFlow end) { | |
2071 HBasicBlock result = current; | |
2072 current.close(end); | |
2073 current = null; | |
2074 result.addSuccessor(graph.exit); | |
2075 return result; | |
2076 } | |
2077 | |
2078 void goto(HBasicBlock from, HBasicBlock to) { | |
2079 from.close(new HGoto()); | |
2080 from.addSuccessor(to); | |
2081 } | |
2082 | |
2083 bool isAborted() { | |
2084 return _current == null; | |
2085 } | |
2086 | |
2087 /** | |
2088 * Creates a new block, transitions to it from any current block, and | |
2089 * opens the new block. | |
2090 */ | |
2091 HBasicBlock openNewBlock() { | |
2092 HBasicBlock newBlock = addNewBlock(); | |
2093 if (!isAborted()) goto(current, newBlock); | |
2094 open(newBlock); | |
2095 return newBlock; | |
2096 } | |
2097 | |
2098 void add(HInstruction instruction) { | |
2099 current.add(instruction); | |
2100 } | |
2101 | |
2102 void addWithPosition(HInstruction instruction, Node node) { | 2119 void addWithPosition(HInstruction instruction, Node node) { |
2103 add(attachPosition(instruction, node)); | 2120 add(attachPosition(instruction, node)); |
2104 } | 2121 } |
2105 | 2122 |
2106 void push(HInstruction instruction) { | 2123 void push(HInstruction instruction) { |
2107 add(instruction); | 2124 add(instruction); |
2108 stack.add(instruction); | 2125 stack.add(instruction); |
2109 } | 2126 } |
2110 | 2127 |
2111 void pushWithPosition(HInstruction instruction, Node node) { | 2128 void pushWithPosition(HInstruction instruction, Node node) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2148 | 2165 |
2149 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { | 2166 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { |
2150 Element element = sourceElementStack.last; | 2167 Element element = sourceElementStack.last; |
2151 // TODO(johnniwinther): remove the 'element.patch' hack. | 2168 // TODO(johnniwinther): remove the 'element.patch' hack. |
2152 if (element is FunctionElement) { | 2169 if (element is FunctionElement) { |
2153 FunctionElement functionElement = element; | 2170 FunctionElement functionElement = element; |
2154 if (functionElement.patch != null) element = functionElement.patch; | 2171 if (functionElement.patch != null) element = functionElement.patch; |
2155 } | 2172 } |
2156 Script script = element.getCompilationUnit().script; | 2173 Script script = element.getCompilationUnit().script; |
2157 SourceFile sourceFile = script.file; | 2174 SourceFile sourceFile = script.file; |
2158 SourceFileLocation location = new SourceFileLocation(sourceFile, token); | 2175 SourceFileLocation location = |
2176 new TokenSourceFileLocation(sourceFile, token); | |
2159 if (!location.isValid()) { | 2177 if (!location.isValid()) { |
2160 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( | 2178 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( |
2161 {'offset': token.charOffset, | 2179 {'offset': token.charOffset, |
2162 'fileName': sourceFile.filename, | 2180 'fileName': sourceFile.filename, |
2163 'length': sourceFile.length}); | 2181 'length': sourceFile.length}); |
2164 } | 2182 } |
2165 return location; | 2183 return location; |
2166 } | 2184 } |
2167 | 2185 |
2168 void visit(Node node) { | 2186 void visit(Node node) { |
(...skipping 3720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5889 new HSubGraphBlockInformation(elseBranch.graph)); | 5907 new HSubGraphBlockInformation(elseBranch.graph)); |
5890 | 5908 |
5891 HBasicBlock conditionStartBlock = conditionBranch.block; | 5909 HBasicBlock conditionStartBlock = conditionBranch.block; |
5892 conditionStartBlock.setBlockFlow(info, joinBlock); | 5910 conditionStartBlock.setBlockFlow(info, joinBlock); |
5893 SubGraph conditionGraph = conditionBranch.graph; | 5911 SubGraph conditionGraph = conditionBranch.graph; |
5894 HIf branch = conditionGraph.end.last; | 5912 HIf branch = conditionGraph.end.last; |
5895 assert(branch is HIf); | 5913 assert(branch is HIf); |
5896 branch.blockInformation = conditionStartBlock.blockFlow; | 5914 branch.blockInformation = conditionStartBlock.blockFlow; |
5897 } | 5915 } |
5898 } | 5916 } |
OLD | NEW |