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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 17413013: Revert "Support runtime check of function types." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 } 1164 }
1165 1165
1166 FunctionSignature signature = function.computeSignature(compiler); 1166 FunctionSignature signature = function.computeSignature(compiler);
1167 signature.orderedForEachParameter((Element parameter) { 1167 signature.orderedForEachParameter((Element parameter) {
1168 HInstruction argument = compiledArguments[argumentIndex++]; 1168 HInstruction argument = compiledArguments[argumentIndex++];
1169 newLocalsHandler.updateLocal(parameter, argument); 1169 newLocalsHandler.updateLocal(parameter, argument);
1170 }); 1170 });
1171 1171
1172 ClassElement enclosing = function.getEnclosingClass(); 1172 ClassElement enclosing = function.getEnclosingClass();
1173 if ((function.isConstructor() || function.isGenerativeConstructorBody()) 1173 if ((function.isConstructor() || function.isGenerativeConstructorBody())
1174 && backend.classNeedsRti(enclosing)) { 1174 && backend.needsRti(enclosing)) {
1175 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1175 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1176 HInstruction argument = compiledArguments[argumentIndex++]; 1176 HInstruction argument = compiledArguments[argumentIndex++];
1177 newLocalsHandler.updateLocal(typeVariable.element, argument); 1177 newLocalsHandler.updateLocal(typeVariable.element, argument);
1178 }); 1178 });
1179 } 1179 }
1180 assert(argumentIndex == compiledArguments.length); 1180 assert(argumentIndex == compiledArguments.length);
1181 1181
1182 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. 1182 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
1183 returnElement = new ElementX(const SourceString("result"), 1183 returnElement = new ElementX(const SourceString("result"),
1184 ElementKind.VARIABLE, 1184 ElementKind.VARIABLE,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 compiledArguments)); 1329 compiledArguments));
1330 if (!succeeded) { 1330 if (!succeeded) {
1331 // Non-matching super and redirects are compile-time errors and thus 1331 // Non-matching super and redirects are compile-time errors and thus
1332 // checked by the resolver. 1332 // checked by the resolver.
1333 compiler.internalError( 1333 compiler.internalError(
1334 "Parameters and arguments didn't match for super/redirect call", 1334 "Parameters and arguments didn't match for super/redirect call",
1335 element: constructor); 1335 element: constructor);
1336 } 1336 }
1337 1337
1338 ClassElement superclass = constructor.getEnclosingClass(); 1338 ClassElement superclass = constructor.getEnclosingClass();
1339 if (backend.classNeedsRti(superclass)) { 1339 if (backend.needsRti(superclass)) {
1340 // If [superclass] needs RTI, we have to give a value to its 1340 // If [superclass] needs RTI, we have to give a value to its
1341 // type parameters. Those values are in the [supertype] 1341 // type parameters. Those values are in the [supertype]
1342 // declaration of [subclass]. 1342 // declaration of [subclass].
1343 ClassElement subclass = inlinedFromElement.getEnclosingClass(); 1343 ClassElement subclass = inlinedFromElement.getEnclosingClass();
1344 InterfaceType supertype = subclass.supertype; 1344 InterfaceType supertype = subclass.supertype;
1345 Link<DartType> typeVariables = superclass.typeVariables; 1345 Link<DartType> typeVariables = superclass.typeVariables;
1346 supertype.typeArguments.forEach((DartType argument) { 1346 supertype.typeArguments.forEach((DartType argument) {
1347 localsHandler.updateLocal(typeVariables.head.element, 1347 localsHandler.updateLocal(typeVariables.head.element,
1348 analyzeTypeArgument(argument, callNode)); 1348 analyzeTypeArgument(argument, callNode));
1349 typeVariables = typeVariables.tail; 1349 typeVariables = typeVariables.tail;
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 includeSuperAndInjectedMembers: true); 1576 includeSuperAndInjectedMembers: true);
1577 1577
1578 InterfaceType type = classElement.computeType(compiler); 1578 InterfaceType type = classElement.computeType(compiler);
1579 HType ssaType = new HType.nonNullExact(type, compiler); 1579 HType ssaType = new HType.nonNullExact(type, compiler);
1580 HForeignNew newObject = new HForeignNew(classElement, 1580 HForeignNew newObject = new HForeignNew(classElement,
1581 ssaType, 1581 ssaType,
1582 constructorArguments); 1582 constructorArguments);
1583 add(newObject); 1583 add(newObject);
1584 1584
1585 // Create the runtime type information, if needed. 1585 // Create the runtime type information, if needed.
1586 if (backend.classNeedsRti(classElement)) { 1586 if (backend.needsRti(classElement)) {
1587 List<HInstruction> rtiInputs = <HInstruction>[]; 1587 List<HInstruction> rtiInputs = <HInstruction>[];
1588 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1588 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1589 rtiInputs.add(localsHandler.readLocal(typeVariable.element)); 1589 rtiInputs.add(localsHandler.readLocal(typeVariable.element));
1590 }); 1590 });
1591 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject); 1591 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject);
1592 } 1592 }
1593 1593
1594 // Generate calls to the constructor bodies. 1594 // Generate calls to the constructor bodies.
1595 for (int index = constructors.length - 1; index >= 0; index--) { 1595 for (int index = constructors.length - 1; index >= 0; index--) {
1596 FunctionElement constructor = constructors[index]; 1596 FunctionElement constructor = constructors[index];
(...skipping 25 matching lines...) Expand all
1622 // If [parameter] is checked, we pass the already computed 1622 // If [parameter] is checked, we pass the already computed
1623 // boolean to the constructor body. 1623 // boolean to the constructor body.
1624 if (elements.isParameterChecked(parameter)) { 1624 if (elements.isParameterChecked(parameter)) {
1625 Element fieldCheck = 1625 Element fieldCheck =
1626 parameterClosureData.parametersWithSentinel[parameter]; 1626 parameterClosureData.parametersWithSentinel[parameter];
1627 bodyCallInputs.add(localsHandler.readLocal(fieldCheck)); 1627 bodyCallInputs.add(localsHandler.readLocal(fieldCheck));
1628 } 1628 }
1629 }); 1629 });
1630 1630
1631 ClassElement currentClass = constructor.getEnclosingClass(); 1631 ClassElement currentClass = constructor.getEnclosingClass();
1632 if (backend.classNeedsRti(currentClass)) { 1632 if (backend.needsRti(currentClass)) {
1633 // If [currentClass] needs RTI, we add the type variables as 1633 // If [currentClass] needs RTI, we add the type variables as
1634 // parameters of the generative constructor body. 1634 // parameters of the generative constructor body.
1635 currentClass.typeVariables.forEach((DartType argument) { 1635 currentClass.typeVariables.forEach((DartType argument) {
1636 bodyCallInputs.add(localsHandler.readLocal(argument.element)); 1636 bodyCallInputs.add(localsHandler.readLocal(argument.element));
1637 }); 1637 });
1638 } 1638 }
1639 1639
1640 // If there are locals that escape (ie mutated in closures), we 1640 // If there are locals that escape (ie mutated in closures), we
1641 // pass the box to the constructor. 1641 // pass the box to the constructor.
1642 ClosureScope scopeData = parameterClosureData.capturingScopes[node]; 1642 ClosureScope scopeData = parameterClosureData.capturingScopes[node];
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 localsHandler.startFunction(element, node); 1726 localsHandler.startFunction(element, node);
1727 close(new HGoto()).addSuccessor(block); 1727 close(new HGoto()).addSuccessor(block);
1728 1728
1729 open(block); 1729 open(block);
1730 1730
1731 // Add the type parameters of the class as parameters of this method. This 1731 // Add the type parameters of the class as parameters of this method. This
1732 // must be done before adding the normal parameters, because their types 1732 // must be done before adding the normal parameters, because their types
1733 // may contain references to type variables. 1733 // may contain references to type variables.
1734 var enclosing = element.enclosingElement; 1734 var enclosing = element.enclosingElement;
1735 if ((element.isConstructor() || element.isGenerativeConstructorBody()) 1735 if ((element.isConstructor() || element.isGenerativeConstructorBody())
1736 && backend.classNeedsRti(enclosing)) { 1736 && backend.needsRti(enclosing)) {
1737 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1737 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1738 HParameterValue param = addParameter(typeVariable.element); 1738 HParameterValue param = addParameter(typeVariable.element);
1739 localsHandler.directLocals[typeVariable.element] = param; 1739 localsHandler.directLocals[typeVariable.element] = param;
1740 }); 1740 });
1741 } 1741 }
1742 1742
1743 if (element is FunctionElement) { 1743 if (element is FunctionElement) {
1744 FunctionElement functionElement = element; 1744 FunctionElement functionElement = element;
1745 FunctionSignature signature = functionElement.computeSignature(compiler); 1745 FunctionSignature signature = functionElement.computeSignature(compiler);
1746 signature.orderedForEachParameter((Element parameterElement) { 1746 signature.orderedForEachParameter((Element parameterElement) {
(...skipping 28 matching lines...) Expand all
1775 } else { 1775 } else {
1776 // Otherwise it is a lazy initializer which does not have parameters. 1776 // Otherwise it is a lazy initializer which does not have parameters.
1777 assert(element is VariableElement); 1777 assert(element is VariableElement);
1778 } 1778 }
1779 } 1779 }
1780 1780
1781 HInstruction buildTypeConversion(HInstruction original, 1781 HInstruction buildTypeConversion(HInstruction original,
1782 DartType type, 1782 DartType type,
1783 int kind) { 1783 int kind) {
1784 if (type == null) return original; 1784 if (type == null) return original;
1785 type = type.unalias(compiler);
1786 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) { 1785 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) {
1787 HType subtype = new HType.subtype(type, compiler); 1786 HType subtype = new HType.subtype(type, compiler);
1788 HInstruction representations = buildTypeArgumentRepresentations(type); 1787 HInstruction representations = buildTypeArgumentRepresentations(type);
1789 add(representations); 1788 add(representations);
1790 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1789 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1791 original, representations); 1790 original, representations);
1792 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 1791 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
1793 HType subtype = original.instructionType; 1792 HType subtype = original.instructionType;
1794 HInstruction typeVariable = addTypeVariableReference(type); 1793 HInstruction typeVariable = addTypeVariableReference(type);
1795 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1794 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1796 original, typeVariable); 1795 original, typeVariable);
1797 } else if (type.kind == TypeKind.FUNCTION) {
1798 HType subtype = original.instructionType;
1799 if (type.containsTypeVariables) {
1800 bool contextIsTypeArguments = false;
1801 HInstruction context;
1802 if (currentElement.isInstanceMember()) {
1803 context = localsHandler.readThis();
1804 } else {
1805 ClassElement contextClass = Types.getClassContext(type);
1806 context = buildTypeVariableList(contextClass);
1807 add(context);
1808 contextIsTypeArguments = true;
1809 }
1810 return new HTypeConversion.withContext(type, kind, subtype,
1811 original, context, contextIsTypeArguments: contextIsTypeArguments);
1812 } else {
1813 return new HTypeConversion(type, kind, subtype, original);
1814 }
1815 } else { 1796 } else {
1816 return original.convertType(compiler, type, kind); 1797 return original.convertType(compiler, type, kind);
1817 } 1798 }
1818 } 1799 }
1819 1800
1820 HInstruction potentiallyCheckType(HInstruction original, DartType type, 1801 HInstruction potentiallyCheckType(HInstruction original, DartType type,
1821 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1802 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1822 if (!compiler.enableTypeAssertions) return original; 1803 if (!compiler.enableTypeAssertions) return original;
1823 HInstruction other = buildTypeConversion(original, type, kind); 1804 HInstruction other = buildTypeConversion(original, type, kind);
1824 if (other != original) add(other); 1805 if (other != original) add(other);
1825 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
1826 return other; 1806 return other;
1827 } 1807 }
1828 1808
1829 HGraph closeFunction() { 1809 HGraph closeFunction() {
1830 // TODO(kasperl): Make this goto an implicit return. 1810 // TODO(kasperl): Make this goto an implicit return.
1831 if (!isAborted()) closeAndGotoExit(new HGoto()); 1811 if (!isAborted()) closeAndGotoExit(new HGoto());
1832 graph.finalize(); 1812 graph.finalize();
1833 return graph; 1813 return graph;
1834 } 1814 }
1835 1815
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2441 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2462 assert(capturedLocal != null); 2442 assert(capturedLocal != null);
2463 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2443 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2464 } 2444 }
2465 }); 2445 });
2466 2446
2467 HType type = new HType.nonNullExact( 2447 HType type = new HType.nonNullExact(
2468 compiler.functionClass.computeType(compiler), 2448 compiler.functionClass.computeType(compiler),
2469 compiler); 2449 compiler);
2470 push(new HForeignNew(closureClassElement, type, capturedVariables)); 2450 push(new HForeignNew(closureClassElement, type, capturedVariables));
2471
2472 Element methodElement = nestedClosureData.closureElement;
2473 if (compiler.backend.methodNeedsRti(methodElement)) {
2474 compiler.backend.registerGenericClosure(
2475 methodElement, compiler.enqueuer.codegen, work.resolutionTree);
2476 }
2477 } 2451 }
2478 2452
2479 visitFunctionDeclaration(FunctionDeclaration node) { 2453 visitFunctionDeclaration(FunctionDeclaration node) {
2480 assert(isReachable); 2454 assert(isReachable);
2481 visit(node.function); 2455 visit(node.function);
2482 localsHandler.updateLocal(elements[node], pop()); 2456 localsHandler.updateLocal(elements[node], pop());
2483 } 2457 }
2484 2458
2485 visitIdentifier(Identifier node) { 2459 visitIdentifier(Identifier node) {
2486 if (node.isThis()) { 2460 if (node.isThis()) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2750 inputs.add(runtimeType); 2724 inputs.add(runtimeType);
2751 })); 2725 }));
2752 } 2726 }
2753 String template = '[${templates.join(', ')}]'; 2727 String template = '[${templates.join(', ')}]';
2754 HInstruction representation = 2728 HInstruction representation =
2755 createForeign(template, backend.readableArrayType, inputs); 2729 createForeign(template, backend.readableArrayType, inputs);
2756 return representation; 2730 return representation;
2757 } 2731 }
2758 } 2732 }
2759 2733
2760 visitOperatorSend(Send node) { 2734 visitOperatorSend(node) {
2761 Operator op = node.selector; 2735 Operator op = node.selector;
2762 if (const SourceString("[]") == op.source) { 2736 if (const SourceString("[]") == op.source) {
2763 visitDynamicSend(node); 2737 visitDynamicSend(node);
2764 } else if (const SourceString("&&") == op.source || 2738 } else if (const SourceString("&&") == op.source ||
2765 const SourceString("||") == op.source) { 2739 const SourceString("||") == op.source) {
2766 visitLogicalAndOr(node, op); 2740 visitLogicalAndOr(node, op);
2767 } else if (const SourceString("!") == op.source) { 2741 } else if (const SourceString("!") == op.source) {
2768 visitLogicalNot(node); 2742 visitLogicalNot(node);
2769 } else if (node.argumentsNode is Prefix) { 2743 } else if (node.argumentsNode is Prefix) {
2770 visitUnary(node, op); 2744 visitUnary(node, op);
(...skipping 16 matching lines...) Expand all
2787 var left = pop(); 2761 var left = pop();
2788 visitBinary(left, op, right, elements.getSelector(node), node); 2762 visitBinary(left, op, right, elements.getSelector(node), node);
2789 } 2763 }
2790 } 2764 }
2791 2765
2792 void visitIsSend(Send node) { 2766 void visitIsSend(Send node) {
2793 visit(node.receiver); 2767 visit(node.receiver);
2794 HInstruction expression = pop(); 2768 HInstruction expression = pop();
2795 bool isNot = node.isIsNotCheck; 2769 bool isNot = node.isIsNotCheck;
2796 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 2770 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
2797 type = type.unalias(compiler);
2798 if (type.isMalformed) { 2771 if (type.isMalformed) {
2799 String reasons = Types.fetchReasonsFromMalformedType(type); 2772 String reasons = Types.fetchReasonsFromMalformedType(type);
2800 if (compiler.enableTypeAssertions) { 2773 if (compiler.enableTypeAssertions) {
2801 generateMalformedSubtypeError(node, expression, type, reasons); 2774 generateMalformedSubtypeError(node, expression, type, reasons);
2802 } else { 2775 } else {
2803 generateRuntimeError(node, '$type is malformed: $reasons'); 2776 generateRuntimeError(node, '$type is malformed: $reasons');
2804 } 2777 }
2805 } else { 2778 } else {
2806 HInstruction instruction = buildIsNode(node, type, expression); 2779 HInstruction instruction = buildIsNode(node, type, expression);
2807 if (isNot) { 2780 if (isNot) {
2808 add(instruction); 2781 add(instruction);
2809 instruction = new HNot(instruction); 2782 instruction = new HNot(instruction);
2810 } 2783 }
2811 push(instruction); 2784 push(instruction);
2812 } 2785 }
2813 } 2786 }
2814 2787
2815 HLiteralList buildTypeVariableList(ClassElement contextClass) {
2816 List<HInstruction> inputs = <HInstruction>[];
2817 for (Link<DartType> link = contextClass.typeVariables;
2818 !link.isEmpty;
2819 link = link.tail) {
2820 inputs.add(addTypeVariableReference(link.head));
2821 }
2822 return buildLiteralList(inputs);
2823 }
2824
2825 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { 2788 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
2826 type = type.unalias(compiler); 2789 if (type.kind == TypeKind.TYPE_VARIABLE) {
2827 if (type.kind == TypeKind.FUNCTION) {
2828 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
2829
2830 HInstruction signatureName = graph.addConstantString(
2831 new DartString.literal(backend.namer.getFunctionTypeName(type)),
2832 node, compiler);
2833
2834 HInstruction contextName;
2835 HInstruction context;
2836 HInstruction typeArguments;
2837 if (type.containsTypeVariables) {
2838 ClassElement contextClass = Types.getClassContext(type);
2839 contextName = graph.addConstantString(
2840 new DartString.literal(backend.namer.getName(contextClass)),
2841 node, compiler);
2842 if (currentElement.isInstanceMember()) {
2843 context = localsHandler.readThis();
2844 typeArguments = graph.addConstantNull(compiler);
2845 } else {
2846 context = graph.addConstantNull(compiler);
2847 typeArguments = buildTypeVariableList(contextClass);
2848 add(typeArguments);
2849 }
2850 } else {
2851 contextName = graph.addConstantNull(compiler);
2852 context = graph.addConstantNull(compiler);
2853 typeArguments = graph.addConstantNull(compiler);
2854 }
2855
2856 List<HInstruction> inputs = <HInstruction>[expression,
2857 signatureName,
2858 contextName,
2859 context,
2860 typeArguments];
2861 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
2862 HInstruction call = pop();
2863 return new HIs(type, <HInstruction>[expression, call],
2864 HIs.COMPOUND_CHECK);
2865 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2866 HInstruction runtimeType = addTypeVariableReference(type); 2790 HInstruction runtimeType = addTypeVariableReference(type);
2867 Element helper = backend.getCheckSubtypeOfRuntimeType(); 2791 Element helper = backend.getCheckSubtypeOfRuntimeType();
2868 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2792 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2869 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); 2793 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
2870 HInstruction call = pop(); 2794 HInstruction call = pop();
2871 return new HIs(type, <HInstruction>[expression, call], 2795 return new HIs(type, <HInstruction>[expression, call],
2872 HIs.VARIABLE_CHECK); 2796 HIs.VARIABLE_CHECK);
2873 } else if (RuntimeTypes.hasTypeArguments(type)) { 2797 } else if (RuntimeTypes.hasTypeArguments(type)) {
2874 ClassElement element = type.element; 2798 ClassElement element = type.element;
2875 Element helper = backend.getCheckSubtype(); 2799 Element helper = backend.getCheckSubtype();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 Element element = compiler.isolateHelperLibrary.find( 2977 Element element = compiler.isolateHelperLibrary.find(
3054 const SourceString('_currentIsolate')); 2978 const SourceString('_currentIsolate'));
3055 if (element == null) { 2979 if (element == null) {
3056 compiler.cancel( 2980 compiler.cancel(
3057 'Isolate library and compiler mismatch', node: node); 2981 'Isolate library and compiler mismatch', node: node);
3058 } 2982 }
3059 pushInvokeStatic(null, element, [], HType.UNKNOWN); 2983 pushInvokeStatic(null, element, [], HType.UNKNOWN);
3060 } 2984 }
3061 } 2985 }
3062 2986
3063 void handleForeignJsSetupObject(Send node) {
3064 if (!node.arguments.isEmpty) {
3065 compiler.cancel(
3066 'Too many arguments to JS_GLOBAL_OBJECT', node: node);
3067 }
3068
3069 String name = backend.namer.GLOBAL_OBJECT;
3070 push(new HForeign(new js.LiteralString(name),
3071 HType.UNKNOWN,
3072 <HInstruction>[]));
3073 }
3074
3075 void handleForeignJsCallInIsolate(Send node) { 2987 void handleForeignJsCallInIsolate(Send node) {
3076 Link<Node> link = node.arguments; 2988 Link<Node> link = node.arguments;
3077 if (!compiler.hasIsolateSupport()) { 2989 if (!compiler.hasIsolateSupport()) {
3078 // If the isolate library is not used, we just invoke the 2990 // If the isolate library is not used, we just invoke the
3079 // closure. 2991 // closure.
3080 visit(link.tail.head); 2992 visit(link.tail.head);
3081 Selector selector = new Selector.callClosure(0); 2993 Selector selector = new Selector.callClosure(0);
3082 push(new HInvokeClosure(selector, <HInstruction>[pop()])); 2994 push(new HInvokeClosure(selector, <HInstruction>[pop()]));
3083 } else { 2995 } else {
3084 // Call a helper method from the isolate library. 2996 // Call a helper method from the isolate library.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 <HInstruction>[])); 3088 <HInstruction>[]));
3177 } 3089 }
3178 3090
3179 visitForeignSend(Send node) { 3091 visitForeignSend(Send node) {
3180 Selector selector = elements.getSelector(node); 3092 Selector selector = elements.getSelector(node);
3181 SourceString name = selector.name; 3093 SourceString name = selector.name;
3182 if (name == const SourceString('JS')) { 3094 if (name == const SourceString('JS')) {
3183 handleForeignJs(node); 3095 handleForeignJs(node);
3184 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { 3096 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) {
3185 handleForeignJsCurrentIsolateContext(node); 3097 handleForeignJsCurrentIsolateContext(node);
3186 } else if (name == const SourceString('JS_GLOBAL_OBJECT')) {
3187 handleForeignJsSetupObject(node);
3188 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { 3098 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) {
3189 handleForeignJsCallInIsolate(node); 3099 handleForeignJsCallInIsolate(node);
3190 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { 3100 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
3191 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 3101 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
3192 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { 3102 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) {
3193 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 3103 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
3194 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { 3104 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) {
3195 handleForeignSetCurrentIsolate(node); 3105 handleForeignSetCurrentIsolate(node);
3196 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { 3106 } else if (name == const SourceString('JS_CREATE_ISOLATE')) {
3197 handleForeignCreateIsolate(node); 3107 handleForeignCreateIsolate(node);
3198 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { 3108 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
3199 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3109 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3200 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { 3110 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) {
3201 String name = backend.namer.getRuntimeTypeName(compiler.objectClass); 3111 String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
3202 stack.add(addConstantString(node, name)); 3112 stack.add(addConstantString(node, name));
3203 } else if (name == const SourceString('JS_FUNCTION_CLASS_NAME')) {
3204 String name = backend.namer.getRuntimeTypeName(compiler.functionClass);
3205 stack.add(addConstantString(node, name));
3206 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { 3113 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3207 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); 3114 stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
3208 } else if (name == const SourceString('JS_SIGNATURE_NAME')) {
3209 stack.add(addConstantString(node, backend.namer.operatorSignature()));
3210 } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) {
3211 stack.add(addConstantString(node, backend.namer.functionTypeTag()));
3212 } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) {
3213 stack.add(addConstantString(node,
3214 backend.namer.functionTypeVoidReturnTag()));
3215 } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) {
3216 stack.add(addConstantString(node,
3217 backend.namer.functionTypeReturnTypeTag()));
3218 } else if (name ==
3219 const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) {
3220 stack.add(addConstantString(node,
3221 backend.namer.functionTypeRequiredParametersTag()));
3222 } else if (name ==
3223 const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) {
3224 stack.add(addConstantString(node,
3225 backend.namer.functionTypeOptionalParametersTag()));
3226 } else if (name ==
3227 const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) {
3228 stack.add(addConstantString(node,
3229 backend.namer.functionTypeNamedParametersTag()));
3230 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { 3115 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
3231 handleForeignDartObjectJsConstructorFunction(node); 3116 handleForeignDartObjectJsConstructorFunction(node);
3232 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { 3117 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) {
3233 Element element = compiler.findHelper( 3118 Element element = compiler.findHelper(
3234 const SourceString('JavaScriptIndexingBehavior')); 3119 const SourceString('JavaScriptIndexingBehavior'));
3235 stack.add(addConstantString(node, backend.namer.operatorIs(element))); 3120 stack.add(addConstantString(node, backend.namer.operatorIs(element)));
3236 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { 3121 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) {
3237 handleForeignJsCurrentIsolate(node); 3122 handleForeignJsCurrentIsolate(node);
3238 } else { 3123 } else {
3239 throw "Unknown foreign: ${selector}"; 3124 throw "Unknown foreign: ${selector}";
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3336 /** 3221 /**
3337 * Generate code to extract the type arguments from the object, substitute 3222 * Generate code to extract the type arguments from the object, substitute
3338 * them as an instance of the type we are testing against (if necessary), and 3223 * them as an instance of the type we are testing against (if necessary), and
3339 * extract the type argument by the index of the variable in the list of type 3224 * extract the type argument by the index of the variable in the list of type
3340 * variables for that class. 3225 * variables for that class.
3341 */ 3226 */
3342 HInstruction readTypeVariable(ClassElement cls, 3227 HInstruction readTypeVariable(ClassElement cls,
3343 TypeVariableElement variable) { 3228 TypeVariableElement variable) {
3344 assert(currentElement.isInstanceMember()); 3229 assert(currentElement.isInstanceMember());
3345 int index = RuntimeTypes.getTypeVariableIndex(variable); 3230 int index = RuntimeTypes.getTypeVariableIndex(variable);
3346 String substitutionNameString = backend.namer.getName(cls); 3231 String substitutionNameString = backend.namer.substitutionName(cls);
3347 HInstruction substitutionName = graph.addConstantString( 3232 HInstruction substitutionName = graph.addConstantString(
3348 new LiteralDartString(substitutionNameString), null, compiler); 3233 new LiteralDartString(substitutionNameString), null, compiler);
3349 HInstruction target = localsHandler.readThis(); 3234 HInstruction target = localsHandler.readThis();
3235 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
3236 <HInstruction>[target, substitutionName]);
3237 add(substitution);
3350 pushInvokeStatic(null, 3238 pushInvokeStatic(null,
3351 backend.getGetRuntimeTypeArgument(), 3239 backend.getGetRuntimeTypeArgument(),
3352 [target, 3240 [target,
3353 substitutionName, 3241 substitution,
3354 graph.addConstantInt(index, compiler)], 3242 graph.addConstantInt(index, compiler)],
3355 HType.UNKNOWN); 3243 HType.UNKNOWN);
3356 return pop(); 3244 return pop();
3357 } 3245 }
3358 3246
3359 /** 3247 /**
3360 * Helper to create an instruction that gets the value of a type variable. 3248 * Helper to create an instruction that gets the value of a type variable.
3361 */ 3249 */
3362 HInstruction addTypeVariableReference(TypeVariableType type) { 3250 HInstruction addTypeVariableReference(TypeVariableType type) {
3363 Element member = currentElement; 3251 Element member = currentElement;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3425 }); 3313 });
3426 3314
3427 HInstruction result = createForeign(template, backend.stringType, inputs); 3315 HInstruction result = createForeign(template, backend.stringType, inputs);
3428 add(result); 3316 add(result);
3429 return result; 3317 return result;
3430 } 3318 }
3431 3319
3432 void handleListConstructor(InterfaceType type, 3320 void handleListConstructor(InterfaceType type,
3433 Node currentNode, 3321 Node currentNode,
3434 HInstruction newObject) { 3322 HInstruction newObject) {
3435 if (!backend.classNeedsRti(type.element)) return; 3323 if (!backend.needsRti(type.element)) return;
3436 if (!type.isRaw) { 3324 if (!type.isRaw) {
3437 List<HInstruction> inputs = <HInstruction>[]; 3325 List<HInstruction> inputs = <HInstruction>[];
3438 type.typeArguments.forEach((DartType argument) { 3326 type.typeArguments.forEach((DartType argument) {
3439 inputs.add(analyzeTypeArgument(argument, currentNode)); 3327 inputs.add(analyzeTypeArgument(argument, currentNode));
3440 }); 3328 });
3441 callSetRuntimeTypeInfo(type.element, inputs, newObject); 3329 callSetRuntimeTypeInfo(type.element, inputs, newObject);
3442 } 3330 }
3443 } 3331 }
3444 3332
3445 void callSetRuntimeTypeInfo(ClassElement element, 3333 void callSetRuntimeTypeInfo(ClassElement element,
3446 List<HInstruction> rtiInputs, 3334 List<HInstruction> rtiInputs,
3447 HInstruction newObject) { 3335 HInstruction newObject) {
3448 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { 3336 if (!backend.needsRti(element) || element.typeVariables.isEmpty) {
3449 return; 3337 return;
3450 } 3338 }
3451 3339
3452 HInstruction typeInfo = buildLiteralList(rtiInputs); 3340 HInstruction typeInfo = buildLiteralList(rtiInputs);
3453 add(typeInfo); 3341 add(typeInfo);
3454 3342
3455 // Set the runtime type information on the object. 3343 // Set the runtime type information on the object.
3456 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); 3344 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo();
3457 pushInvokeStatic( 3345 pushInvokeStatic(
3458 null, 3346 null,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3536 if (!succeeded) { 3424 if (!succeeded) {
3537 generateWrongArgumentCountError(send, constructor, send.arguments); 3425 generateWrongArgumentCountError(send, constructor, send.arguments);
3538 return; 3426 return;
3539 } 3427 }
3540 3428
3541 ClassElement cls = constructor.getEnclosingClass(); 3429 ClassElement cls = constructor.getEnclosingClass();
3542 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) { 3430 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) {
3543 generateAbstractClassInstantiationError(send, cls.name.slowToString()); 3431 generateAbstractClassInstantiationError(send, cls.name.slowToString());
3544 return; 3432 return;
3545 } 3433 }
3546 if (backend.classNeedsRti(cls)) { 3434 if (backend.needsRti(cls)) {
3547 Link<DartType> typeVariable = cls.typeVariables; 3435 Link<DartType> typeVariable = cls.typeVariables;
3548 type.typeArguments.forEach((DartType argument) { 3436 type.typeArguments.forEach((DartType argument) {
3549 inputs.add(analyzeTypeArgument(argument, send)); 3437 inputs.add(analyzeTypeArgument(argument, send));
3550 typeVariable = typeVariable.tail; 3438 typeVariable = typeVariable.tail;
3551 }); 3439 });
3552 // Also add null to non-provided type variables to call the 3440 // Also add null to non-provided type variables to call the
3553 // constructor with the right number of arguments. 3441 // constructor with the right number of arguments.
3554 while (!typeVariable.isEmpty) { 3442 while (!typeVariable.isEmpty) {
3555 inputs.add(graph.addConstantNull(compiler)); 3443 inputs.add(graph.addConstantNull(compiler));
3556 typeVariable = typeVariable.tail; 3444 typeVariable = typeVariable.tail;
3557 } 3445 }
3558 } 3446 }
3559 3447
3560 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { 3448 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
3561 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); 3449 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
3562 } 3450 }
3563 HType elementType = computeType(constructor); 3451 HType elementType = computeType(constructor);
3564 pushInvokeStatic(node, constructor, inputs, elementType); 3452 pushInvokeStatic(node, constructor, inputs, elementType);
3565 HInstruction newInstance = stack.last; 3453 HInstruction newInstance = stack.last;
3566 3454
3567 // The List constructor forwards to a Dart static method that does 3455 // The List constructor forwards to a Dart static method that does
3568 // not know about the type argument. Therefore we special case 3456 // not know about the type argument. Therefore we special case
3569 // this constructor to have the setRuntimeTypeInfo called where 3457 // this constructor to have the setRuntimeTypeInfo called where
3570 // the 'new' is done. 3458 // the 'new' is done.
3571 if (isListConstructor && backend.classNeedsRti(compiler.listClass)) { 3459 if (isListConstructor && backend.needsRti(compiler.listClass)) {
3572 handleListConstructor(type, send, newInstance); 3460 handleListConstructor(type, send, newInstance);
3573 } 3461 }
3574 3462
3575 // Finally, if we called a redirecting factory constructor, check the type. 3463 // Finally, if we called a redirecting factory constructor, check the type.
3576 if (isRedirected) { 3464 if (isRedirected) {
3577 HInstruction checked = potentiallyCheckType(newInstance, expectedType); 3465 HInstruction checked = potentiallyCheckType(newInstance, expectedType);
3578 if (checked != newInstance) { 3466 if (checked != newInstance) {
3579 pop(); 3467 pop();
3580 stack.add(checked); 3468 stack.add(checked);
3581 } 3469 }
(...skipping 1933 matching lines...) Expand 10 before | Expand all | Expand 10 after
5515 new HSubGraphBlockInformation(elseBranch.graph)); 5403 new HSubGraphBlockInformation(elseBranch.graph));
5516 5404
5517 HBasicBlock conditionStartBlock = conditionBranch.block; 5405 HBasicBlock conditionStartBlock = conditionBranch.block;
5518 conditionStartBlock.setBlockFlow(info, joinBlock); 5406 conditionStartBlock.setBlockFlow(info, joinBlock);
5519 SubGraph conditionGraph = conditionBranch.graph; 5407 SubGraph conditionGraph = conditionBranch.graph;
5520 HIf branch = conditionGraph.end.last; 5408 HIf branch = conditionGraph.end.last;
5521 assert(branch is HIf); 5409 assert(branch is HIf);
5522 branch.blockInformation = conditionStartBlock.blockFlow; 5410 branch.blockInformation = conditionStartBlock.blockFlow;
5523 } 5411 }
5524 } 5412 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698