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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 | 6 |
| 7 final JavaScriptBackend backend; | 7 final JavaScriptBackend backend; |
| 8 | 8 |
| 9 SsaCodeGeneratorTask(JavaScriptBackend backend) | 9 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 10 : this.backend = backend, | 10 : this.backend = backend, |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 }); | 41 }); |
| 42 compiler.tracer.traceGraph("codegen", graph); | 42 compiler.tracer.traceGraph("codegen", graph); |
| 43 Map<Element, String> parameterNames = getParameterNames(work); | 43 Map<Element, String> parameterNames = getParameterNames(work); |
| 44 parameterNames.forEach((element, name) { | 44 parameterNames.forEach((element, name) { |
| 45 compiler.enqueuer.codegen.addToWorkList(element); | 45 compiler.enqueuer.codegen.addToWorkList(element); |
| 46 }); | 46 }); |
| 47 List<js.Parameter> parameters = <js.Parameter>[]; | 47 List<js.Parameter> parameters = <js.Parameter>[]; |
| 48 parameterNames.forEach((element, name) { | 48 parameterNames.forEach((element, name) { |
| 49 parameters.add(new js.Parameter(name)); | 49 parameters.add(new js.Parameter(name)); |
| 50 }); | 50 }); |
| 51 addTypeVariables(work.element, parameters, parameterNames); | |
| 51 String parametersString = Strings.join(parameterNames.getValues(), ", "); | 52 String parametersString = Strings.join(parameterNames.getValues(), ", "); |
| 52 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( | 53 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( |
| 53 backend, work, parameters, parameterNames); | 54 backend, work, parameters, parameterNames); |
| 54 codegen.visitGraph(graph); | 55 codegen.visitGraph(graph); |
| 55 | 56 |
| 56 FunctionElement element = work.element; | 57 FunctionElement element = work.element; |
| 57 js.Block body; | 58 js.Block body; |
| 58 ClassElement enclosingClass = element.getEnclosingClass(); | 59 ClassElement enclosingClass = element.getEnclosingClass(); |
| 59 if (element.isInstanceMember() | 60 if (element.isInstanceMember() |
| 60 && enclosingClass.isNative() | 61 && enclosingClass.isNative() |
| 61 && native.isOverriddenMethod( | 62 && native.isOverriddenMethod( |
| 62 element, enclosingClass, nativeEmitter)) { | 63 element, enclosingClass, nativeEmitter)) { |
| 63 // Record that this method is overridden. In case of optional | 64 // Record that this method is overridden. In case of optional |
| 64 // arguments, the emitter will generate stubs to handle them, | 65 // arguments, the emitter will generate stubs to handle them, |
| 65 // and needs to know if the method is overridden. | 66 // and needs to know if the method is overridden. |
| 66 nativeEmitter.overriddenMethods.add(element); | 67 nativeEmitter.overriddenMethods.add(element); |
| 67 StringBuffer buffer = new StringBuffer(); | 68 StringBuffer buffer = new StringBuffer(); |
| 68 String codeString = prettyPrint(codegen.body, work.element).toString(); | 69 String codeString = prettyPrint(codegen.body, work.element).toString(); |
| 69 native.generateMethodWithPrototypeCheckForElement( | 70 native.generateMethodWithPrototypeCheckForElement( |
| 70 compiler, buffer, element, codeString, parametersString); | 71 compiler, buffer, element, codeString, parametersString); |
| 71 js.Node nativeCode = new js.LiteralStatement(buffer.toString()); | 72 js.Node nativeCode = new js.LiteralStatement(buffer.toString()); |
| 72 body = new js.Block(<js.Statement>[nativeCode]); | 73 body = new js.Block(<js.Statement>[nativeCode]); |
| 73 } else { | 74 } else { |
| 74 body = codegen.body; | 75 body = codegen.body; |
| 75 } | 76 } |
| 76 js.Fun fun = buildJavaScriptFunction(element, parameters, body); | 77 js.Fun fun = buildJavaScriptFunction(element, parameters, body); |
| 77 return prettyPrint(fun, work.element); | 78 return prettyPrint(fun, work.element); |
| 78 }); | 79 }); |
| 79 } | 80 } |
| 81 | |
| 82 void addTypeVariables(Element element, | |
|
kasperl
2012/08/28 09:14:15
Shouldn't this be something like addTypeParameters
ngeoffray
2012/08/28 10:39:45
Done.
| |
| 83 List<js.Parameter> parameters, | |
| 84 Map<Element, String> parameterNames) { | |
| 85 if (element.isFactoryConstructor() || element.isGenerativeConstructor()) { | |
| 86 ClassElement cls = element.enclosingElement; | |
| 87 cls.typeVariables.forEach((TypeVariableType typeVariable) { | |
| 88 String name = typeVariable.element.name.slowToString(); | |
| 89 String prefix = ''; | |
| 90 // Avoid collisions with real parameters of the method. | |
| 91 do { | |
| 92 name = JsNames.getValid('$prefix$name'); | |
| 93 prefix = '\$$prefix'; | |
| 94 } while (parameterNames.containsValue(name)); | |
| 95 parameterNames[typeVariable.element] = name; | |
| 96 parameters.add(new js.Parameter(name)); | |
| 97 }); | |
| 98 } | |
| 99 } | |
| 80 | 100 |
| 81 CodeBuffer generateBailoutMethod(WorkItem work, HGraph graph) { | 101 CodeBuffer generateBailoutMethod(WorkItem work, HGraph graph) { |
| 82 return measure(() { | 102 return measure(() { |
| 83 compiler.tracer.traceGraph("codegen-bailout", graph); | 103 compiler.tracer.traceGraph("codegen-bailout", graph); |
| 84 | 104 |
| 85 Map<Element, String> parameterNames = getParameterNames(work); | 105 Map<Element, String> parameterNames = getParameterNames(work); |
| 86 List<js.Parameter> parameters = <js.Parameter>[]; | 106 List<js.Parameter> parameters = <js.Parameter>[]; |
| 87 parameterNames.forEach((element, name) { | 107 parameterNames.forEach((element, name) { |
| 88 parameters.add(new js.Parameter(name)); | 108 parameters.add(new js.Parameter(name)); |
| 89 }); | 109 }); |
| 110 addTypeVariables(work.element, parameters, parameterNames); | |
| 111 | |
| 90 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( | 112 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( |
| 91 backend, work, parameters, parameterNames); | 113 backend, work, parameters, parameterNames); |
| 92 codegen.visitGraph(graph); | 114 codegen.visitGraph(graph); |
| 93 | 115 |
| 94 js.Block body = new js.Block(<js.Statement>[]); | 116 js.Block body = new js.Block(<js.Statement>[]); |
| 95 if (codegen.setup != null) body.statements.add(codegen.setup); | 117 if (codegen.setup != null) body.statements.add(codegen.setup); |
| 96 body.statements.add(codegen.body); | 118 body.statements.add(codegen.body); |
| 97 js.Fun fun = | 119 js.Fun fun = |
| 98 buildJavaScriptFunction(work.element, codegen.newParameters, body); | 120 buildJavaScriptFunction(work.element, codegen.newParameters, body); |
| 99 return prettyPrint(fun, work.element); | 121 return prettyPrint(fun, work.element); |
| (...skipping 2152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2252 attachLocationToLast(node); | 2274 attachLocationToLast(node); |
| 2253 } else if (types[input].canBePrimitive() || types[input].canBeNull()) { | 2275 } else if (types[input].canBePrimitive() || types[input].canBeNull()) { |
| 2254 checkObject(input, '==='); | 2276 checkObject(input, '==='); |
| 2255 js.Expression objectTest = pop(); | 2277 js.Expression objectTest = pop(); |
| 2256 checkType(input, element); | 2278 checkType(input, element); |
| 2257 push(new js.Binary('&&', objectTest, pop()), node); | 2279 push(new js.Binary('&&', objectTest, pop()), node); |
| 2258 } else { | 2280 } else { |
| 2259 checkType(input, element); | 2281 checkType(input, element); |
| 2260 attachLocationToLast(node); | 2282 attachLocationToLast(node); |
| 2261 } | 2283 } |
| 2262 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { | 2284 if (node.hasTypeInfo()) { |
| 2263 InterfaceType interfaceType = type; | 2285 InterfaceType interfaceType = type; |
| 2264 ClassElement cls = type.element; | 2286 ClassElement cls = type.element; |
| 2265 Link<Type> arguments = interfaceType.arguments; | 2287 Link<Type> arguments = interfaceType.arguments; |
| 2266 js.Expression result = pop(); | 2288 js.Expression result = pop(); |
| 2267 checkObject(node.typeInfoCall, '==='); | |
| 2268 result = new js.Binary('&&', result, pop()); | |
| 2269 for (TypeVariableType typeVariable in cls.typeVariables) { | 2289 for (TypeVariableType typeVariable in cls.typeVariables) { |
| 2270 use(node.typeInfoCall); | 2290 use(node.typeInfoCall); |
| 2271 // TODO(johnniwinther): Retrieve the type name properly and not through | 2291 // TODO(johnniwinther): Retrieve the type name properly and not through |
| 2272 // [toString]. Note: Two cases below [typeVariable] and | 2292 // [toString]. Note: Two cases below [typeVariable] and |
| 2273 // [arguments.head]. | 2293 // [arguments.head]. |
| 2274 js.PropertyAccess field = | 2294 js.PropertyAccess field = |
| 2275 new js.PropertyAccess.field(pop(), typeVariable.toString()); | 2295 new js.PropertyAccess.field(pop(), typeVariable.toString()); |
| 2276 js.Expression genericName = new js.LiteralString("'${arguments.head}'"); | 2296 js.Expression genericName = new js.LiteralString("'${arguments.head}'"); |
| 2277 js.Binary eqTest = new js.Binary('===', field, genericName); | 2297 js.Binary eqTest = new js.Binary('===', field, genericName); |
| 2278 result = new js.Binary('&&', result, eqTest); | 2298 result = new js.Binary('&&', result, eqTest); |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2905 if (leftType.canBeNull() && rightType.canBeNull()) { | 2925 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2906 if (left.isConstantNull() || right.isConstantNull() || | 2926 if (left.isConstantNull() || right.isConstantNull() || |
| 2907 (leftType.isPrimitive() && leftType == rightType)) { | 2927 (leftType.isPrimitive() && leftType == rightType)) { |
| 2908 return '=='; | 2928 return '=='; |
| 2909 } | 2929 } |
| 2910 return null; | 2930 return null; |
| 2911 } else { | 2931 } else { |
| 2912 return '==='; | 2932 return '==='; |
| 2913 } | 2933 } |
| 2914 } | 2934 } |
| OLD | NEW |