| 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 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 // the emitter. | 851 // the emitter. |
| 852 List<HInstruction> constructorArguments = <HInstruction>[]; | 852 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 853 ClassElement element = classElement; | 853 ClassElement element = classElement; |
| 854 while (element != null) { | 854 while (element != null) { |
| 855 for (Element member in element.members) { | 855 for (Element member in element.members) { |
| 856 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { | 856 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { |
| 857 HInstruction value; | 857 HInstruction value; |
| 858 if (localsHandler.hasValueForDirectLocal(member)) { | 858 if (localsHandler.hasValueForDirectLocal(member)) { |
| 859 value = localsHandler.readLocal(member); | 859 value = localsHandler.readLocal(member); |
| 860 } else { | 860 } else { |
| 861 var fieldValue = | 861 Constant fieldValue = |
| 862 compiler.compileTimeConstantHandler.compileVariable(member); | 862 compiler.constantHandler.compileVariable(member); |
| 863 // TODO(floitsch): this constant should be treated like all | 863 value = graph.addConstant(fieldValue); |
| 864 // other constants and should be at the top of the graph. | |
| 865 value = new HLiteral.internal(fieldValue, HType.UNKNOWN); | |
| 866 add(value); | |
| 867 } | 864 } |
| 868 constructorArguments.add(value); | 865 constructorArguments.add(value); |
| 869 } | 866 } |
| 870 } | 867 } |
| 871 element = element.superclass; | 868 element = element.superclass; |
| 872 } | 869 } |
| 873 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 870 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| 874 add(newObject); | 871 add(newObject); |
| 875 // Generate calls to the constructor bodies. | 872 // Generate calls to the constructor bodies. |
| 876 for (int index = constructors.length - 1; index >= 0; index--) { | 873 for (int index = constructors.length - 1; index >= 0; index--) { |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 visit(node.receiver); | 1306 visit(node.receiver); |
| 1310 HNot not = new HNot(popBoolified()); | 1307 HNot not = new HNot(popBoolified()); |
| 1311 push(not); | 1308 push(not); |
| 1312 } | 1309 } |
| 1313 | 1310 |
| 1314 void visitUnary(Send node, Operator op) { | 1311 void visitUnary(Send node, Operator op) { |
| 1315 assert(node.argumentsNode is Prefix); | 1312 assert(node.argumentsNode is Prefix); |
| 1316 visit(node.receiver); | 1313 visit(node.receiver); |
| 1317 assert(op.token.kind !== PLUS_TOKEN); | 1314 assert(op.token.kind !== PLUS_TOKEN); |
| 1318 HInstruction operand = pop(); | 1315 HInstruction operand = pop(); |
| 1316 // See if we can constant-fold right away. This avoids rewrites later on. |
| 1317 if (operand is HConstant) { |
| 1318 HConstant typedOperand = operand; |
| 1319 Constant constant = typedOperand.constant; |
| 1320 Constant folded = constant.unaryFold(op.source.stringValue); |
| 1321 if (folded !== null) { |
| 1322 stack.add(graph.addConstant(folded)); |
| 1323 return; |
| 1324 } |
| 1325 } |
| 1319 HInstruction target = | 1326 HInstruction target = |
| 1320 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); | 1327 new HStatic(interceptors.getPrefixOperatorInterceptor(op)); |
| 1321 add(target); | 1328 add(target); |
| 1322 switch (op.source.stringValue) { | 1329 switch (op.source.stringValue) { |
| 1323 case "-": | 1330 case "-": push(new HNegate(target, operand)); break; |
| 1324 // TODO(kasperl): Avoid calling visit(node.receiver) above. | |
| 1325 if ((operand is HLiteral) && (operand.value is double)) { | |
| 1326 stack.add(graph.addNewLiteralDouble(-operand.value)); | |
| 1327 } else if ((operand is HLiteral) && (operand.value is int)) { | |
| 1328 stack.add(graph.addNewLiteralInt(-operand.value)); | |
| 1329 } else { | |
| 1330 push(new HNegate(target, operand)); | |
| 1331 } | |
| 1332 break; | |
| 1333 case "~": push(new HBitNot(target, operand)); break; | 1331 case "~": push(new HBitNot(target, operand)); break; |
| 1334 default: unreachable(); | 1332 default: unreachable(); |
| 1335 } | 1333 } |
| 1336 } | 1334 } |
| 1337 | 1335 |
| 1338 void visitBinary(HInstruction left, Operator op, HInstruction right) { | 1336 void visitBinary(HInstruction left, Operator op, HInstruction right) { |
| 1339 Element element = interceptors.getOperatorInterceptor(op); | 1337 Element element = interceptors.getOperatorInterceptor(op); |
| 1340 assert(element != null); | 1338 assert(element != null); |
| 1341 HInstruction target = new HStatic(element); | 1339 HInstruction target = new HStatic(element); |
| 1342 add(target); | 1340 add(target); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 for (int i = 0; i < selector.namedArguments.length; i++) { | 1628 for (int i = 0; i < selector.namedArguments.length; i++) { |
| 1631 SourceString name = selector.namedArguments[i]; | 1629 SourceString name = selector.namedArguments[i]; |
| 1632 if (name == parameter.name) { | 1630 if (name == parameter.name) { |
| 1633 foundIndex = i; | 1631 foundIndex = i; |
| 1634 break; | 1632 break; |
| 1635 } | 1633 } |
| 1636 } | 1634 } |
| 1637 if (foundIndex != -1) { | 1635 if (foundIndex != -1) { |
| 1638 list.add(namedArguments[foundIndex]); | 1636 list.add(namedArguments[foundIndex]); |
| 1639 } else { | 1637 } else { |
| 1640 // TODO(kasperl): This needs more work. Ideally these | 1638 Constant constant = compiler.compileVariable(parameter); |
| 1641 // constants should be treated like any other constant and | 1639 list.add(graph.addConstant(constant)); |
| 1642 // canonicalized by the graph methods. | |
| 1643 var constant = compiler.compileVariable(parameter); | |
| 1644 push(new HLiteral.internal(constant, HType.UNKNOWN)); | |
| 1645 list.add(pop()); | |
| 1646 } | 1640 } |
| 1647 } | 1641 } |
| 1648 } | 1642 } |
| 1649 } | 1643 } |
| 1650 | 1644 |
| 1651 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { | 1645 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { |
| 1652 for (; !link.isEmpty(); link = link.tail) { | 1646 for (; !link.isEmpty(); link = link.tail) { |
| 1653 visit(link.head); | 1647 visit(link.head); |
| 1654 list.add(pop()); | 1648 list.add(pop()); |
| 1655 } | 1649 } |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 HInstruction index; | 1864 HInstruction index; |
| 1871 bool isCompoundAssignment = op.source.stringValue.endsWith('='); | 1865 bool isCompoundAssignment = op.source.stringValue.endsWith('='); |
| 1872 // Compound assignments are considered as being prefix. | 1866 // Compound assignments are considered as being prefix. |
| 1873 bool isPrefix = !node.isPostfix; | 1867 bool isPrefix = !node.isPostfix; |
| 1874 Element getter = elements[node.selector]; | 1868 Element getter = elements[node.selector]; |
| 1875 if (isCompoundAssignment) { | 1869 if (isCompoundAssignment) { |
| 1876 value = pop(); | 1870 value = pop(); |
| 1877 index = pop(); | 1871 index = pop(); |
| 1878 } else { | 1872 } else { |
| 1879 index = pop(); | 1873 index = pop(); |
| 1880 value = graph.addNewLiteralInt(1); | 1874 value = graph.addConstantInt(1); |
| 1881 } | 1875 } |
| 1882 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); | 1876 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); |
| 1883 add(indexMethod); | 1877 add(indexMethod); |
| 1884 HInstruction left = new HIndex(indexMethod, receiver, index); | 1878 HInstruction left = new HIndex(indexMethod, receiver, index); |
| 1885 add(left); | 1879 add(left); |
| 1886 Element opElement = elements[op]; | 1880 Element opElement = elements[op]; |
| 1887 visitBinary(left, op, value); | 1881 visitBinary(left, op, value); |
| 1888 HInstruction assign = new HIndexAssign( | 1882 HInstruction assign = new HIndexAssign( |
| 1889 target, receiver, index, pop()); | 1883 target, receiver, index, pop()); |
| 1890 add(assign); | 1884 add(assign); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1911 Element element = elements[node]; | 1905 Element element = elements[node]; |
| 1912 bool isCompoundAssignment = !node.arguments.isEmpty(); | 1906 bool isCompoundAssignment = !node.arguments.isEmpty(); |
| 1913 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 1907 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
| 1914 generateGetter(node, elements[node.selector]); | 1908 generateGetter(node, elements[node.selector]); |
| 1915 HInstruction left = pop(); | 1909 HInstruction left = pop(); |
| 1916 HInstruction right; | 1910 HInstruction right; |
| 1917 if (isCompoundAssignment) { | 1911 if (isCompoundAssignment) { |
| 1918 visit(node.argumentsNode); | 1912 visit(node.argumentsNode); |
| 1919 right = pop(); | 1913 right = pop(); |
| 1920 } else { | 1914 } else { |
| 1921 right = graph.addNewLiteralInt(1); | 1915 right = graph.addConstantInt(1); |
| 1922 } | 1916 } |
| 1923 visitBinary(left, op, right); | 1917 visitBinary(left, op, right); |
| 1924 HInstruction operation = pop(); | 1918 HInstruction operation = pop(); |
| 1925 assert(operation !== null); | 1919 assert(operation !== null); |
| 1926 generateSetter(node, element, operation); | 1920 generateSetter(node, element, operation); |
| 1927 if (!isPrefix) { | 1921 if (!isPrefix) { |
| 1928 pop(); | 1922 pop(); |
| 1929 stack.add(left); | 1923 stack.add(left); |
| 1930 } | 1924 } |
| 1931 } | 1925 } |
| 1932 } | 1926 } |
| 1933 | 1927 |
| 1934 void visitLiteralInt(LiteralInt node) { | 1928 void visitLiteralInt(LiteralInt node) { |
| 1935 stack.add(graph.addNewLiteralInt(node.value)); | 1929 stack.add(graph.addConstantInt(node.value)); |
| 1936 } | 1930 } |
| 1937 | 1931 |
| 1938 void visitLiteralDouble(LiteralDouble node) { | 1932 void visitLiteralDouble(LiteralDouble node) { |
| 1939 stack.add(graph.addNewLiteralDouble(node.value)); | 1933 stack.add(graph.addConstantDouble(node.value)); |
| 1940 } | 1934 } |
| 1941 | 1935 |
| 1942 void visitLiteralBool(LiteralBool node) { | 1936 void visitLiteralBool(LiteralBool node) { |
| 1943 stack.add(graph.addNewLiteralBool(node.value)); | 1937 stack.add(graph.addConstantBool(node.value)); |
| 1944 } | 1938 } |
| 1945 | 1939 |
| 1946 void visitLiteralString(LiteralString node) { | 1940 void visitLiteralString(LiteralString node) { |
| 1947 stack.add(graph.addNewLiteralString(node.dartString)); | 1941 stack.add(graph.addConstantString(node.dartString)); |
| 1948 } | 1942 } |
| 1949 | 1943 |
| 1950 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { | 1944 void visitLiteralStringJuxtaposition(LiteralStringJuxtaposition node) { |
| 1951 visitLiteralString(node); | 1945 visitLiteralString(node); |
| 1952 } | 1946 } |
| 1953 | 1947 |
| 1954 void visitLiteralNull(LiteralNull node) { | 1948 void visitLiteralNull(LiteralNull node) { |
| 1955 stack.add(graph.addNewLiteralNull()); | 1949 stack.add(graph.addConstantNull()); |
| 1956 } | 1950 } |
| 1957 | 1951 |
| 1958 visitNodeList(NodeList node) { | 1952 visitNodeList(NodeList node) { |
| 1959 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 1953 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
| 1960 if (isAborted()) { | 1954 if (isAborted()) { |
| 1961 compiler.reportWarning(link.head, 'dead code'); | 1955 compiler.reportWarning(link.head, 'dead code'); |
| 1962 } else { | 1956 } else { |
| 1963 visit(link.head); | 1957 visit(link.head); |
| 1964 } | 1958 } |
| 1965 } | 1959 } |
| 1966 } | 1960 } |
| 1967 | 1961 |
| 1968 void visitParenthesizedExpression(ParenthesizedExpression node) { | 1962 void visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1969 visit(node.expression); | 1963 visit(node.expression); |
| 1970 } | 1964 } |
| 1971 | 1965 |
| 1972 visitOperator(Operator node) { | 1966 visitOperator(Operator node) { |
| 1973 // Operators are intercepted in their surrounding Send nodes. | 1967 // Operators are intercepted in their surrounding Send nodes. |
| 1974 unreachable(); | 1968 unreachable(); |
| 1975 } | 1969 } |
| 1976 | 1970 |
| 1977 visitReturn(Return node) { | 1971 visitReturn(Return node) { |
| 1978 HInstruction value; | 1972 HInstruction value; |
| 1979 if (node.expression === null) { | 1973 if (node.expression === null) { |
| 1980 value = graph.addNewLiteralNull(); | 1974 value = graph.addConstantNull(); |
| 1981 } else { | 1975 } else { |
| 1982 visit(node.expression); | 1976 visit(node.expression); |
| 1983 value = pop(); | 1977 value = pop(); |
| 1984 } | 1978 } |
| 1985 close(new HReturn(value)).addSuccessor(graph.exit); | 1979 close(new HReturn(value)).addSuccessor(graph.exit); |
| 1986 } | 1980 } |
| 1987 | 1981 |
| 1988 visitThrow(Throw node) { | 1982 visitThrow(Throw node) { |
| 1989 if (node.expression === null) { | 1983 if (node.expression === null) { |
| 1990 HInstruction exception = rethrowableException; | 1984 HInstruction exception = rethrowableException; |
| 1991 if (exception === null) { | 1985 if (exception === null) { |
| 1992 exception = graph.addNewLiteralNull(); | 1986 exception = graph.addConstantNull(); |
| 1993 compiler.reportError(node, | 1987 compiler.reportError(node, |
| 1994 'throw without expression outside catch block'); | 1988 'throw without expression outside catch block'); |
| 1995 } | 1989 } |
| 1996 close(new HThrow(exception, isRethrow: true)); | 1990 close(new HThrow(exception, isRethrow: true)); |
| 1997 } else { | 1991 } else { |
| 1998 visit(node.expression); | 1992 visit(node.expression); |
| 1999 close(new HThrow(pop())); | 1993 close(new HThrow(pop())); |
| 2000 } | 1994 } |
| 2001 } | 1995 } |
| 2002 | 1996 |
| 2003 visitTypeAnnotation(TypeAnnotation node) { | 1997 visitTypeAnnotation(TypeAnnotation node) { |
| 2004 compiler.internalError('visiting type annotation in SSA builder', | 1998 compiler.internalError('visiting type annotation in SSA builder', |
| 2005 node: node); | 1999 node: node); |
| 2006 } | 2000 } |
| 2007 | 2001 |
| 2008 visitVariableDefinitions(VariableDefinitions node) { | 2002 visitVariableDefinitions(VariableDefinitions node) { |
| 2009 for (Link<Node> link = node.definitions.nodes; | 2003 for (Link<Node> link = node.definitions.nodes; |
| 2010 !link.isEmpty(); | 2004 !link.isEmpty(); |
| 2011 link = link.tail) { | 2005 link = link.tail) { |
| 2012 Node definition = link.head; | 2006 Node definition = link.head; |
| 2013 if (definition is Identifier) { | 2007 if (definition is Identifier) { |
| 2014 HInstruction initialValue = graph.addNewLiteralNull(); | 2008 HInstruction initialValue = graph.addConstantNull(); |
| 2015 localsHandler.updateLocal(elements[definition], initialValue); | 2009 localsHandler.updateLocal(elements[definition], initialValue); |
| 2016 } else { | 2010 } else { |
| 2017 assert(definition is SendSet); | 2011 assert(definition is SendSet); |
| 2018 visitSendSet(definition); | 2012 visitSendSet(definition); |
| 2019 pop(); // Discard value. | 2013 pop(); // Discard value. |
| 2020 } | 2014 } |
| 2021 } | 2015 } |
| 2022 } | 2016 } |
| 2023 | 2017 |
| 2024 visitLiteralList(LiteralList node) { | 2018 visitLiteralList(LiteralList node) { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2288 handleThen() { | 2282 handleThen() { |
| 2289 if (cases.head.statements.nodes.isEmpty()) { | 2283 if (cases.head.statements.nodes.isEmpty()) { |
| 2290 compiler.unimplemented('fall-through', node: cases.head); | 2284 compiler.unimplemented('fall-through', node: cases.head); |
| 2291 } | 2285 } |
| 2292 visit(cases.head.statements); | 2286 visit(cases.head.statements); |
| 2293 cases = cases.tail; | 2287 cases = cases.tail; |
| 2294 } | 2288 } |
| 2295 handleElse() { | 2289 handleElse() { |
| 2296 if (cases.isEmpty()) return; | 2290 if (cases.isEmpty()) return; |
| 2297 if (cases.head is DefaultCase) { | 2291 if (cases.head is DefaultCase) { |
| 2298 stack.add(graph.addNewLiteralBool(true)); | 2292 stack.add(graph.addConstantBool(true)); |
| 2299 if (!cases.tail.isEmpty()) { | 2293 if (!cases.tail.isEmpty()) { |
| 2300 compiler.unimplemented('default case not last', node: cases.head); | 2294 compiler.unimplemented('default case not last', node: cases.head); |
| 2301 } | 2295 } |
| 2302 } else { | 2296 } else { |
| 2303 SwitchCase switchCase = cases.head; | 2297 SwitchCase switchCase = cases.head; |
| 2304 visit(switchCase.expression); | 2298 visit(switchCase.expression); |
| 2305 HInstruction caseExpression = pop(); | 2299 HInstruction caseExpression = pop(); |
| 2306 Element equalsHelper = compiler.findHelper(const SourceString('eq')); | 2300 Element equalsHelper = compiler.findHelper(const SourceString('eq')); |
| 2307 HInstruction target = new HStatic(equalsHelper); | 2301 HInstruction target = new HStatic(equalsHelper); |
| 2308 add(target); | 2302 add(target); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2320 | 2314 |
| 2321 if (isAborted()) { | 2315 if (isAborted()) { |
| 2322 compiler.unimplemented("SsaBuilder for loop with aborting body", | 2316 compiler.unimplemented("SsaBuilder for loop with aborting body", |
| 2323 node: node); | 2317 node: node); |
| 2324 } | 2318 } |
| 2325 | 2319 |
| 2326 HBasicBlock bodyExitBlock = close(new HGoto()); | 2320 HBasicBlock bodyExitBlock = close(new HGoto()); |
| 2327 HBasicBlock conditionBlock = addNewBlock(); | 2321 HBasicBlock conditionBlock = addNewBlock(); |
| 2328 bodyExitBlock.addSuccessor(conditionBlock); | 2322 bodyExitBlock.addSuccessor(conditionBlock); |
| 2329 open(conditionBlock); | 2323 open(conditionBlock); |
| 2330 stack.add(graph.addNewLiteralBool(false)); | 2324 stack.add(graph.addConstantBool(false)); |
| 2331 | 2325 |
| 2332 conditionBlock = close(new HLoopBranch(popBoolified(), | 2326 conditionBlock = close(new HLoopBranch(popBoolified(), |
| 2333 HLoopBranch.DO_WHILE_LOOP)); | 2327 HLoopBranch.DO_WHILE_LOOP)); |
| 2334 | 2328 |
| 2335 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. | 2329 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. |
| 2336 loopEntryBlock.postProcessLoopHeader(); | 2330 loopEntryBlock.postProcessLoopHeader(); |
| 2337 | 2331 |
| 2338 endLoop(loopEntryBlock, conditionBlock, breakHandler); | 2332 endLoop(loopEntryBlock, conditionBlock, breakHandler); |
| 2339 } | 2333 } |
| 2340 | 2334 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2371 new HInvokeStatic(Selector.INVOCATION_1, inputs); | 2365 new HInvokeStatic(Selector.INVOCATION_1, inputs); |
| 2372 add(unwrappedException); | 2366 add(unwrappedException); |
| 2373 | 2367 |
| 2374 tryInstruction.exception = exception; | 2368 tryInstruction.exception = exception; |
| 2375 Link<Node> link = node.catchBlocks.nodes; | 2369 Link<Node> link = node.catchBlocks.nodes; |
| 2376 | 2370 |
| 2377 void pushCondition(CatchBlock catchBlock) { | 2371 void pushCondition(CatchBlock catchBlock) { |
| 2378 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 2372 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 2379 HInstruction condition = null; | 2373 HInstruction condition = null; |
| 2380 if (declaration.type == null) { | 2374 if (declaration.type == null) { |
| 2381 condition = graph.addNewLiteralTrue(); | 2375 condition = graph.addConstantBool(true); |
| 2382 stack.add(condition); | 2376 stack.add(condition); |
| 2383 } else { | 2377 } else { |
| 2384 Element typeElement = elements[declaration.type]; | 2378 Element typeElement = elements[declaration.type]; |
| 2385 if (typeElement == null) { | 2379 if (typeElement == null) { |
| 2386 compiler.cancel('Catch with unresolved type', node: catchBlock); | 2380 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 2387 } | 2381 } |
| 2388 condition = new HIs(typeElement, unwrappedException, nullOk: true); | 2382 condition = new HIs(typeElement, unwrappedException, nullOk: true); |
| 2389 push(condition); | 2383 push(condition); |
| 2390 } | 2384 } |
| 2391 } | 2385 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2441 visitCatchBlock(CatchBlock node) { | 2435 visitCatchBlock(CatchBlock node) { |
| 2442 visit(node.block); | 2436 visit(node.block); |
| 2443 } | 2437 } |
| 2444 | 2438 |
| 2445 visitTypedef(Typedef node) { | 2439 visitTypedef(Typedef node) { |
| 2446 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 2440 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 2447 } | 2441 } |
| 2448 | 2442 |
| 2449 generateUnimplemented(String reason, [bool isExpression = false]) { | 2443 generateUnimplemented(String reason, [bool isExpression = false]) { |
| 2450 DartString string = new DartString.literal(reason); | 2444 DartString string = new DartString.literal(reason); |
| 2451 HInstruction message = graph.addNewLiteralString(string); | 2445 HInstruction message = graph.addConstantString(string); |
| 2452 | 2446 |
| 2453 // Normally, we would call [close] here. However, then we hit | 2447 // Normally, we would call [close] here. However, then we hit |
| 2454 // another unimplemented feature: aborting loop body. Simply | 2448 // another unimplemented feature: aborting loop body. Simply |
| 2455 // calling [add] does not work as it asserts that the instruction | 2449 // calling [add] does not work as it asserts that the instruction |
| 2456 // isn't a control flow instruction. So we inline parts of [add]. | 2450 // isn't a control flow instruction. So we inline parts of [add]. |
| 2457 current.addAfter(current.last, new HThrow(message)); | 2451 current.addAfter(current.last, new HThrow(message)); |
| 2458 if (isExpression) { | 2452 if (isExpression) { |
| 2459 stack.add(graph.addNewLiteralNull()); | 2453 stack.add(graph.addConstantNull()); |
| 2460 } | 2454 } |
| 2461 } | 2455 } |
| 2462 } | 2456 } |
| OLD | NEW |