Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 17848) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -179,7 +179,7 @@ |
| // TODO(floitsch): Clean up this hack. Should we create a box-object by |
| // just creating an empty object literal? |
| HInstruction box = new HForeign(const LiteralDartString("{}"), |
| - const LiteralDartString('Object'), |
| + HType.UNKNOWN, |
| <HInstruction>[]); |
| builder.add(box); |
| return box; |
| @@ -1326,11 +1326,14 @@ |
| includeBackendMembers: true, |
| includeSuperMembers: true); |
| - HForeignNew newObject = new HForeignNew(classElement, constructorArguments); |
| + InterfaceType type = classElement.computeType(compiler); |
| + 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
|
| + HForeignNew newObject = new HForeignNew(classElement, |
| + ssaType, |
| + constructorArguments); |
| add(newObject); |
| // Create the runtime type information, if needed. |
| - InterfaceType type = classElement.computeType(compiler); |
| List<HInstruction> inputs = <HInstruction>[]; |
| if (compiler.world.needsRti(classElement)) { |
| classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| @@ -2113,7 +2116,9 @@ |
| } |
| }); |
| - push(new HForeignNew(closureClassElement, capturedVariables)); |
| + HType type = new HBoundedType.exact( |
| + compiler.functionClass.computeType(compiler)); |
| + push(new HForeignNew(closureClassElement, type, capturedVariables)); |
| } |
| visitFunctionDeclaration(FunctionDeclaration node) { |
| @@ -2507,10 +2512,8 @@ |
| push(result); |
| } |
| - HForeign createForeign(String code, String type, List<HInstruction> inputs) { |
| - return new HForeign(new LiteralDartString(code), |
| - new LiteralDartString(type), |
| - inputs); |
| + HForeign createForeign(String code, HType type, List<HInstruction> inputs) { |
| + return new HForeign(new LiteralDartString(code), type, inputs); |
| } |
| HInstruction getRuntimeTypeInfo(HInstruction target) { |
| @@ -2522,7 +2525,7 @@ |
| // (dartbug.com/7182). |
| List<HInstruction> buildTypeArgumentRepresentations(DartType type) { |
| HInstruction createForeignArray(String code, inputs) { |
| - return createForeign(code, '=List', inputs); |
| + return createForeign(code, HType.READABLE_ARRAY, inputs); |
| } |
| HInstruction typeInfo; |
| @@ -2622,7 +2625,7 @@ |
| HInstruction position = graph.addConstantInt(index, constantSystem); |
| // Get the index'th type argument from the runtime type information. |
| HInstruction typeArgument = |
| - createForeign('#[#]', 'Object', [typeInfo, position]); |
| + createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]); |
| add(typeArgument); |
| // Create the call to isSubtype. |
| List<HInstruction> inputs = |
| @@ -2820,26 +2823,6 @@ |
| pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); |
| } |
| - void registerForeignTypes(String specString) { |
| - CodegenEnqueuer enqueuer = compiler.enqueuer.codegen; |
| - for (final typeString in specString.split('|')) { |
| - if (typeString == '=List') { |
| - enqueuer.registerInstantiatedClass(compiler.listClass); |
| - } else if (typeString == 'int') { |
| - enqueuer.registerInstantiatedClass(compiler.intClass); |
| - } else if (typeString == 'double') { |
| - enqueuer.registerInstantiatedClass(compiler.doubleClass); |
| - } else if (typeString == 'num') { |
| - enqueuer.registerInstantiatedClass(compiler.intClass); |
| - enqueuer.registerInstantiatedClass(compiler.doubleClass); |
| - } else if (typeString == 'Null') { |
| - enqueuer.registerInstantiatedClass(compiler.nullClass); |
| - } else if (typeString == 'String') { |
| - enqueuer.registerInstantiatedClass(compiler.stringClass); |
| - } |
| - } |
| - } |
| - |
| void handleForeignJs(Send node) { |
| Link<Node> link = node.arguments; |
| // If the invoke is on foreign code, don't visit the first |
| @@ -2854,24 +2837,15 @@ |
| Node code = link.tail.head; |
| addGenericSendArgumentsToList(link.tail.tail, inputs); |
| - if (type is !LiteralString) { |
| - // The type must not be a juxtaposition or interpolation. |
| - compiler.cancel('The type of a JS expression must be a string literal', |
| - node: type); |
| - } |
| - LiteralString typeString = type; |
| - // TODO(ngeoffray): This should be registered in codegen, not here. |
| - // Also, we should share the type parsing with the native |
| - // enqueuer. |
| - registerForeignTypes(typeString.dartString.slowToString()); |
| - |
| + native.NativeBehavior nativeBehavior = |
| + compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
| + HType ssaType = mapNativeBehaviorType(nativeBehavior); |
| + print('$node for $ssaType'); |
|
kasperl
2013/02/04 09:27:50
Remove printing.
ngeoffray
2013/02/04 10:45:06
Done.
|
| if (code is StringNode) { |
| StringNode codeString = code; |
| if (!codeString.isInterpolation) { |
| // codeString may not be an interpolation, but may be a juxtaposition. |
| - push(new HForeign(codeString.dartString, |
| - typeString.dartString, |
| - inputs)); |
| + push(new HForeign(codeString.dartString, ssaType, inputs)); |
| return; |
| } |
| } |
| @@ -2889,7 +2863,7 @@ |
| // to fetch the Leg's current isolate. |
| String name = backend.namer.CURRENT_ISOLATE; |
| push(new HForeign(new DartString.literal(name), |
| - const LiteralDartString('var'), |
| + HType.UNKNOWN, |
| <HInstruction>[])); |
| } else { |
| // Call a helper method from the isolate library. The isolate |
| @@ -2962,7 +2936,7 @@ |
| String invocationName = backend.namer.invocationName( |
| new Selector.callClosure(params.requiredParameterCount)); |
| push(new HForeign(new DartString.literal('#.$invocationName'), |
| - const LiteralDartString('var'), |
| + HType.UNKNOWN, |
| inputs)); |
| } |
| @@ -2974,7 +2948,7 @@ |
| visit(node.arguments.head); |
| String isolateName = backend.namer.CURRENT_ISOLATE; |
| push(new HForeign(new DartString.literal("$isolateName = #"), |
| - const LiteralDartString('void'), |
| + HType.UNKNOWN, |
| <HInstruction>[pop()])); |
| } |
| @@ -2985,7 +2959,7 @@ |
| } |
| String constructorName = backend.namer.isolateName; |
| push(new HForeign(new DartString.literal("new $constructorName"), |
| - const LiteralDartString('var'), |
| + HType.UNKNOWN, |
| <HInstruction>[])); |
| } |
| @@ -3152,7 +3126,7 @@ |
| typeInfo = pop(); |
| } |
| int index = RuntimeTypeInformation.getTypeVariableIndex(type); |
| - HInstruction foreign = createForeign('#[$index]', 'String', |
| + HInstruction foreign = createForeign('#[$index]', HType.STRING, |
| <HInstruction>[typeInfo]); |
| add(foreign); |
| inputs.add(foreign); |
| @@ -3166,7 +3140,7 @@ |
| String template = rti.getTypeRepresentation(argument, |
| addTypeVariableReference); |
| - HInstruction result = createForeign(template, 'String', inputs); |
| + HInstruction result = createForeign(template, HType.STRING, inputs); |
| add(result); |
| return result; |
| } |
| @@ -4565,18 +4539,44 @@ |
| compiler.internalError('SsaBuilder.visitTypeVariable'); |
| } |
| + HType mapBaseType(BaseType baseType) { |
| + if (!baseType.isClass()) return HType.UNKNOWN; |
| + ClassBaseType classBaseType = baseType; |
|
kasperl
2013/02/04 09:27:50
Unused local variable.
ngeoffray
2013/02/04 10:45:06
Done.
|
| + return new HType.fromBoundedType( |
| + baseType.element.computeType(compiler), compiler, false); |
| + } |
| + |
| HType mapInferredType(ConcreteType concreteType) { |
| if (concreteType == null) return HType.UNKNOWN; |
| - ClassElement element = concreteType.getUniqueType(); |
| - if (element == null) return HType.UNKNOWN; |
| - if (element == builder.compiler.boolClass) return HType.BOOLEAN; |
| - if (element == builder.compiler.doubleClass) return HType.DOUBLE; |
| - if (element == builder.compiler.intClass) return HType.INTEGER; |
| - if (element == builder.compiler.listClass) return HType.READABLE_ARRAY; |
| - if (element == builder.compiler.nullClass) return HType.NULL; |
| - if (element == builder.compiler.stringClass) return HType.STRING; |
| - return HType.UNKNOWN; |
| + HType ssaType = HType.CONFLICTING; |
| + for (BaseType baseType in concreteType.baseTypes) { |
| + ssaType = ssaType.union(mapBaseType(baseType), compiler); |
| + } |
| + assert(!ssaType.isConflicting()); |
| + return ssaType; |
| } |
| + |
| + HType mapNativeType(type) { |
| + if (type == native.SpecialType.JsObject) { |
| + return new HBoundedType.exact( |
| + compiler.objectClass.computeType(compiler)); |
| + } else if (type == native.SpecialType.JsArray) { |
| + return HType.READABLE_ARRAY; |
| + } else { |
| + return new HType.fromBoundedType(type, compiler, false); |
| + } |
| + } |
| + |
| + HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) { |
| + if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN; |
| + |
| + HType ssaType = HType.CONFLICTING; |
| + for (final type in nativeBehavior.typesInstantiated) { |
| + ssaType = ssaType.union(mapNativeType(type), compiler); |
| + } |
| + assert(!ssaType.isConflicting()); |
| + return ssaType; |
| + } |
| } |
| /** |