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

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 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698