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

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

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix 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.needsRti(enclosing)) { 1174 && backend.classNeedsRti(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.needsRti(superclass)) { 1339 if (backend.classNeedsRti(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.needsRti(classElement)) { 1586 if (backend.classNeedsRti(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.needsRti(currentClass)) { 1632 if (backend.classNeedsRti(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.needsRti(enclosing)) { 1736 && backend.classNeedsRti(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);
1785 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) { 1786 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) {
1786 HType subtype = new HType.subtype(type, compiler); 1787 HType subtype = new HType.subtype(type, compiler);
1787 HInstruction representations = buildTypeArgumentRepresentations(type); 1788 HInstruction representations = buildTypeArgumentRepresentations(type);
1788 add(representations); 1789 add(representations);
1789 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1790 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1790 original, representations); 1791 original, representations);
1791 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 1792 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
1792 HType subtype = original.instructionType; 1793 HType subtype = original.instructionType;
1793 HInstruction typeVariable = addTypeVariableReference(type); 1794 HInstruction typeVariable = addTypeVariableReference(type);
1794 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 1795 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
1795 original, typeVariable); 1796 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 }
1796 } else { 1815 } else {
1797 return original.convertType(compiler, type, kind); 1816 return original.convertType(compiler, type, kind);
1798 } 1817 }
1799 } 1818 }
1800 1819
1801 HInstruction potentiallyCheckType(HInstruction original, DartType type, 1820 HInstruction potentiallyCheckType(HInstruction original, DartType type,
1802 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1821 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1803 if (!compiler.enableTypeAssertions) return original; 1822 if (!compiler.enableTypeAssertions) return original;
1804 HInstruction other = buildTypeConversion(original, type, kind); 1823 HInstruction other = buildTypeConversion(original, type, kind);
1805 if (other != original) add(other); 1824 if (other != original) add(other);
1825 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
1806 return other; 1826 return other;
1807 } 1827 }
1808 1828
1809 HGraph closeFunction() { 1829 HGraph closeFunction() {
1810 // TODO(kasperl): Make this goto an implicit return. 1830 // TODO(kasperl): Make this goto an implicit return.
1811 if (!isAborted()) closeAndGotoExit(new HGoto()); 1831 if (!isAborted()) closeAndGotoExit(new HGoto());
1812 graph.finalize(); 1832 graph.finalize();
1813 return graph; 1833 return graph;
1814 } 1834 }
1815 1835
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2461 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2442 assert(capturedLocal != null); 2462 assert(capturedLocal != null);
2443 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2463 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2444 } 2464 }
2445 }); 2465 });
2446 2466
2447 HType type = new HType.nonNullExact( 2467 HType type = new HType.nonNullExact(
2448 compiler.functionClass.computeType(compiler), 2468 compiler.functionClass.computeType(compiler),
2449 compiler); 2469 compiler);
2450 push(new HForeignNew(closureClassElement, type, capturedVariables)); 2470 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 }
2451 } 2477 }
2452 2478
2453 visitFunctionDeclaration(FunctionDeclaration node) { 2479 visitFunctionDeclaration(FunctionDeclaration node) {
2454 assert(isReachable); 2480 assert(isReachable);
2455 visit(node.function); 2481 visit(node.function);
2456 localsHandler.updateLocal(elements[node], pop()); 2482 localsHandler.updateLocal(elements[node], pop());
2457 } 2483 }
2458 2484
2459 visitIdentifier(Identifier node) { 2485 visitIdentifier(Identifier node) {
2460 if (node.isThis()) { 2486 if (node.isThis()) {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 inputs.add(runtimeType); 2750 inputs.add(runtimeType);
2725 })); 2751 }));
2726 } 2752 }
2727 String template = '[${templates.join(', ')}]'; 2753 String template = '[${templates.join(', ')}]';
2728 HInstruction representation = 2754 HInstruction representation =
2729 createForeign(template, backend.readableArrayType, inputs); 2755 createForeign(template, backend.readableArrayType, inputs);
2730 return representation; 2756 return representation;
2731 } 2757 }
2732 } 2758 }
2733 2759
2734 visitOperatorSend(node) { 2760 visitOperatorSend(Send node) {
2735 Operator op = node.selector; 2761 Operator op = node.selector;
2736 if (const SourceString("[]") == op.source) { 2762 if (const SourceString("[]") == op.source) {
2737 visitDynamicSend(node); 2763 visitDynamicSend(node);
2738 } else if (const SourceString("&&") == op.source || 2764 } else if (const SourceString("&&") == op.source ||
2739 const SourceString("||") == op.source) { 2765 const SourceString("||") == op.source) {
2740 visitLogicalAndOr(node, op); 2766 visitLogicalAndOr(node, op);
2741 } else if (const SourceString("!") == op.source) { 2767 } else if (const SourceString("!") == op.source) {
2742 visitLogicalNot(node); 2768 visitLogicalNot(node);
2743 } else if (node.argumentsNode is Prefix) { 2769 } else if (node.argumentsNode is Prefix) {
2744 visitUnary(node, op); 2770 visitUnary(node, op);
(...skipping 16 matching lines...) Expand all
2761 var left = pop(); 2787 var left = pop();
2762 visitBinary(left, op, right, elements.getSelector(node), node); 2788 visitBinary(left, op, right, elements.getSelector(node), node);
2763 } 2789 }
2764 } 2790 }
2765 2791
2766 void visitIsSend(Send node) { 2792 void visitIsSend(Send node) {
2767 visit(node.receiver); 2793 visit(node.receiver);
2768 HInstruction expression = pop(); 2794 HInstruction expression = pop();
2769 bool isNot = node.isIsNotCheck; 2795 bool isNot = node.isIsNotCheck;
2770 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 2796 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
2797 type = type.unalias(compiler);
2771 if (type.isMalformed) { 2798 if (type.isMalformed) {
2772 String reasons = Types.fetchReasonsFromMalformedType(type); 2799 String reasons = Types.fetchReasonsFromMalformedType(type);
2773 if (compiler.enableTypeAssertions) { 2800 if (compiler.enableTypeAssertions) {
2774 generateMalformedSubtypeError(node, expression, type, reasons); 2801 generateMalformedSubtypeError(node, expression, type, reasons);
2775 } else { 2802 } else {
2776 generateRuntimeError(node, '$type is malformed: $reasons'); 2803 generateRuntimeError(node, '$type is malformed: $reasons');
2777 } 2804 }
2778 } else { 2805 } else {
2779 HInstruction instruction = buildIsNode(node, type, expression); 2806 HInstruction instruction = buildIsNode(node, type, expression);
2780 if (isNot) { 2807 if (isNot) {
2781 add(instruction); 2808 add(instruction);
2782 instruction = new HNot(instruction); 2809 instruction = new HNot(instruction);
2783 } 2810 }
2784 push(instruction); 2811 push(instruction);
2785 } 2812 }
2786 } 2813 }
2787 2814
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
2788 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { 2825 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
2789 if (type.kind == TypeKind.TYPE_VARIABLE) { 2826 type = type.unalias(compiler);
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) {
2790 HInstruction runtimeType = addTypeVariableReference(type); 2866 HInstruction runtimeType = addTypeVariableReference(type);
2791 Element helper = backend.getCheckSubtypeOfRuntimeType(); 2867 Element helper = backend.getCheckSubtypeOfRuntimeType();
2792 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2868 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2793 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); 2869 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
2794 HInstruction call = pop(); 2870 HInstruction call = pop();
2795 return new HIs(type, <HInstruction>[expression, call], 2871 return new HIs(type, <HInstruction>[expression, call],
2796 HIs.VARIABLE_CHECK); 2872 HIs.VARIABLE_CHECK);
2797 } else if (RuntimeTypes.hasTypeArguments(type)) { 2873 } else if (RuntimeTypes.hasTypeArguments(type)) {
2798 ClassElement element = type.element; 2874 ClassElement element = type.element;
2799 Element helper = backend.getCheckSubtype(); 2875 Element helper = backend.getCheckSubtype();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2977 Element element = compiler.isolateHelperLibrary.find( 3053 Element element = compiler.isolateHelperLibrary.find(
2978 const SourceString('_currentIsolate')); 3054 const SourceString('_currentIsolate'));
2979 if (element == null) { 3055 if (element == null) {
2980 compiler.cancel( 3056 compiler.cancel(
2981 'Isolate library and compiler mismatch', node: node); 3057 'Isolate library and compiler mismatch', node: node);
2982 } 3058 }
2983 pushInvokeStatic(null, element, [], HType.UNKNOWN); 3059 pushInvokeStatic(null, element, [], HType.UNKNOWN);
2984 } 3060 }
2985 } 3061 }
2986 3062
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
2987 void handleForeignJsCallInIsolate(Send node) { 3075 void handleForeignJsCallInIsolate(Send node) {
2988 Link<Node> link = node.arguments; 3076 Link<Node> link = node.arguments;
2989 if (!compiler.hasIsolateSupport()) { 3077 if (!compiler.hasIsolateSupport()) {
2990 // If the isolate library is not used, we just invoke the 3078 // If the isolate library is not used, we just invoke the
2991 // closure. 3079 // closure.
2992 visit(link.tail.head); 3080 visit(link.tail.head);
2993 Selector selector = new Selector.callClosure(0); 3081 Selector selector = new Selector.callClosure(0);
2994 push(new HInvokeClosure(selector, <HInstruction>[pop()])); 3082 push(new HInvokeClosure(selector, <HInstruction>[pop()]));
2995 } else { 3083 } else {
2996 // Call a helper method from the isolate library. 3084 // Call a helper method from the isolate library.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3088 <HInstruction>[])); 3176 <HInstruction>[]));
3089 } 3177 }
3090 3178
3091 visitForeignSend(Send node) { 3179 visitForeignSend(Send node) {
3092 Selector selector = elements.getSelector(node); 3180 Selector selector = elements.getSelector(node);
3093 SourceString name = selector.name; 3181 SourceString name = selector.name;
3094 if (name == const SourceString('JS')) { 3182 if (name == const SourceString('JS')) {
3095 handleForeignJs(node); 3183 handleForeignJs(node);
3096 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) { 3184 } else if (name == const SourceString('JS_CURRENT_ISOLATE_CONTEXT')) {
3097 handleForeignJsCurrentIsolateContext(node); 3185 handleForeignJsCurrentIsolateContext(node);
3186 } else if (name == const SourceString('JS_GLOBAL_OBJECT')) {
3187 handleForeignJsSetupObject(node);
3098 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) { 3188 } else if (name == const SourceString('JS_CALL_IN_ISOLATE')) {
3099 handleForeignJsCallInIsolate(node); 3189 handleForeignJsCallInIsolate(node);
3100 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { 3190 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
3101 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 3191 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
3102 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { 3192 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) {
3103 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 3193 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
3104 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { 3194 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) {
3105 handleForeignSetCurrentIsolate(node); 3195 handleForeignSetCurrentIsolate(node);
3106 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { 3196 } else if (name == const SourceString('JS_CREATE_ISOLATE')) {
3107 handleForeignCreateIsolate(node); 3197 handleForeignCreateIsolate(node);
3108 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { 3198 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
3109 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3199 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3110 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) { 3200 } else if (name == const SourceString('JS_OBJECT_CLASS_NAME')) {
3111 String name = backend.namer.getRuntimeTypeName(compiler.objectClass); 3201 String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
3112 stack.add(addConstantString(node, name)); 3202 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));
3113 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { 3206 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3114 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); 3207 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()));
3115 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { 3230 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
3116 handleForeignDartObjectJsConstructorFunction(node); 3231 handleForeignDartObjectJsConstructorFunction(node);
3117 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) { 3232 } else if (name == const SourceString('JS_IS_INDEXABLE_FIELD_NAME')) {
3118 Element element = compiler.findHelper( 3233 Element element = compiler.findHelper(
3119 const SourceString('JavaScriptIndexingBehavior')); 3234 const SourceString('JavaScriptIndexingBehavior'));
3120 stack.add(addConstantString(node, backend.namer.operatorIs(element))); 3235 stack.add(addConstantString(node, backend.namer.operatorIs(element)));
3121 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { 3236 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) {
3122 handleForeignJsCurrentIsolate(node); 3237 handleForeignJsCurrentIsolate(node);
3123 } else { 3238 } else {
3124 throw "Unknown foreign: ${selector}"; 3239 throw "Unknown foreign: ${selector}";
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 /** 3336 /**
3222 * Generate code to extract the type arguments from the object, substitute 3337 * Generate code to extract the type arguments from the object, substitute
3223 * them as an instance of the type we are testing against (if necessary), and 3338 * them as an instance of the type we are testing against (if necessary), and
3224 * extract the type argument by the index of the variable in the list of type 3339 * extract the type argument by the index of the variable in the list of type
3225 * variables for that class. 3340 * variables for that class.
3226 */ 3341 */
3227 HInstruction readTypeVariable(ClassElement cls, 3342 HInstruction readTypeVariable(ClassElement cls,
3228 TypeVariableElement variable) { 3343 TypeVariableElement variable) {
3229 assert(currentElement.isInstanceMember()); 3344 assert(currentElement.isInstanceMember());
3230 int index = RuntimeTypes.getTypeVariableIndex(variable); 3345 int index = RuntimeTypes.getTypeVariableIndex(variable);
3231 String substitutionNameString = backend.namer.substitutionName(cls); 3346 String substitutionNameString = backend.namer.getName(cls);
3232 HInstruction substitutionName = graph.addConstantString( 3347 HInstruction substitutionName = graph.addConstantString(
3233 new LiteralDartString(substitutionNameString), null, compiler); 3348 new LiteralDartString(substitutionNameString), null, compiler);
3234 HInstruction target = localsHandler.readThis(); 3349 HInstruction target = localsHandler.readThis();
3235 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
3236 <HInstruction>[target, substitutionName]);
3237 add(substitution);
3238 pushInvokeStatic(null, 3350 pushInvokeStatic(null,
3239 backend.getGetRuntimeTypeArgument(), 3351 backend.getGetRuntimeTypeArgument(),
3240 [target, 3352 [target,
3241 substitution, 3353 substitutionName,
3242 graph.addConstantInt(index, compiler)], 3354 graph.addConstantInt(index, compiler)],
3243 HType.UNKNOWN); 3355 HType.UNKNOWN);
3244 return pop(); 3356 return pop();
3245 } 3357 }
3246 3358
3247 /** 3359 /**
3248 * Helper to create an instruction that gets the value of a type variable. 3360 * Helper to create an instruction that gets the value of a type variable.
3249 */ 3361 */
3250 HInstruction addTypeVariableReference(TypeVariableType type) { 3362 HInstruction addTypeVariableReference(TypeVariableType type) {
3251 Element member = currentElement; 3363 Element member = currentElement;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3313 }); 3425 });
3314 3426
3315 HInstruction result = createForeign(template, backend.stringType, inputs); 3427 HInstruction result = createForeign(template, backend.stringType, inputs);
3316 add(result); 3428 add(result);
3317 return result; 3429 return result;
3318 } 3430 }
3319 3431
3320 void handleListConstructor(InterfaceType type, 3432 void handleListConstructor(InterfaceType type,
3321 Node currentNode, 3433 Node currentNode,
3322 HInstruction newObject) { 3434 HInstruction newObject) {
3323 if (!backend.needsRti(type.element)) return; 3435 if (!backend.classNeedsRti(type.element)) return;
3324 if (!type.isRaw) { 3436 if (!type.isRaw) {
3325 List<HInstruction> inputs = <HInstruction>[]; 3437 List<HInstruction> inputs = <HInstruction>[];
3326 type.typeArguments.forEach((DartType argument) { 3438 type.typeArguments.forEach((DartType argument) {
3327 inputs.add(analyzeTypeArgument(argument, currentNode)); 3439 inputs.add(analyzeTypeArgument(argument, currentNode));
3328 }); 3440 });
3329 callSetRuntimeTypeInfo(type.element, inputs, newObject); 3441 callSetRuntimeTypeInfo(type.element, inputs, newObject);
3330 } 3442 }
3331 } 3443 }
3332 3444
3333 void callSetRuntimeTypeInfo(ClassElement element, 3445 void callSetRuntimeTypeInfo(ClassElement element,
3334 List<HInstruction> rtiInputs, 3446 List<HInstruction> rtiInputs,
3335 HInstruction newObject) { 3447 HInstruction newObject) {
3336 if (!backend.needsRti(element) || element.typeVariables.isEmpty) { 3448 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) {
3337 return; 3449 return;
3338 } 3450 }
3339 3451
3340 HInstruction typeInfo = buildLiteralList(rtiInputs); 3452 HInstruction typeInfo = buildLiteralList(rtiInputs);
3341 add(typeInfo); 3453 add(typeInfo);
3342 3454
3343 // Set the runtime type information on the object. 3455 // Set the runtime type information on the object.
3344 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); 3456 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo();
3345 pushInvokeStatic( 3457 pushInvokeStatic(
3346 null, 3458 null,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 if (!succeeded) { 3536 if (!succeeded) {
3425 generateWrongArgumentCountError(send, constructor, send.arguments); 3537 generateWrongArgumentCountError(send, constructor, send.arguments);
3426 return; 3538 return;
3427 } 3539 }
3428 3540
3429 ClassElement cls = constructor.getEnclosingClass(); 3541 ClassElement cls = constructor.getEnclosingClass();
3430 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) { 3542 if (cls.isAbstract(compiler) && constructor.isGenerativeConstructor()) {
3431 generateAbstractClassInstantiationError(send, cls.name.slowToString()); 3543 generateAbstractClassInstantiationError(send, cls.name.slowToString());
3432 return; 3544 return;
3433 } 3545 }
3434 if (backend.needsRti(cls)) { 3546 if (backend.classNeedsRti(cls)) {
3435 Link<DartType> typeVariable = cls.typeVariables; 3547 Link<DartType> typeVariable = cls.typeVariables;
3436 type.typeArguments.forEach((DartType argument) { 3548 type.typeArguments.forEach((DartType argument) {
3437 inputs.add(analyzeTypeArgument(argument, send)); 3549 inputs.add(analyzeTypeArgument(argument, send));
3438 typeVariable = typeVariable.tail; 3550 typeVariable = typeVariable.tail;
3439 }); 3551 });
3440 // Also add null to non-provided type variables to call the 3552 // Also add null to non-provided type variables to call the
3441 // constructor with the right number of arguments. 3553 // constructor with the right number of arguments.
3442 while (!typeVariable.isEmpty) { 3554 while (!typeVariable.isEmpty) {
3443 inputs.add(graph.addConstantNull(compiler)); 3555 inputs.add(graph.addConstantNull(compiler));
3444 typeVariable = typeVariable.tail; 3556 typeVariable = typeVariable.tail;
3445 } 3557 }
3446 } 3558 }
3447 3559
3448 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) { 3560 if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
3449 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); 3561 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
3450 } 3562 }
3451 HType elementType = computeType(constructor); 3563 HType elementType = computeType(constructor);
3452 pushInvokeStatic(node, constructor, inputs, elementType); 3564 pushInvokeStatic(node, constructor, inputs, elementType);
3453 HInstruction newInstance = stack.last; 3565 HInstruction newInstance = stack.last;
3454 3566
3455 // The List constructor forwards to a Dart static method that does 3567 // The List constructor forwards to a Dart static method that does
3456 // not know about the type argument. Therefore we special case 3568 // not know about the type argument. Therefore we special case
3457 // this constructor to have the setRuntimeTypeInfo called where 3569 // this constructor to have the setRuntimeTypeInfo called where
3458 // the 'new' is done. 3570 // the 'new' is done.
3459 if (isListConstructor && backend.needsRti(compiler.listClass)) { 3571 if (isListConstructor && backend.classNeedsRti(compiler.listClass)) {
3460 handleListConstructor(type, send, newInstance); 3572 handleListConstructor(type, send, newInstance);
3461 } 3573 }
3462 3574
3463 // Finally, if we called a redirecting factory constructor, check the type. 3575 // Finally, if we called a redirecting factory constructor, check the type.
3464 if (isRedirected) { 3576 if (isRedirected) {
3465 HInstruction checked = potentiallyCheckType(newInstance, expectedType); 3577 HInstruction checked = potentiallyCheckType(newInstance, expectedType);
3466 if (checked != newInstance) { 3578 if (checked != newInstance) {
3467 pop(); 3579 pop();
3468 stack.add(checked); 3580 stack.add(checked);
3469 } 3581 }
(...skipping 1933 matching lines...) Expand 10 before | Expand all | Expand 10 after
5403 new HSubGraphBlockInformation(elseBranch.graph)); 5515 new HSubGraphBlockInformation(elseBranch.graph));
5404 5516
5405 HBasicBlock conditionStartBlock = conditionBranch.block; 5517 HBasicBlock conditionStartBlock = conditionBranch.block;
5406 conditionStartBlock.setBlockFlow(info, joinBlock); 5518 conditionStartBlock.setBlockFlow(info, joinBlock);
5407 SubGraph conditionGraph = conditionBranch.graph; 5519 SubGraph conditionGraph = conditionBranch.graph;
5408 HIf branch = conditionGraph.end.last; 5520 HIf branch = conditionGraph.end.last;
5409 assert(branch is HIf); 5521 assert(branch is HIf);
5410 branch.blockInformation = conditionStartBlock.blockFlow; 5522 branch.blockInformation = conditionStartBlock.blockFlow;
5411 } 5523 }
5412 } 5524 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698