Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 void redirectElement(Element from, Element to) { | 172 void redirectElement(Element from, Element to) { |
| 173 assert(redirectionMapping[from] == null); | 173 assert(redirectionMapping[from] == null); |
| 174 redirectionMapping[from] = to; | 174 redirectionMapping[from] = to; |
| 175 assert(isStoredInClosureField(from) || isBoxed(from)); | 175 assert(isStoredInClosureField(from) || isBoxed(from)); |
| 176 } | 176 } |
| 177 | 177 |
| 178 HInstruction createBox() { | 178 HInstruction createBox() { |
| 179 // TODO(floitsch): Clean up this hack. Should we create a box-object by | 179 // TODO(floitsch): Clean up this hack. Should we create a box-object by |
| 180 // just creating an empty object literal? | 180 // just creating an empty object literal? |
| 181 HInstruction box = new HForeign(const LiteralDartString("{}"), | 181 HInstruction box = new HForeign(const LiteralDartString("{}"), |
| 182 const LiteralDartString('Object'), | 182 HType.UNKNOWN, |
| 183 <HInstruction>[]); | 183 <HInstruction>[]); |
| 184 builder.add(box); | 184 builder.add(box); |
| 185 return box; | 185 return box; |
| 186 } | 186 } |
| 187 | 187 |
| 188 /** | 188 /** |
| 189 * If the scope (function or loop) [node] has captured variables then this | 189 * If the scope (function or loop) [node] has captured variables then this |
| 190 * method creates a box and sets up the redirections. | 190 * method creates a box and sets up the redirections. |
| 191 */ | 191 */ |
| 192 void enterScope(Node node, Element element) { | 192 void enterScope(Node node, Element element) { |
| (...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1319 // Call the JavaScript constructor with the fields as argument. | 1319 // Call the JavaScript constructor with the fields as argument. |
| 1320 List<HInstruction> constructorArguments = <HInstruction>[]; | 1320 List<HInstruction> constructorArguments = <HInstruction>[]; |
| 1321 classElement.forEachInstanceField( | 1321 classElement.forEachInstanceField( |
| 1322 (ClassElement enclosingClass, Element member) { | 1322 (ClassElement enclosingClass, Element member) { |
| 1323 constructorArguments.add(potentiallyCheckType( | 1323 constructorArguments.add(potentiallyCheckType( |
| 1324 fieldValues[member], member.computeType(compiler))); | 1324 fieldValues[member], member.computeType(compiler))); |
| 1325 }, | 1325 }, |
| 1326 includeBackendMembers: true, | 1326 includeBackendMembers: true, |
| 1327 includeSuperMembers: true); | 1327 includeSuperMembers: true); |
| 1328 | 1328 |
| 1329 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); | 1329 InterfaceType type = classElement.computeType(compiler); |
| 1330 HType ssaType = new HBoundedType.exact(type); | |
|
kasperl
2013/02/04 09:27:50
This is fairly common. Maybe have an HBoundedType
ngeoffray
2013/02/04 10:45:06
Good point. There are too many constructors in HBo
| |
| 1331 HForeignNew newObject = new HForeignNew(classElement, | |
| 1332 ssaType, | |
| 1333 constructorArguments); | |
| 1330 add(newObject); | 1334 add(newObject); |
| 1331 | 1335 |
| 1332 // Create the runtime type information, if needed. | 1336 // Create the runtime type information, if needed. |
| 1333 InterfaceType type = classElement.computeType(compiler); | |
| 1334 List<HInstruction> inputs = <HInstruction>[]; | 1337 List<HInstruction> inputs = <HInstruction>[]; |
| 1335 if (compiler.world.needsRti(classElement)) { | 1338 if (compiler.world.needsRti(classElement)) { |
| 1336 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 1339 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1337 inputs.add(localsHandler.directLocals[typeVariable.element]); | 1340 inputs.add(localsHandler.directLocals[typeVariable.element]); |
| 1338 }); | 1341 }); |
| 1339 callSetRuntimeTypeInfo(classElement, inputs, newObject); | 1342 callSetRuntimeTypeInfo(classElement, inputs, newObject); |
| 1340 } | 1343 } |
| 1341 | 1344 |
| 1342 // Generate calls to the constructor bodies. | 1345 // Generate calls to the constructor bodies. |
| 1343 for (int index = constructors.length - 1; index >= 0; index--) { | 1346 for (int index = constructors.length - 1; index >= 0; index--) { |
| (...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2106 closureClassElement.forEachBackendMember((Element member) { | 2109 closureClassElement.forEachBackendMember((Element member) { |
| 2107 // The backendMembers also contains the call method(s). We are only | 2110 // The backendMembers also contains the call method(s). We are only |
| 2108 // interested in the fields. | 2111 // interested in the fields. |
| 2109 if (member.isField()) { | 2112 if (member.isField()) { |
| 2110 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 2113 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
| 2111 assert(capturedLocal != null); | 2114 assert(capturedLocal != null); |
| 2112 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2115 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 2113 } | 2116 } |
| 2114 }); | 2117 }); |
| 2115 | 2118 |
| 2116 push(new HForeignNew(closureClassElement, capturedVariables)); | 2119 HType type = new HBoundedType.exact( |
| 2120 compiler.functionClass.computeType(compiler)); | |
| 2121 push(new HForeignNew(closureClassElement, type, capturedVariables)); | |
| 2117 } | 2122 } |
| 2118 | 2123 |
| 2119 visitFunctionDeclaration(FunctionDeclaration node) { | 2124 visitFunctionDeclaration(FunctionDeclaration node) { |
| 2120 visit(node.function); | 2125 visit(node.function); |
| 2121 localsHandler.updateLocal(elements[node], pop()); | 2126 localsHandler.updateLocal(elements[node], pop()); |
| 2122 } | 2127 } |
| 2123 | 2128 |
| 2124 visitIdentifier(Identifier node) { | 2129 visitIdentifier(Identifier node) { |
| 2125 if (node.isThis()) { | 2130 if (node.isThis()) { |
| 2126 stack.add(localsHandler.readThis()); | 2131 stack.add(localsHandler.readThis()); |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2500 | 2505 |
| 2501 void pushInvokeHelper5(Element helper, HInstruction a0, HInstruction a1, | 2506 void pushInvokeHelper5(Element helper, HInstruction a0, HInstruction a1, |
| 2502 HInstruction a2, HInstruction a3, HInstruction a4) { | 2507 HInstruction a2, HInstruction a3, HInstruction a4) { |
| 2503 HInstruction reference = new HStatic(helper); | 2508 HInstruction reference = new HStatic(helper); |
| 2504 add(reference); | 2509 add(reference); |
| 2505 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; | 2510 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; |
| 2506 HInstruction result = new HInvokeStatic(inputs); | 2511 HInstruction result = new HInvokeStatic(inputs); |
| 2507 push(result); | 2512 push(result); |
| 2508 } | 2513 } |
| 2509 | 2514 |
| 2510 HForeign createForeign(String code, String type, List<HInstruction> inputs) { | 2515 HForeign createForeign(String code, HType type, List<HInstruction> inputs) { |
| 2511 return new HForeign(new LiteralDartString(code), | 2516 return new HForeign(new LiteralDartString(code), type, inputs); |
| 2512 new LiteralDartString(type), | |
| 2513 inputs); | |
| 2514 } | 2517 } |
| 2515 | 2518 |
| 2516 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2519 HInstruction getRuntimeTypeInfo(HInstruction target) { |
| 2517 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target); | 2520 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target); |
| 2518 return pop(); | 2521 return pop(); |
| 2519 } | 2522 } |
| 2520 | 2523 |
| 2521 // TODO(karlklose): change construction of the representations to be GVN'able | 2524 // TODO(karlklose): change construction of the representations to be GVN'able |
| 2522 // (dartbug.com/7182). | 2525 // (dartbug.com/7182). |
| 2523 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { | 2526 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { |
| 2524 HInstruction createForeignArray(String code, inputs) { | 2527 HInstruction createForeignArray(String code, inputs) { |
| 2525 return createForeign(code, '=List', inputs); | 2528 return createForeign(code, HType.READABLE_ARRAY, inputs); |
| 2526 } | 2529 } |
| 2527 HInstruction typeInfo; | 2530 HInstruction typeInfo; |
| 2528 | 2531 |
| 2529 /// Helper to create an instruction that contains the runtime value of | 2532 /// Helper to create an instruction that contains the runtime value of |
| 2530 /// the type variable [variable]. | 2533 /// the type variable [variable]. |
| 2531 HInstruction getTypeArgument(TypeVariableType variable) { | 2534 HInstruction getTypeArgument(TypeVariableType variable) { |
| 2532 if (typeInfo == null) { | 2535 if (typeInfo == null) { |
| 2533 typeInfo = getRuntimeTypeInfo(localsHandler.readThis()); | 2536 typeInfo = getRuntimeTypeInfo(localsHandler.readThis()); |
| 2534 } | 2537 } |
| 2535 int intIndex = RuntimeTypeInformation.getTypeVariableIndex(variable); | 2538 int intIndex = RuntimeTypeInformation.getTypeVariableIndex(variable); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2615 buildTypeArgumentRepresentations(type); | 2618 buildTypeArgumentRepresentations(type); |
| 2616 // For each type argument, build a call to isSubtype, with the type | 2619 // For each type argument, build a call to isSubtype, with the type |
| 2617 // argument as first and the representation of the tested type as | 2620 // argument as first and the representation of the tested type as |
| 2618 // second argument. | 2621 // second argument. |
| 2619 List<HInstruction> checks = <HInstruction>[]; | 2622 List<HInstruction> checks = <HInstruction>[]; |
| 2620 int index = 0; | 2623 int index = 0; |
| 2621 representations.forEach((HInstruction representation) { | 2624 representations.forEach((HInstruction representation) { |
| 2622 HInstruction position = graph.addConstantInt(index, constantSystem); | 2625 HInstruction position = graph.addConstantInt(index, constantSystem); |
| 2623 // Get the index'th type argument from the runtime type information. | 2626 // Get the index'th type argument from the runtime type information. |
| 2624 HInstruction typeArgument = | 2627 HInstruction typeArgument = |
| 2625 createForeign('#[#]', 'Object', [typeInfo, position]); | 2628 createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]); |
| 2626 add(typeArgument); | 2629 add(typeArgument); |
| 2627 // Create the call to isSubtype. | 2630 // Create the call to isSubtype. |
| 2628 List<HInstruction> inputs = | 2631 List<HInstruction> inputs = |
| 2629 <HInstruction>[isSubtype, typeArgument, representation]; | 2632 <HInstruction>[isSubtype, typeArgument, representation]; |
| 2630 HInstruction call = new HInvokeStatic(inputs); | 2633 HInstruction call = new HInvokeStatic(inputs); |
| 2631 add(call); | 2634 add(call); |
| 2632 checks.add(call); | 2635 checks.add(call); |
| 2633 index++; | 2636 index++; |
| 2634 }); | 2637 }); |
| 2635 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); | 2638 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2813 assert(Elements.isLocal(element)); | 2816 assert(Elements.isLocal(element)); |
| 2814 closureTarget = localsHandler.readLocal(element); | 2817 closureTarget = localsHandler.readLocal(element); |
| 2815 } | 2818 } |
| 2816 var inputs = <HInstruction>[]; | 2819 var inputs = <HInstruction>[]; |
| 2817 inputs.add(closureTarget); | 2820 inputs.add(closureTarget); |
| 2818 addDynamicSendArgumentsToList(node, inputs); | 2821 addDynamicSendArgumentsToList(node, inputs); |
| 2819 Selector closureSelector = new Selector.callClosureFrom(selector); | 2822 Selector closureSelector = new Selector.callClosureFrom(selector); |
| 2820 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); | 2823 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); |
| 2821 } | 2824 } |
| 2822 | 2825 |
| 2823 void registerForeignTypes(String specString) { | |
| 2824 CodegenEnqueuer enqueuer = compiler.enqueuer.codegen; | |
| 2825 for (final typeString in specString.split('|')) { | |
| 2826 if (typeString == '=List') { | |
| 2827 enqueuer.registerInstantiatedClass(compiler.listClass); | |
| 2828 } else if (typeString == 'int') { | |
| 2829 enqueuer.registerInstantiatedClass(compiler.intClass); | |
| 2830 } else if (typeString == 'double') { | |
| 2831 enqueuer.registerInstantiatedClass(compiler.doubleClass); | |
| 2832 } else if (typeString == 'num') { | |
| 2833 enqueuer.registerInstantiatedClass(compiler.intClass); | |
| 2834 enqueuer.registerInstantiatedClass(compiler.doubleClass); | |
| 2835 } else if (typeString == 'Null') { | |
| 2836 enqueuer.registerInstantiatedClass(compiler.nullClass); | |
| 2837 } else if (typeString == 'String') { | |
| 2838 enqueuer.registerInstantiatedClass(compiler.stringClass); | |
| 2839 } | |
| 2840 } | |
| 2841 } | |
| 2842 | |
| 2843 void handleForeignJs(Send node) { | 2826 void handleForeignJs(Send node) { |
| 2844 Link<Node> link = node.arguments; | 2827 Link<Node> link = node.arguments; |
| 2845 // If the invoke is on foreign code, don't visit the first | 2828 // If the invoke is on foreign code, don't visit the first |
| 2846 // argument, which is the type, and the second argument, | 2829 // argument, which is the type, and the second argument, |
| 2847 // which is the foreign code. | 2830 // which is the foreign code. |
| 2848 if (link.isEmpty || link.tail.isEmpty) { | 2831 if (link.isEmpty || link.tail.isEmpty) { |
| 2849 compiler.cancel('At least two arguments expected', | 2832 compiler.cancel('At least two arguments expected', |
| 2850 node: node.argumentsNode); | 2833 node: node.argumentsNode); |
| 2851 } | 2834 } |
| 2852 List<HInstruction> inputs = <HInstruction>[]; | 2835 List<HInstruction> inputs = <HInstruction>[]; |
| 2853 Node type = link.head; | 2836 Node type = link.head; |
| 2854 Node code = link.tail.head; | 2837 Node code = link.tail.head; |
| 2855 addGenericSendArgumentsToList(link.tail.tail, inputs); | 2838 addGenericSendArgumentsToList(link.tail.tail, inputs); |
| 2856 | 2839 |
| 2857 if (type is !LiteralString) { | 2840 native.NativeBehavior nativeBehavior = |
| 2858 // The type must not be a juxtaposition or interpolation. | 2841 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
| 2859 compiler.cancel('The type of a JS expression must be a string literal', | 2842 HType ssaType = mapNativeBehaviorType(nativeBehavior); |
| 2860 node: type); | 2843 print('$node for $ssaType'); |
|
kasperl
2013/02/04 09:27:50
Remove printing.
ngeoffray
2013/02/04 10:45:06
Done.
| |
| 2861 } | |
| 2862 LiteralString typeString = type; | |
| 2863 // TODO(ngeoffray): This should be registered in codegen, not here. | |
| 2864 // Also, we should share the type parsing with the native | |
| 2865 // enqueuer. | |
| 2866 registerForeignTypes(typeString.dartString.slowToString()); | |
| 2867 | |
| 2868 if (code is StringNode) { | 2844 if (code is StringNode) { |
| 2869 StringNode codeString = code; | 2845 StringNode codeString = code; |
| 2870 if (!codeString.isInterpolation) { | 2846 if (!codeString.isInterpolation) { |
| 2871 // codeString may not be an interpolation, but may be a juxtaposition. | 2847 // codeString may not be an interpolation, but may be a juxtaposition. |
| 2872 push(new HForeign(codeString.dartString, | 2848 push(new HForeign(codeString.dartString, ssaType, inputs)); |
| 2873 typeString.dartString, | |
| 2874 inputs)); | |
| 2875 return; | 2849 return; |
| 2876 } | 2850 } |
| 2877 } | 2851 } |
| 2878 compiler.cancel('JS code must be a string literal', node: code); | 2852 compiler.cancel('JS code must be a string literal', node: code); |
| 2879 } | 2853 } |
| 2880 | 2854 |
| 2881 void handleForeignJsCurrentIsolate(Send node) { | 2855 void handleForeignJsCurrentIsolate(Send node) { |
| 2882 if (!node.arguments.isEmpty) { | 2856 if (!node.arguments.isEmpty) { |
| 2883 compiler.cancel( | 2857 compiler.cancel( |
| 2884 'Too many arguments to JS_CURRENT_ISOLATE', node: node); | 2858 'Too many arguments to JS_CURRENT_ISOLATE', node: node); |
| 2885 } | 2859 } |
| 2886 | 2860 |
| 2887 if (!compiler.hasIsolateSupport()) { | 2861 if (!compiler.hasIsolateSupport()) { |
| 2888 // If the isolate library is not used, we just generate code | 2862 // If the isolate library is not used, we just generate code |
| 2889 // to fetch the Leg's current isolate. | 2863 // to fetch the Leg's current isolate. |
| 2890 String name = backend.namer.CURRENT_ISOLATE; | 2864 String name = backend.namer.CURRENT_ISOLATE; |
| 2891 push(new HForeign(new DartString.literal(name), | 2865 push(new HForeign(new DartString.literal(name), |
| 2892 const LiteralDartString('var'), | 2866 HType.UNKNOWN, |
| 2893 <HInstruction>[])); | 2867 <HInstruction>[])); |
| 2894 } else { | 2868 } else { |
| 2895 // Call a helper method from the isolate library. The isolate | 2869 // Call a helper method from the isolate library. The isolate |
| 2896 // library uses its own isolate structure, that encapsulates | 2870 // library uses its own isolate structure, that encapsulates |
| 2897 // Leg's isolate. | 2871 // Leg's isolate. |
| 2898 Element element = compiler.isolateHelperLibrary.find( | 2872 Element element = compiler.isolateHelperLibrary.find( |
| 2899 const SourceString('_currentIsolate')); | 2873 const SourceString('_currentIsolate')); |
| 2900 if (element == null) { | 2874 if (element == null) { |
| 2901 compiler.cancel( | 2875 compiler.cancel( |
| 2902 'Isolate library and compiler mismatch', node: node); | 2876 'Isolate library and compiler mismatch', node: node); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2955 visit(closure); | 2929 visit(closure); |
| 2956 return params; | 2930 return params; |
| 2957 } | 2931 } |
| 2958 | 2932 |
| 2959 void handleForeignDartClosureToJs(Send node, String name) { | 2933 void handleForeignDartClosureToJs(Send node, String name) { |
| 2960 FunctionSignature params = handleForeignRawFunctionRef(node, name); | 2934 FunctionSignature params = handleForeignRawFunctionRef(node, name); |
| 2961 List<HInstruction> inputs = <HInstruction>[pop()]; | 2935 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 2962 String invocationName = backend.namer.invocationName( | 2936 String invocationName = backend.namer.invocationName( |
| 2963 new Selector.callClosure(params.requiredParameterCount)); | 2937 new Selector.callClosure(params.requiredParameterCount)); |
| 2964 push(new HForeign(new DartString.literal('#.$invocationName'), | 2938 push(new HForeign(new DartString.literal('#.$invocationName'), |
| 2965 const LiteralDartString('var'), | 2939 HType.UNKNOWN, |
| 2966 inputs)); | 2940 inputs)); |
| 2967 } | 2941 } |
| 2968 | 2942 |
| 2969 void handleForeignSetCurrentIsolate(Send node) { | 2943 void handleForeignSetCurrentIsolate(Send node) { |
| 2970 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { | 2944 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { |
| 2971 compiler.cancel('Exactly one argument required', | 2945 compiler.cancel('Exactly one argument required', |
| 2972 node: node.argumentsNode); | 2946 node: node.argumentsNode); |
| 2973 } | 2947 } |
| 2974 visit(node.arguments.head); | 2948 visit(node.arguments.head); |
| 2975 String isolateName = backend.namer.CURRENT_ISOLATE; | 2949 String isolateName = backend.namer.CURRENT_ISOLATE; |
| 2976 push(new HForeign(new DartString.literal("$isolateName = #"), | 2950 push(new HForeign(new DartString.literal("$isolateName = #"), |
| 2977 const LiteralDartString('void'), | 2951 HType.UNKNOWN, |
| 2978 <HInstruction>[pop()])); | 2952 <HInstruction>[pop()])); |
| 2979 } | 2953 } |
| 2980 | 2954 |
| 2981 void handleForeignCreateIsolate(Send node) { | 2955 void handleForeignCreateIsolate(Send node) { |
| 2982 if (!node.arguments.isEmpty) { | 2956 if (!node.arguments.isEmpty) { |
| 2983 compiler.cancel('Too many arguments', | 2957 compiler.cancel('Too many arguments', |
| 2984 node: node.argumentsNode); | 2958 node: node.argumentsNode); |
| 2985 } | 2959 } |
| 2986 String constructorName = backend.namer.isolateName; | 2960 String constructorName = backend.namer.isolateName; |
| 2987 push(new HForeign(new DartString.literal("new $constructorName"), | 2961 push(new HForeign(new DartString.literal("new $constructorName"), |
| 2988 const LiteralDartString('var'), | 2962 HType.UNKNOWN, |
| 2989 <HInstruction>[])); | 2963 <HInstruction>[])); |
| 2990 } | 2964 } |
| 2991 | 2965 |
| 2992 visitForeignSend(Send node) { | 2966 visitForeignSend(Send node) { |
| 2993 Selector selector = elements.getSelector(node); | 2967 Selector selector = elements.getSelector(node); |
| 2994 SourceString name = selector.name; | 2968 SourceString name = selector.name; |
| 2995 if (name == const SourceString('JS')) { | 2969 if (name == const SourceString('JS')) { |
| 2996 handleForeignJs(node); | 2970 handleForeignJs(node); |
| 2997 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { | 2971 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { |
| 2998 handleForeignJsCurrentIsolate(node); | 2972 handleForeignJsCurrentIsolate(node); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3145 inputs.add(localsHandler.readLocal(type.element)); | 3119 inputs.add(localsHandler.readLocal(type.element)); |
| 3146 } else if (member.isInstanceMember() | 3120 } else if (member.isInstanceMember() |
| 3147 || member.isGenerativeConstructor()) { | 3121 || member.isGenerativeConstructor()) { |
| 3148 // The type variable is stored in [this]. | 3122 // The type variable is stored in [this]. |
| 3149 if (typeInfo == null) { | 3123 if (typeInfo == null) { |
| 3150 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), | 3124 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), |
| 3151 localsHandler.readThis()); | 3125 localsHandler.readThis()); |
| 3152 typeInfo = pop(); | 3126 typeInfo = pop(); |
| 3153 } | 3127 } |
| 3154 int index = RuntimeTypeInformation.getTypeVariableIndex(type); | 3128 int index = RuntimeTypeInformation.getTypeVariableIndex(type); |
| 3155 HInstruction foreign = createForeign('#[$index]', 'String', | 3129 HInstruction foreign = createForeign('#[$index]', HType.STRING, |
| 3156 <HInstruction>[typeInfo]); | 3130 <HInstruction>[typeInfo]); |
| 3157 add(foreign); | 3131 add(foreign); |
| 3158 inputs.add(foreign); | 3132 inputs.add(foreign); |
| 3159 } else { | 3133 } else { |
| 3160 // TODO(ngeoffray): Match the VM behavior and throw an | 3134 // TODO(ngeoffray): Match the VM behavior and throw an |
| 3161 // exception at runtime. | 3135 // exception at runtime. |
| 3162 compiler.cancel('Unimplemented unresolved type variable', | 3136 compiler.cancel('Unimplemented unresolved type variable', |
| 3163 node: currentNode); | 3137 node: currentNode); |
| 3164 } | 3138 } |
| 3165 } | 3139 } |
| 3166 | 3140 |
| 3167 String template = rti.getTypeRepresentation(argument, | 3141 String template = rti.getTypeRepresentation(argument, |
| 3168 addTypeVariableReference); | 3142 addTypeVariableReference); |
| 3169 HInstruction result = createForeign(template, 'String', inputs); | 3143 HInstruction result = createForeign(template, HType.STRING, inputs); |
| 3170 add(result); | 3144 add(result); |
| 3171 return result; | 3145 return result; |
| 3172 } | 3146 } |
| 3173 | 3147 |
| 3174 void handleListConstructor(InterfaceType type, | 3148 void handleListConstructor(InterfaceType type, |
| 3175 Node currentNode, | 3149 Node currentNode, |
| 3176 HInstruction newObject) { | 3150 HInstruction newObject) { |
| 3177 if (!compiler.world.needsRti(type.element)) return; | 3151 if (!compiler.world.needsRti(type.element)) return; |
| 3178 List<HInstruction> inputs = <HInstruction>[]; | 3152 List<HInstruction> inputs = <HInstruction>[]; |
| 3179 if (!type.isRaw) { | 3153 if (!type.isRaw) { |
| (...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4558 } | 4532 } |
| 4559 | 4533 |
| 4560 visitTypedef(Typedef node) { | 4534 visitTypedef(Typedef node) { |
| 4561 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 4535 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 4562 } | 4536 } |
| 4563 | 4537 |
| 4564 visitTypeVariable(TypeVariable node) { | 4538 visitTypeVariable(TypeVariable node) { |
| 4565 compiler.internalError('SsaBuilder.visitTypeVariable'); | 4539 compiler.internalError('SsaBuilder.visitTypeVariable'); |
| 4566 } | 4540 } |
| 4567 | 4541 |
| 4542 HType mapBaseType(BaseType baseType) { | |
| 4543 if (!baseType.isClass()) return HType.UNKNOWN; | |
| 4544 ClassBaseType classBaseType = baseType; | |
|
kasperl
2013/02/04 09:27:50
Unused local variable.
ngeoffray
2013/02/04 10:45:06
Done.
| |
| 4545 return new HType.fromBoundedType( | |
| 4546 baseType.element.computeType(compiler), compiler, false); | |
| 4547 } | |
| 4548 | |
| 4568 HType mapInferredType(ConcreteType concreteType) { | 4549 HType mapInferredType(ConcreteType concreteType) { |
| 4569 if (concreteType == null) return HType.UNKNOWN; | 4550 if (concreteType == null) return HType.UNKNOWN; |
| 4570 ClassElement element = concreteType.getUniqueType(); | 4551 HType ssaType = HType.CONFLICTING; |
| 4571 if (element == null) return HType.UNKNOWN; | 4552 for (BaseType baseType in concreteType.baseTypes) { |
| 4572 if (element == builder.compiler.boolClass) return HType.BOOLEAN; | 4553 ssaType = ssaType.union(mapBaseType(baseType), compiler); |
| 4573 if (element == builder.compiler.doubleClass) return HType.DOUBLE; | 4554 } |
| 4574 if (element == builder.compiler.intClass) return HType.INTEGER; | 4555 assert(!ssaType.isConflicting()); |
| 4575 if (element == builder.compiler.listClass) return HType.READABLE_ARRAY; | 4556 return ssaType; |
| 4576 if (element == builder.compiler.nullClass) return HType.NULL; | 4557 } |
| 4577 if (element == builder.compiler.stringClass) return HType.STRING; | 4558 |
| 4578 return HType.UNKNOWN; | 4559 HType mapNativeType(type) { |
| 4560 if (type == native.SpecialType.JsObject) { | |
| 4561 return new HBoundedType.exact( | |
| 4562 compiler.objectClass.computeType(compiler)); | |
| 4563 } else if (type == native.SpecialType.JsArray) { | |
| 4564 return HType.READABLE_ARRAY; | |
| 4565 } else { | |
| 4566 return new HType.fromBoundedType(type, compiler, false); | |
| 4567 } | |
| 4568 } | |
| 4569 | |
| 4570 HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) { | |
| 4571 if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN; | |
| 4572 | |
| 4573 HType ssaType = HType.CONFLICTING; | |
| 4574 for (final type in nativeBehavior.typesInstantiated) { | |
| 4575 ssaType = ssaType.union(mapNativeType(type), compiler); | |
| 4576 } | |
| 4577 assert(!ssaType.isConflicting()); | |
| 4578 return ssaType; | |
| 4579 } | 4579 } |
| 4580 } | 4580 } |
| 4581 | 4581 |
| 4582 /** | 4582 /** |
| 4583 * Visitor that handles generation of string literals (LiteralString, | 4583 * Visitor that handles generation of string literals (LiteralString, |
| 4584 * StringInterpolation), and otherwise delegates to the given visitor for | 4584 * StringInterpolation), and otherwise delegates to the given visitor for |
| 4585 * non-literal subexpressions. | 4585 * non-literal subexpressions. |
| 4586 * TODO(lrn): Consider whether to handle compile time constant int/boolean | 4586 * TODO(lrn): Consider whether to handle compile time constant int/boolean |
| 4587 * expressions as well. | 4587 * expressions as well. |
| 4588 */ | 4588 */ |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4954 new HSubGraphBlockInformation(elseBranch.graph)); | 4954 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4955 | 4955 |
| 4956 HBasicBlock conditionStartBlock = conditionBranch.block; | 4956 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4957 conditionStartBlock.setBlockFlow(info, joinBlock); | 4957 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4958 SubGraph conditionGraph = conditionBranch.graph; | 4958 SubGraph conditionGraph = conditionBranch.graph; |
| 4959 HIf branch = conditionGraph.end.last; | 4959 HIf branch = conditionGraph.end.last; |
| 4960 assert(branch is HIf); | 4960 assert(branch is HIf); |
| 4961 branch.blockInformation = conditionStartBlock.blockFlow; | 4961 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4962 } | 4962 } |
| 4963 } | 4963 } |
| OLD | NEW |