| 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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 tmp.prototype = parent.prototype; | 30 tmp.prototype = parent.prototype; |
| 31 child.prototype = new tmp(); | 31 child.prototype = new tmp(); |
| 32 child.prototype.constructor = child; | 32 child.prototype.constructor = child; |
| 33 } | 33 } |
| 34 }'''; | 34 }'''; |
| 35 | 35 |
| 36 bool addedInheritFunction = false; | 36 bool addedInheritFunction = false; |
| 37 final Namer namer; | 37 final Namer namer; |
| 38 final NativeEmitter nativeEmitter; | 38 final NativeEmitter nativeEmitter; |
| 39 Set<ClassElement> generatedClasses; | 39 Set<ClassElement> generatedClasses; |
| 40 StringBuffer mainBuffer; |
| 40 | 41 |
| 41 CodeEmitterTask(Compiler compiler) | 42 CodeEmitterTask(Compiler compiler) |
| 42 : namer = compiler.namer, | 43 : namer = compiler.namer, |
| 43 nativeEmitter = new NativeEmitter(compiler), | 44 nativeEmitter = new NativeEmitter(compiler), |
| 44 generatedClasses = new Set<ClassElement>(), | 45 generatedClasses = new Set<ClassElement>(), |
| 46 mainBuffer = new StringBuffer(), |
| 45 super(compiler); | 47 super(compiler); |
| 46 | 48 |
| 47 String get name() => 'CodeEmitter'; | 49 String get name() => 'CodeEmitter'; |
| 48 | 50 |
| 49 String get inheritsName() => '${namer.ISOLATE}.\$inherits'; | 51 String get inheritsName() => '${namer.ISOLATE}.\$inherits'; |
| 50 | 52 |
| 51 String get objectClassName() { | 53 String get objectClassName() { |
| 52 ClassElement objectClass = | 54 ClassElement objectClass = |
| 53 compiler.coreLibrary.find(const SourceString('Object')); | 55 compiler.coreLibrary.find(const SourceString('Object')); |
| 54 return namer.isolatePropertyAccess(objectClass); | 56 return namer.isolatePropertyAccess(objectClass); |
| 55 } | 57 } |
| 56 | 58 |
| 57 void addInheritFunctionIfNecessary(StringBuffer buffer) { | 59 void addInheritFunctionIfNecessary() { |
| 58 if (addedInheritFunction) return; | 60 if (addedInheritFunction) return; |
| 59 addedInheritFunction = true; | 61 addedInheritFunction = true; |
| 60 buffer.add('$inheritsName = '); | 62 mainBuffer.add('$inheritsName = '); |
| 61 buffer.add(INHERIT_FUNCTION); | 63 mainBuffer.add(INHERIT_FUNCTION); |
| 62 buffer.add(';\n'); | 64 mainBuffer.add(';\n'); |
| 63 } | 65 } |
| 64 | 66 |
| 65 void addParameterStub(FunctionElement member, | 67 void addParameterStub(FunctionElement member, |
| 66 String attachTo(String invocationName), | 68 String attachTo(String invocationName), |
| 67 StringBuffer buffer, | 69 StringBuffer buffer, |
| 68 Selector selector, | 70 Selector selector, |
| 69 bool isNative) { | 71 bool isNative) { |
| 70 FunctionParameters parameters = member.computeParameters(compiler); | 72 FunctionParameters parameters = member.computeParameters(compiler); |
| 71 int positionalArgumentCount = selector.positionalArgumentCount; | 73 int positionalArgumentCount = selector.positionalArgumentCount; |
| 72 if (positionalArgumentCount == parameters.parameterCount) { | 74 if (positionalArgumentCount == parameters.parameterCount) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 } | 153 } |
| 152 } | 154 } |
| 153 count++; | 155 count++; |
| 154 }); | 156 }); |
| 155 String parametersString = Strings.join(parametersBuffer, ","); | 157 String parametersString = Strings.join(parametersBuffer, ","); |
| 156 buffer.add('$parametersString) {\n'); | 158 buffer.add('$parametersString) {\n'); |
| 157 | 159 |
| 158 if (isNative) { | 160 if (isNative) { |
| 159 nativeEmitter.emitParameterStub( | 161 nativeEmitter.emitParameterStub( |
| 160 member, invocationName, parametersString, argumentsBuffer, | 162 member, invocationName, parametersString, argumentsBuffer, |
| 161 indexOfLastOptionalArgumentInParameters, buffer); | 163 indexOfLastOptionalArgumentInParameters); |
| 162 } else { | 164 } else { |
| 163 String arguments = Strings.join(argumentsBuffer, ","); | 165 String arguments = Strings.join(argumentsBuffer, ","); |
| 164 buffer.add(' return this.${namer.getName(member)}($arguments)'); | 166 buffer.add(' return this.${namer.getName(member)}($arguments)'); |
| 165 } | 167 } |
| 166 buffer.add('\n}\n'); | 168 buffer.add('\n}\n'); |
| 167 } | 169 } |
| 168 | 170 |
| 169 void addParameterStubs(FunctionElement member, | 171 void addParameterStubs(FunctionElement member, |
| 170 String attachTo(String invocationName), | 172 String attachTo(String invocationName), |
| 171 StringBuffer buffer, | 173 StringBuffer buffer, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 generateFieldInit(element); | 257 generateFieldInit(element); |
| 256 } | 258 } |
| 257 | 259 |
| 258 classElement = classElement.superclass; | 260 classElement = classElement.superclass; |
| 259 } while(classElement !== null); | 261 } while(classElement !== null); |
| 260 } | 262 } |
| 261 | 263 |
| 262 void emitInherits(ClassElement cls, StringBuffer buffer) { | 264 void emitInherits(ClassElement cls, StringBuffer buffer) { |
| 263 ClassElement superclass = cls.superclass; | 265 ClassElement superclass = cls.superclass; |
| 264 if (superclass !== null) { | 266 if (superclass !== null) { |
| 265 addInheritFunctionIfNecessary(buffer); | 267 addInheritFunctionIfNecessary(); |
| 266 String className = namer.isolatePropertyAccess(cls); | 268 String className = namer.isolatePropertyAccess(cls); |
| 267 String superName = namer.isolatePropertyAccess(superclass); | 269 String superName = namer.isolatePropertyAccess(superclass); |
| 268 buffer.add('${inheritsName}($className, $superName);\n'); | 270 buffer.add('${inheritsName}($className, $superName);\n'); |
| 269 } | 271 } |
| 270 } | 272 } |
| 271 | 273 |
| 272 void ensureGenerated(ClassElement classElement, StringBuffer buffer) { | 274 void ensureGenerated(ClassElement classElement, StringBuffer buffer) { |
| 273 if (classElement == null) return; | 275 if (classElement == null) return; |
| 274 if (generatedClasses.contains(classElement)) return; | 276 if (generatedClasses.contains(classElement)) return; |
| 275 generatedClasses.add(classElement); | 277 generatedClasses.add(classElement); |
| 276 generateClass(classElement, buffer); | 278 generateClass(classElement, buffer); |
| 277 } | 279 } |
| 278 | 280 |
| 279 void generateClass(ClassElement classElement, StringBuffer buffer) { | 281 void generateClass(ClassElement classElement, StringBuffer buffer) { |
| 280 ensureGenerated(classElement.superclass, buffer); | 282 ensureGenerated(classElement.superclass, buffer); |
| 281 | 283 |
| 282 if (classElement.isNative()) { | 284 if (classElement.isNative()) { |
| 283 nativeEmitter.generateNativeClass(classElement, buffer); | 285 nativeEmitter.generateNativeClass(classElement); |
| 284 return; | 286 return; |
| 287 } else { |
| 288 // TODO(ngeoffray): Instead of switching between buffer, we |
| 289 // should create code sections, and decide where to emit them at |
| 290 // the end. |
| 291 buffer = mainBuffer; |
| 285 } | 292 } |
| 286 | 293 |
| 287 String className = namer.isolatePropertyAccess(classElement); | 294 String className = namer.isolatePropertyAccess(classElement); |
| 288 buffer.add('$className = function ${classElement.name.slowToString()}('); | 295 buffer.add('$className = function ${classElement.name.slowToString()}('); |
| 289 StringBuffer bodyBuffer = new StringBuffer(); | 296 StringBuffer bodyBuffer = new StringBuffer(); |
| 290 // If the class is never instantiated we still need to set it up for | 297 // If the class is never instantiated we still need to set it up for |
| 291 // inheritance purposes, but we can leave its JavaScript constructor empty. | 298 // inheritance purposes, but we can leave its JavaScript constructor empty. |
| 292 if (compiler.universe.instantiatedClasses.contains(classElement)) { | 299 if (compiler.universe.instantiatedClasses.contains(classElement)) { |
| 293 generateFieldInits(classElement, buffer, bodyBuffer); | 300 generateFieldInits(classElement, buffer, bodyBuffer); |
| 294 } | 301 } |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 Element isolateMain = | 687 Element isolateMain = |
| 681 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE); | 688 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE); |
| 682 buffer.add(buildIsolateSetup(main, isolateMain)); | 689 buffer.add(buildIsolateSetup(main, isolateMain)); |
| 683 } else { | 690 } else { |
| 684 buffer.add('${namer.isolateAccess(main)}();\n'); | 691 buffer.add('${namer.isolateAccess(main)}();\n'); |
| 685 } | 692 } |
| 686 } | 693 } |
| 687 | 694 |
| 688 String assembleProgram() { | 695 String assembleProgram() { |
| 689 measure(() { | 696 measure(() { |
| 690 StringBuffer buffer = new StringBuffer(); | 697 mainBuffer.add('function ${namer.ISOLATE}() {'); |
| 691 buffer.add('function ${namer.ISOLATE}() {'); | 698 emitStaticNonFinalFieldInitializations(mainBuffer); |
| 692 emitStaticNonFinalFieldInitializations(buffer); | 699 mainBuffer.add('}\n\n'); |
| 693 buffer.add('}\n\n'); | 700 emitClasses(mainBuffer); |
| 694 emitClasses(buffer); | 701 emitStaticFunctions(mainBuffer); |
| 695 emitStaticFunctions(buffer); | 702 emitStaticFunctionGetters(mainBuffer); |
| 696 emitStaticFunctionGetters(buffer); | 703 emitCompileTimeConstants(mainBuffer); |
| 697 emitCompileTimeConstants(buffer); | 704 emitStaticFinalFieldInitializations(mainBuffer); |
| 698 emitStaticFinalFieldInitializations(buffer); | 705 nativeEmitter.emitDynamicDispatchMetadata(); |
| 699 nativeEmitter.emitDynamicDispatchMetadata(buffer); | 706 mainBuffer.add( |
| 700 buffer.add('var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); | 707 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); |
| 701 emitMain(buffer); | 708 nativeEmitter.assembleCode(mainBuffer); |
| 702 compiler.assembledCode = buffer.toString(); | 709 emitMain(mainBuffer); |
| 710 compiler.assembledCode = mainBuffer.toString(); |
| 703 }); | 711 }); |
| 704 return compiler.assembledCode; | 712 return compiler.assembledCode; |
| 705 } | 713 } |
| 706 } | 714 } |
| OLD | NEW |