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

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

Issue 12095011: Properly register types on the JS foreign instruction. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 // Call the JavaScript constructor with the fields as argument. 1318 // Call the JavaScript constructor with the fields as argument.
1319 List<HInstruction> constructorArguments = <HInstruction>[]; 1319 List<HInstruction> constructorArguments = <HInstruction>[];
1320 classElement.forEachInstanceField( 1320 classElement.forEachInstanceField(
1321 (ClassElement enclosingClass, Element member) { 1321 (ClassElement enclosingClass, Element member) {
1322 constructorArguments.add(potentiallyCheckType( 1322 constructorArguments.add(potentiallyCheckType(
1323 fieldValues[member], member.computeType(compiler))); 1323 fieldValues[member], member.computeType(compiler)));
1324 }, 1324 },
1325 includeBackendMembers: true, 1325 includeBackendMembers: true,
1326 includeSuperMembers: true); 1326 includeSuperMembers: true);
1327 1327
1328 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 1328 InterfaceType type = classElement.computeType(compiler);
1329 HType ssaType = new HBoundedType.exact(type);
ahe 2013/01/28 15:14:31 Why is this not a DartType?
ngeoffray 2013/01/28 15:34:19 Because the SSA graph works on HType, not DartType
1330 HForeignNew newObject = new HForeignNew(classElement,
1331 ssaType,
1332 constructorArguments);
1329 add(newObject); 1333 add(newObject);
1330 1334
1331 // Create the runtime type information, if needed. 1335 // Create the runtime type information, if needed.
1332 InterfaceType type = classElement.computeType(compiler);
1333 List<HInstruction> inputs = <HInstruction>[]; 1336 List<HInstruction> inputs = <HInstruction>[];
1334 if (compiler.world.needsRti(classElement)) { 1337 if (compiler.world.needsRti(classElement)) {
1335 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1338 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1336 inputs.add(localsHandler.directLocals[typeVariable.element]); 1339 inputs.add(localsHandler.directLocals[typeVariable.element]);
1337 }); 1340 });
1338 callSetRuntimeTypeInfo(classElement, inputs, newObject); 1341 callSetRuntimeTypeInfo(classElement, inputs, newObject);
1339 } 1342 }
1340 1343
1341 // Generate calls to the constructor bodies. 1344 // Generate calls to the constructor bodies.
1342 for (int index = constructors.length - 1; index >= 0; index--) { 1345 for (int index = constructors.length - 1; index >= 0; index--) {
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 closureClassElement.forEachBackendMember((Element member) { 2106 closureClassElement.forEachBackendMember((Element member) {
2104 // The backendMembers also contains the call method(s). We are only 2107 // The backendMembers also contains the call method(s). We are only
2105 // interested in the fields. 2108 // interested in the fields.
2106 if (member.isField()) { 2109 if (member.isField()) {
2107 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2110 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2108 assert(capturedLocal != null); 2111 assert(capturedLocal != null);
2109 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2112 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2110 } 2113 }
2111 }); 2114 });
2112 2115
2113 push(new HForeignNew(closureClassElement, capturedVariables)); 2116 HType type = new HBoundedType.exact(
2117 compiler.functionClass.computeType(compiler));
2118 push(new HForeignNew(closureClassElement, type, capturedVariables));
2114 } 2119 }
2115 2120
2116 visitFunctionDeclaration(FunctionDeclaration node) { 2121 visitFunctionDeclaration(FunctionDeclaration node) {
2117 visit(node.function); 2122 visit(node.function);
2118 localsHandler.updateLocal(elements[node], pop()); 2123 localsHandler.updateLocal(elements[node], pop());
2119 } 2124 }
2120 2125
2121 visitIdentifier(Identifier node) { 2126 visitIdentifier(Identifier node) {
2122 if (node.isThis()) { 2127 if (node.isThis()) {
2123 stack.add(localsHandler.readThis()); 2128 stack.add(localsHandler.readThis());
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 2502
2498 void pushInvokeHelper5(Element helper, HInstruction a0, HInstruction a1, 2503 void pushInvokeHelper5(Element helper, HInstruction a0, HInstruction a1,
2499 HInstruction a2, HInstruction a3, HInstruction a4) { 2504 HInstruction a2, HInstruction a3, HInstruction a4) {
2500 HInstruction reference = new HStatic(helper); 2505 HInstruction reference = new HStatic(helper);
2501 add(reference); 2506 add(reference);
2502 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4]; 2507 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4];
2503 HInstruction result = new HInvokeStatic(inputs); 2508 HInstruction result = new HInvokeStatic(inputs);
2504 push(result); 2509 push(result);
2505 } 2510 }
2506 2511
2507 HForeign createForeign(String code, String type, List<HInstruction> inputs) { 2512 HForeign createForeign(String code, HType type, List<HInstruction> inputs) {
2508 return new HForeign(new LiteralDartString(code), 2513 return new HForeign(new LiteralDartString(code), type, inputs);
2509 new LiteralDartString(type),
2510 inputs);
2511 } 2514 }
2512 2515
2513 HInstruction getRuntimeTypeInfo(HInstruction target) { 2516 HInstruction getRuntimeTypeInfo(HInstruction target) {
2514 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target); 2517 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target);
2515 return pop(); 2518 return pop();
2516 } 2519 }
2517 2520
2518 // TODO(karlklose): change construction of the representations to be GVN'able 2521 // TODO(karlklose): change construction of the representations to be GVN'able
2519 // (dartbug.com/7182). 2522 // (dartbug.com/7182).
2520 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { 2523 List<HInstruction> buildTypeArgumentRepresentations(DartType type) {
2521 HInstruction createForeignArray(String code, inputs) { 2524 HInstruction createForeignArray(String code, inputs) {
2522 return createForeign(code, '=List', inputs); 2525 return createForeign(code, HType.READABLE_ARRAY, inputs);
2523 } 2526 }
2524 HInstruction typeInfo; 2527 HInstruction typeInfo;
2525 2528
2526 /// Helper to create an instruction that contains the runtime value of 2529 /// Helper to create an instruction that contains the runtime value of
2527 /// the type variable [variable]. 2530 /// the type variable [variable].
2528 HInstruction getTypeArgument(TypeVariableType variable) { 2531 HInstruction getTypeArgument(TypeVariableType variable) {
2529 if (typeInfo == null) { 2532 if (typeInfo == null) {
2530 typeInfo = getRuntimeTypeInfo(localsHandler.readThis()); 2533 typeInfo = getRuntimeTypeInfo(localsHandler.readThis());
2531 } 2534 }
2532 int intIndex = RuntimeTypeInformation.getTypeVariableIndex(variable); 2535 int intIndex = RuntimeTypeInformation.getTypeVariableIndex(variable);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 buildTypeArgumentRepresentations(type); 2615 buildTypeArgumentRepresentations(type);
2613 // For each type argument, build a call to isSubtype, with the type 2616 // For each type argument, build a call to isSubtype, with the type
2614 // argument as first and the representation of the tested type as 2617 // argument as first and the representation of the tested type as
2615 // second argument. 2618 // second argument.
2616 List<HInstruction> checks = <HInstruction>[]; 2619 List<HInstruction> checks = <HInstruction>[];
2617 int index = 0; 2620 int index = 0;
2618 representations.forEach((HInstruction representation) { 2621 representations.forEach((HInstruction representation) {
2619 HInstruction position = graph.addConstantInt(index, constantSystem); 2622 HInstruction position = graph.addConstantInt(index, constantSystem);
2620 // Get the index'th type argument from the runtime type information. 2623 // Get the index'th type argument from the runtime type information.
2621 HInstruction typeArgument = 2624 HInstruction typeArgument =
2622 createForeign('#[#]', 'Object', [typeInfo, position]); 2625 createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]);
2623 add(typeArgument); 2626 add(typeArgument);
2624 // Create the call to isSubtype. 2627 // Create the call to isSubtype.
2625 List<HInstruction> inputs = 2628 List<HInstruction> inputs =
2626 <HInstruction>[isSubtype, typeArgument, representation]; 2629 <HInstruction>[isSubtype, typeArgument, representation];
2627 HInstruction call = new HInvokeStatic(inputs); 2630 HInstruction call = new HInvokeStatic(inputs);
2628 add(call); 2631 add(call);
2629 checks.add(call); 2632 checks.add(call);
2630 index++; 2633 index++;
2631 }); 2634 });
2632 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks)); 2635 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks));
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2810 assert(Elements.isLocal(element)); 2813 assert(Elements.isLocal(element));
2811 closureTarget = localsHandler.readLocal(element); 2814 closureTarget = localsHandler.readLocal(element);
2812 } 2815 }
2813 var inputs = <HInstruction>[]; 2816 var inputs = <HInstruction>[];
2814 inputs.add(closureTarget); 2817 inputs.add(closureTarget);
2815 addDynamicSendArgumentsToList(node, inputs); 2818 addDynamicSendArgumentsToList(node, inputs);
2816 Selector closureSelector = new Selector.callClosureFrom(selector); 2819 Selector closureSelector = new Selector.callClosureFrom(selector);
2817 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); 2820 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node);
2818 } 2821 }
2819 2822
2820 void registerForeignTypes(String specString) {
2821 CodegenEnqueuer enqueuer = compiler.enqueuer.codegen;
2822 for (final typeString in specString.split('|')) {
2823 if (typeString == '=List') {
2824 enqueuer.registerInstantiatedClass(compiler.listClass);
2825 } else if (typeString == 'int') {
2826 enqueuer.registerInstantiatedClass(compiler.intClass);
2827 } else if (typeString == 'double') {
2828 enqueuer.registerInstantiatedClass(compiler.doubleClass);
2829 } else if (typeString == 'num') {
2830 enqueuer.registerInstantiatedClass(compiler.intClass);
2831 enqueuer.registerInstantiatedClass(compiler.doubleClass);
2832 } else if (typeString == 'Null') {
2833 enqueuer.registerInstantiatedClass(compiler.nullClass);
2834 } else if (typeString == 'String') {
2835 enqueuer.registerInstantiatedClass(compiler.stringClass);
2836 }
2837 }
2838 }
2839
2840 void handleForeignJs(Send node) { 2823 void handleForeignJs(Send node) {
2841 Link<Node> link = node.arguments; 2824 Link<Node> link = node.arguments;
2842 // If the invoke is on foreign code, don't visit the first 2825 // If the invoke is on foreign code, don't visit the first
2843 // argument, which is the type, and the second argument, 2826 // argument, which is the type, and the second argument,
2844 // which is the foreign code. 2827 // which is the foreign code.
2845 if (link.isEmpty || link.tail.isEmpty) { 2828 if (link.isEmpty || link.tail.isEmpty) {
2846 compiler.cancel('At least two arguments expected', 2829 compiler.cancel('At least two arguments expected',
2847 node: node.argumentsNode); 2830 node: node.argumentsNode);
2848 } 2831 }
2849 List<HInstruction> inputs = <HInstruction>[]; 2832 List<HInstruction> inputs = <HInstruction>[];
2850 Node type = link.head; 2833 Node type = link.head;
2851 Node code = link.tail.head; 2834 Node code = link.tail.head;
2852 addGenericSendArgumentsToList(link.tail.tail, inputs); 2835 addGenericSendArgumentsToList(link.tail.tail, inputs);
2853 2836
2854 if (type is !LiteralString) { 2837 ConcreteType concreteType =
2855 // The type must not be a juxtaposition or interpolation. 2838 compiler.typesTask.getGuaranteedTypeOfNode(node, currentElement);
2856 compiler.cancel('The type of a JS expression must be a string literal', 2839 HType ssaType = mapInferredType(concreteType);
2857 node: type);
2858 }
2859 LiteralString typeString = type;
2860 // TODO(ngeoffray): This should be registered in codegen, not here.
2861 // Also, we should share the type parsing with the native
2862 // enqueuer.
2863 registerForeignTypes(typeString.dartString.slowToString());
2864
2865 if (code is StringNode) { 2840 if (code is StringNode) {
2866 StringNode codeString = code; 2841 StringNode codeString = code;
2867 if (!codeString.isInterpolation) { 2842 if (!codeString.isInterpolation) {
2868 // codeString may not be an interpolation, but may be a juxtaposition. 2843 // codeString may not be an interpolation, but may be a juxtaposition.
2869 push(new HForeign(codeString.dartString, 2844 push(new HForeign(codeString.dartString, ssaType, inputs));
2870 typeString.dartString,
2871 inputs));
2872 return; 2845 return;
2873 } 2846 }
2874 } 2847 }
2875 compiler.cancel('JS code must be a string literal', node: code); 2848 compiler.cancel('JS code must be a string literal', node: code);
2876 } 2849 }
2877 2850
2878 void handleForeignJsCurrentIsolate(Send node) { 2851 void handleForeignJsCurrentIsolate(Send node) {
2879 if (!node.arguments.isEmpty) { 2852 if (!node.arguments.isEmpty) {
2880 compiler.cancel( 2853 compiler.cancel(
2881 'Too many arguments to JS_CURRENT_ISOLATE', node: node); 2854 'Too many arguments to JS_CURRENT_ISOLATE', node: node);
2882 } 2855 }
2883 2856
2884 if (!compiler.hasIsolateSupport()) { 2857 if (!compiler.hasIsolateSupport()) {
2885 // If the isolate library is not used, we just generate code 2858 // If the isolate library is not used, we just generate code
2886 // to fetch the Leg's current isolate. 2859 // to fetch the Leg's current isolate.
2887 String name = backend.namer.CURRENT_ISOLATE; 2860 String name = backend.namer.CURRENT_ISOLATE;
2888 push(new HForeign(new DartString.literal(name), 2861 push(new HForeign(new DartString.literal(name),
2889 const LiteralDartString('var'), 2862 HType.UNKNOWN,
2890 <HInstruction>[])); 2863 <HInstruction>[]));
2891 } else { 2864 } else {
2892 // Call a helper method from the isolate library. The isolate 2865 // Call a helper method from the isolate library. The isolate
2893 // library uses its own isolate structure, that encapsulates 2866 // library uses its own isolate structure, that encapsulates
2894 // Leg's isolate. 2867 // Leg's isolate.
2895 Element element = compiler.isolateHelperLibrary.find( 2868 Element element = compiler.isolateHelperLibrary.find(
2896 const SourceString('_currentIsolate')); 2869 const SourceString('_currentIsolate'));
2897 if (element == null) { 2870 if (element == null) {
2898 compiler.cancel( 2871 compiler.cancel(
2899 'Isolate library and compiler mismatch', node: node); 2872 'Isolate library and compiler mismatch', node: node);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 visit(closure); 2925 visit(closure);
2953 return params; 2926 return params;
2954 } 2927 }
2955 2928
2956 void handleForeignDartClosureToJs(Send node, String name) { 2929 void handleForeignDartClosureToJs(Send node, String name) {
2957 FunctionSignature params = handleForeignRawFunctionRef(node, name); 2930 FunctionSignature params = handleForeignRawFunctionRef(node, name);
2958 List<HInstruction> inputs = <HInstruction>[pop()]; 2931 List<HInstruction> inputs = <HInstruction>[pop()];
2959 String invocationName = backend.namer.invocationName( 2932 String invocationName = backend.namer.invocationName(
2960 new Selector.callClosure(params.requiredParameterCount)); 2933 new Selector.callClosure(params.requiredParameterCount));
2961 push(new HForeign(new DartString.literal('#.$invocationName'), 2934 push(new HForeign(new DartString.literal('#.$invocationName'),
2962 const LiteralDartString('var'), 2935 HType.UNKNOWN,
2963 inputs)); 2936 inputs));
2964 } 2937 }
2965 2938
2966 void handleForeignSetCurrentIsolate(Send node) { 2939 void handleForeignSetCurrentIsolate(Send node) {
2967 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 2940 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
2968 compiler.cancel('Exactly one argument required', 2941 compiler.cancel('Exactly one argument required',
2969 node: node.argumentsNode); 2942 node: node.argumentsNode);
2970 } 2943 }
2971 visit(node.arguments.head); 2944 visit(node.arguments.head);
2972 String isolateName = backend.namer.CURRENT_ISOLATE; 2945 String isolateName = backend.namer.CURRENT_ISOLATE;
2973 push(new HForeign(new DartString.literal("$isolateName = #"), 2946 push(new HForeign(new DartString.literal("$isolateName = #"),
2974 const LiteralDartString('void'), 2947 HType.UNKNOWN,
2975 <HInstruction>[pop()])); 2948 <HInstruction>[pop()]));
2976 } 2949 }
2977 2950
2978 void handleForeignCreateIsolate(Send node) { 2951 void handleForeignCreateIsolate(Send node) {
2979 if (!node.arguments.isEmpty) { 2952 if (!node.arguments.isEmpty) {
2980 compiler.cancel('Too many arguments', 2953 compiler.cancel('Too many arguments',
2981 node: node.argumentsNode); 2954 node: node.argumentsNode);
2982 } 2955 }
2983 String constructorName = backend.namer.isolateName; 2956 String constructorName = backend.namer.isolateName;
2984 push(new HForeign(new DartString.literal("new $constructorName"), 2957 push(new HForeign(new DartString.literal("new $constructorName"),
2985 const LiteralDartString('var'), 2958 HType.UNKNOWN,
2986 <HInstruction>[])); 2959 <HInstruction>[]));
2987 } 2960 }
2988 2961
2989 visitForeignSend(Send node) { 2962 visitForeignSend(Send node) {
2990 Selector selector = elements.getSelector(node); 2963 Selector selector = elements.getSelector(node);
2991 SourceString name = selector.name; 2964 SourceString name = selector.name;
2992 if (name == const SourceString('JS')) { 2965 if (name == const SourceString('JS')) {
2993 handleForeignJs(node); 2966 handleForeignJs(node);
2994 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) { 2967 } else if (name == const SourceString('JS_CURRENT_ISOLATE')) {
2995 handleForeignJsCurrentIsolate(node); 2968 handleForeignJsCurrentIsolate(node);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 inputs.add(localsHandler.readLocal(type.element)); 3115 inputs.add(localsHandler.readLocal(type.element));
3143 } else if (member.isInstanceMember() 3116 } else if (member.isInstanceMember()
3144 || member.isGenerativeConstructor()) { 3117 || member.isGenerativeConstructor()) {
3145 // The type variable is stored in [this]. 3118 // The type variable is stored in [this].
3146 if (typeInfo == null) { 3119 if (typeInfo == null) {
3147 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), 3120 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(),
3148 localsHandler.readThis()); 3121 localsHandler.readThis());
3149 typeInfo = pop(); 3122 typeInfo = pop();
3150 } 3123 }
3151 int index = RuntimeTypeInformation.getTypeVariableIndex(type); 3124 int index = RuntimeTypeInformation.getTypeVariableIndex(type);
3152 HInstruction foreign = createForeign('#[$index]', 'String', 3125 HInstruction foreign = createForeign('#[$index]', HType.STRING,
3153 <HInstruction>[typeInfo]); 3126 <HInstruction>[typeInfo]);
3154 add(foreign); 3127 add(foreign);
3155 inputs.add(foreign); 3128 inputs.add(foreign);
3156 } else { 3129 } else {
3157 // TODO(ngeoffray): Match the VM behavior and throw an 3130 // TODO(ngeoffray): Match the VM behavior and throw an
3158 // exception at runtime. 3131 // exception at runtime.
3159 compiler.cancel('Unimplemented unresolved type variable', 3132 compiler.cancel('Unimplemented unresolved type variable',
3160 node: currentNode); 3133 node: currentNode);
3161 } 3134 }
3162 } 3135 }
3163 3136
3164 String template = rti.getTypeRepresentation(argument, 3137 String template = rti.getTypeRepresentation(argument,
3165 addTypeVariableReference); 3138 addTypeVariableReference);
3166 HInstruction result = createForeign(template, 'String', inputs); 3139 HInstruction result = createForeign(template, HType.STRING, inputs);
3167 add(result); 3140 add(result);
3168 return result; 3141 return result;
3169 } 3142 }
3170 3143
3171 void handleListConstructor(InterfaceType type, 3144 void handleListConstructor(InterfaceType type,
3172 Node currentNode, 3145 Node currentNode,
3173 HInstruction newObject) { 3146 HInstruction newObject) {
3174 if (!compiler.world.needsRti(type.element)) return; 3147 if (!compiler.world.needsRti(type.element)) return;
3175 List<HInstruction> inputs = <HInstruction>[]; 3148 List<HInstruction> inputs = <HInstruction>[];
3176 if (!type.isRaw) { 3149 if (!type.isRaw) {
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
4555 } 4528 }
4556 4529
4557 visitTypedef(Typedef node) { 4530 visitTypedef(Typedef node) {
4558 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); 4531 compiler.unimplemented('SsaBuilder.visitTypedef', node: node);
4559 } 4532 }
4560 4533
4561 visitTypeVariable(TypeVariable node) { 4534 visitTypeVariable(TypeVariable node) {
4562 compiler.internalError('SsaBuilder.visitTypeVariable'); 4535 compiler.internalError('SsaBuilder.visitTypeVariable');
4563 } 4536 }
4564 4537
4538 HType mapBaseType(BaseType baseType) {
4539 if (!baseType.isClass()) return HType.UNKNOWN;
4540 ClassBaseType classBaseType = baseType;
4541 return new HType.fromBoundedType(
4542 baseType.element.computeType(compiler), compiler, false);
4543 }
4544
4565 HType mapInferredType(ConcreteType concreteType) { 4545 HType mapInferredType(ConcreteType concreteType) {
4566 if (concreteType == null) return HType.UNKNOWN; 4546 if (concreteType == null) return HType.UNKNOWN;
4567 ClassElement element = concreteType.getUniqueType(); 4547 HType ssaType = HType.CONFLICTING;
4568 if (element == null) return HType.UNKNOWN; 4548 for (BaseType baseType in concreteType.baseTypes) {
4569 if (element == builder.compiler.boolClass) return HType.BOOLEAN; 4549 ssaType = ssaType.union(mapBaseType(baseType), compiler);
4570 if (element == builder.compiler.doubleClass) return HType.DOUBLE; 4550 }
4571 if (element == builder.compiler.intClass) return HType.INTEGER; 4551 assert(!ssaType.isConflicting());
4572 if (element == builder.compiler.listClass) return HType.READABLE_ARRAY; 4552 return ssaType;
4573 if (element == builder.compiler.nullClass) return HType.NULL;
4574 if (element == builder.compiler.stringClass) return HType.STRING;
4575 return HType.UNKNOWN;
4576 } 4553 }
4577 } 4554 }
4578 4555
4579 /** 4556 /**
4580 * Visitor that handles generation of string literals (LiteralString, 4557 * Visitor that handles generation of string literals (LiteralString,
4581 * StringInterpolation), and otherwise delegates to the given visitor for 4558 * StringInterpolation), and otherwise delegates to the given visitor for
4582 * non-literal subexpressions. 4559 * non-literal subexpressions.
4583 * TODO(lrn): Consider whether to handle compile time constant int/boolean 4560 * TODO(lrn): Consider whether to handle compile time constant int/boolean
4584 * expressions as well. 4561 * expressions as well.
4585 */ 4562 */
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 new HSubGraphBlockInformation(elseBranch.graph)); 4928 new HSubGraphBlockInformation(elseBranch.graph));
4952 4929
4953 HBasicBlock conditionStartBlock = conditionBranch.block; 4930 HBasicBlock conditionStartBlock = conditionBranch.block;
4954 conditionStartBlock.setBlockFlow(info, joinBlock); 4931 conditionStartBlock.setBlockFlow(info, joinBlock);
4955 SubGraph conditionGraph = conditionBranch.graph; 4932 SubGraph conditionGraph = conditionBranch.graph;
4956 HIf branch = conditionGraph.end.last; 4933 HIf branch = conditionGraph.end.last;
4957 assert(branch is HIf); 4934 assert(branch is HIf);
4958 branch.blockInformation = conditionStartBlock.blockFlow; 4935 branch.blockInformation = conditionStartBlock.blockFlow;
4959 } 4936 }
4960 } 4937 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698