| 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 part of js_backend; | 5 part of js_backend; | 
| 6 | 6 | 
| 7 /** | 7 /** | 
| 8  * A function element that represents a closure call. The signature is copied | 8  * A function element that represents a closure call. The signature is copied | 
| 9  * from the given element. | 9  * from the given element. | 
| 10  */ | 10  */ | 
| (...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2624     } | 2624     } | 
| 2625   } | 2625   } | 
| 2626 | 2626 | 
| 2627   void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 2627   void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 
| 2628     ConstantHandler handler = compiler.constantHandler; | 2628     ConstantHandler handler = compiler.constantHandler; | 
| 2629     Iterable<VariableElement> staticNonFinalFields = | 2629     Iterable<VariableElement> staticNonFinalFields = | 
| 2630         handler.getStaticNonFinalFieldsForEmission(); | 2630         handler.getStaticNonFinalFieldsForEmission(); | 
| 2631     for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 2631     for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 
| 2632       // [:interceptedNames:] is handled in [emitInterceptedNames]. | 2632       // [:interceptedNames:] is handled in [emitInterceptedNames]. | 
| 2633       if (element == backend.interceptedNames) continue; | 2633       if (element == backend.interceptedNames) continue; | 
|  | 2634       // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor]. | 
|  | 2635       if (element == backend.mapTypeToInterceptor) continue; | 
| 2634       compiler.withCurrentElement(element, () { | 2636       compiler.withCurrentElement(element, () { | 
| 2635         Constant initialValue = handler.getInitialValueFor(element); | 2637         Constant initialValue = handler.getInitialValueFor(element); | 
| 2636         jsAst.Expression init = | 2638         jsAst.Expression init = | 
| 2637           js('$isolateProperties.${namer.getName(element)} = #', | 2639           js('$isolateProperties.${namer.getName(element)} = #', | 
| 2638               constantEmitter.referenceInInitializationContext(initialValue)); | 2640               constantEmitter.referenceInInitializationContext(initialValue)); | 
| 2639         buffer.write(jsAst.prettyPrint(init, compiler)); | 2641         buffer.write(jsAst.prettyPrint(init, compiler)); | 
| 2640         buffer.write('$N'); | 2642         buffer.write('$N'); | 
| 2641       }); | 2643       }); | 
| 2642     } | 2644     } | 
| 2643   } | 2645   } | 
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3049     } | 3051     } | 
| 3050 | 3052 | 
| 3051     bool hasArray = false; | 3053     bool hasArray = false; | 
| 3052     bool hasBool = false; | 3054     bool hasBool = false; | 
| 3053     bool hasDouble = false; | 3055     bool hasDouble = false; | 
| 3054     bool hasInt = false; | 3056     bool hasInt = false; | 
| 3055     bool hasNull = false; | 3057     bool hasNull = false; | 
| 3056     bool hasNumber = false; | 3058     bool hasNumber = false; | 
| 3057     bool hasString = false; | 3059     bool hasString = false; | 
| 3058     bool hasNative = false; | 3060     bool hasNative = false; | 
|  | 3061     bool anyNativeClasses = compiler.enqueuer.codegen.nativeEnqueuer | 
|  | 3062           .hasInstantiatedNativeClasses(); | 
|  | 3063 | 
| 3059     for (ClassElement cls in classes) { | 3064     for (ClassElement cls in classes) { | 
| 3060       if (cls == backend.jsArrayClass || | 3065       if (cls == backend.jsArrayClass || | 
| 3061           cls == backend.jsMutableArrayClass || | 3066           cls == backend.jsMutableArrayClass || | 
| 3062           cls == backend.jsFixedArrayClass || | 3067           cls == backend.jsFixedArrayClass || | 
| 3063           cls == backend.jsExtendableArrayClass) hasArray = true; | 3068           cls == backend.jsExtendableArrayClass) hasArray = true; | 
| 3064       else if (cls == backend.jsBoolClass) hasBool = true; | 3069       else if (cls == backend.jsBoolClass) hasBool = true; | 
| 3065       else if (cls == backend.jsDoubleClass) hasDouble = true; | 3070       else if (cls == backend.jsDoubleClass) hasDouble = true; | 
| 3066       else if (cls == backend.jsIntClass) hasInt = true; | 3071       else if (cls == backend.jsIntClass) hasInt = true; | 
| 3067       else if (cls == backend.jsNullClass) hasNull = true; | 3072       else if (cls == backend.jsNullClass) hasNull = true; | 
| 3068       else if (cls == backend.jsNumberClass) hasNumber = true; | 3073       else if (cls == backend.jsNumberClass) hasNumber = true; | 
| 3069       else if (cls == backend.jsStringClass) hasString = true; | 3074       else if (cls == backend.jsStringClass) hasString = true; | 
| 3070       else { | 3075       else { | 
| 3071         // TODO(sra): The set of classes includes classes mixed-in to | 3076         // The set of classes includes classes mixed-in to interceptor classes | 
| 3072         // interceptor classes. | 3077         // and user extensions of native classes. | 
| 3073         // assert(cls == compiler.objectClass || cls.isNative()); | 3078         // | 
| 3074         if (cls.isNative()) hasNative = true; | 3079         // The set of classes also includes the 'primitive' interceptor | 
|  | 3080         // PlainJavaScriptObject even when it has not been resolved, since it is | 
|  | 3081         // only resolved through the reference in getNativeInterceptor when | 
|  | 3082         // getNativeInterceptor is marked as used.  Guard against probing | 
|  | 3083         // unresolved PlainJavaScriptObject by testing for anyNativeClasses. | 
|  | 3084 | 
|  | 3085         if (anyNativeClasses) { | 
|  | 3086           if (Elements.isNativeOrExtendsNative(cls)) hasNative = true; | 
|  | 3087         } | 
| 3075       } | 3088       } | 
| 3076     } | 3089     } | 
| 3077     if (hasDouble) { | 3090     if (hasDouble) { | 
| 3078       hasNumber = true; | 3091       hasNumber = true; | 
| 3079     } | 3092     } | 
| 3080     if (hasInt) hasNumber = true; | 3093     if (hasInt) hasNumber = true; | 
| 3081 | 3094 | 
| 3082     if (classes == backend.interceptedClasses) { | 3095     if (classes == backend.interceptedClasses) { | 
| 3083       // I.e. this is the general interceptor. | 3096       // I.e. this is the general interceptor. | 
| 3084       hasNative = compiler.enqueuer.codegen.nativeEnqueuer | 3097       hasNative = anyNativeClasses; | 
| 3085           .hasInstantiatedNativeClasses(); |  | 
| 3086     } | 3098     } | 
| 3087 | 3099 | 
| 3088     jsAst.Block block = new jsAst.Block.empty(); | 3100     jsAst.Block block = new jsAst.Block.empty(); | 
| 3089 | 3101 | 
| 3090     if (hasNumber) { | 3102     if (hasNumber) { | 
| 3091       jsAst.Statement whenNumber; | 3103       jsAst.Statement whenNumber; | 
| 3092 | 3104 | 
| 3093       /// Note: there are two number classes in play: Dart's [num], | 3105       /// Note: there are two number classes in play: Dart's [num], | 
| 3094       /// and JavaScript's Number (typeof receiver == 'number').  This | 3106       /// and JavaScript's Number (typeof receiver == 'number').  This | 
| 3095       /// is the fallback used when we have determined that receiver | 3107       /// is the fallback used when we have determined that receiver | 
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3238     rtiNeededClasses.removeAll(neededClasses); | 3250     rtiNeededClasses.removeAll(neededClasses); | 
| 3239     // rtiNeededClasses now contains only the "empty shells". | 3251     // rtiNeededClasses now contains only the "empty shells". | 
| 3240     neededClasses.addAll(rtiNeededClasses); | 3252     neededClasses.addAll(rtiNeededClasses); | 
| 3241 | 3253 | 
| 3242     // 5. Finally, sort the classes. | 3254     // 5. Finally, sort the classes. | 
| 3243     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 3255     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 
| 3244 | 3256 | 
| 3245     for (ClassElement element in sortedClasses) { | 3257     for (ClassElement element in sortedClasses) { | 
| 3246       if (rtiNeededClasses.contains(element)) { | 3258       if (rtiNeededClasses.contains(element)) { | 
| 3247         regularClasses.add(element); | 3259         regularClasses.add(element); | 
| 3248       } else if (element.isNative()) { | 3260       } else if (Elements.isNativeOrExtendsNative(element)) { | 
| 3249         // For now, native classes cannot be deferred. | 3261         // For now, native classes and related classes cannot be deferred. | 
| 3250         nativeClasses.add(element); | 3262         nativeClasses.add(element); | 
|  | 3263         if (!element.isNative()) { | 
|  | 3264           assert(invariant(element, !isDeferred(element))); | 
|  | 3265           regularClasses.add(element); | 
|  | 3266         } | 
| 3251       } else if (isDeferred(element)) { | 3267       } else if (isDeferred(element)) { | 
| 3252         deferredClasses.add(element); | 3268         deferredClasses.add(element); | 
| 3253       } else { | 3269       } else { | 
| 3254         regularClasses.add(element); | 3270         regularClasses.add(element); | 
| 3255       } | 3271       } | 
| 3256     } | 3272     } | 
| 3257   } | 3273   } | 
| 3258 | 3274 | 
| 3259   Set<ClassElement> computeRtiNeededClasses() { | 3275   Set<ClassElement> computeRtiNeededClasses() { | 
| 3260     void addClassWithSuperclasses(ClassElement cls) { | 3276     void addClassWithSuperclasses(ClassElement cls) { | 
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3504       }).toList(); | 3520       }).toList(); | 
| 3505     jsAst.ArrayInitializer array = | 3521     jsAst.ArrayInitializer array = | 
| 3506         new jsAst.ArrayInitializer(invocationNames.length, elements); | 3522         new jsAst.ArrayInitializer(invocationNames.length, elements); | 
| 3507 | 3523 | 
| 3508     jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | 3524     jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | 
| 3509 | 3525 | 
| 3510     buffer.write(jsAst.prettyPrint(assignment, compiler)); | 3526     buffer.write(jsAst.prettyPrint(assignment, compiler)); | 
| 3511     buffer.write(N); | 3527     buffer.write(N); | 
| 3512   } | 3528   } | 
| 3513 | 3529 | 
|  | 3530   /** | 
|  | 3531    * Emit initializer for [mapTypeToInterceptor] data structure used by | 
|  | 3532    * [findInterceptorForType].  See declaration of [mapTypeToInterceptor] in | 
|  | 3533    * `interceptors.dart`. | 
|  | 3534    */ | 
|  | 3535   void emitMapTypeToInterceptor(CodeBuffer buffer) { | 
|  | 3536     // TODO(sra): Perhaps inject a constant instead? | 
|  | 3537     // TODO(sra): Filter by subclasses of native types. | 
|  | 3538     List<jsAst.Expression> elements = <jsAst.Expression>[]; | 
|  | 3539     ConstantHandler handler = compiler.constantHandler; | 
|  | 3540     List<Constant> constants = handler.getConstantsForEmission(); | 
|  | 3541     for (Constant constant in constants) { | 
|  | 3542       if (constant is TypeConstant) { | 
|  | 3543         TypeConstant typeConstant = constant; | 
|  | 3544         Element element = typeConstant.representedType.element; | 
|  | 3545         if (element is ClassElement) { | 
|  | 3546           ClassElement classElement = element; | 
|  | 3547           elements.add(backend.emitter.constantReference(constant)); | 
|  | 3548           elements.add(js(namer.isolateAccess(classElement))); | 
|  | 3549         } | 
|  | 3550       } | 
|  | 3551     } | 
|  | 3552 | 
|  | 3553     jsAst.ArrayInitializer array = new jsAst.ArrayInitializer.from(elements); | 
|  | 3554     String name = backend.namer.getName(backend.mapTypeToInterceptor); | 
|  | 3555     jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | 
|  | 3556 | 
|  | 3557     buffer.write(jsAst.prettyPrint(assignment, compiler)); | 
|  | 3558     buffer.write(N); | 
|  | 3559   } | 
|  | 3560 | 
| 3514   void emitInitFunction(CodeBuffer buffer) { | 3561   void emitInitFunction(CodeBuffer buffer) { | 
| 3515     jsAst.Fun fun = js.fun([], [ | 3562     jsAst.Fun fun = js.fun([], [ | 
| 3516       js('$isolateProperties = {}'), | 3563       js('$isolateProperties = {}'), | 
| 3517     ] | 3564     ] | 
| 3518     ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary()) | 3565     ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary()) | 
| 3519     ..addAll(buildLazyInitializerFunctionIfNecessary()) | 3566     ..addAll(buildLazyInitializerFunctionIfNecessary()) | 
| 3520     ..addAll(buildFinishIsolateConstructor()) | 3567     ..addAll(buildFinishIsolateConstructor()) | 
| 3521     ); | 3568     ); | 
| 3522     jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration( | 3569     jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration( | 
| 3523         new jsAst.VariableDeclaration('init'), fun); | 3570         new jsAst.VariableDeclaration('init'), fun); | 
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3836       emitGetInterceptorMethods(mainBuffer); | 3883       emitGetInterceptorMethods(mainBuffer); | 
| 3837       // Constants in checked mode call into RTI code to set type information | 3884       // Constants in checked mode call into RTI code to set type information | 
| 3838       // which may need getInterceptor methods, so we have to make sure that | 3885       // which may need getInterceptor methods, so we have to make sure that | 
| 3839       // [emitGetInterceptorMethods] has been called. | 3886       // [emitGetInterceptorMethods] has been called. | 
| 3840       emitCompileTimeConstants(mainBuffer); | 3887       emitCompileTimeConstants(mainBuffer); | 
| 3841       // Static field initializations require the classes and compile-time | 3888       // Static field initializations require the classes and compile-time | 
| 3842       // constants to be set up. | 3889       // constants to be set up. | 
| 3843       emitStaticNonFinalFieldInitializations(mainBuffer); | 3890       emitStaticNonFinalFieldInitializations(mainBuffer); | 
| 3844       emitOneShotInterceptors(mainBuffer); | 3891       emitOneShotInterceptors(mainBuffer); | 
| 3845       emitInterceptedNames(mainBuffer); | 3892       emitInterceptedNames(mainBuffer); | 
|  | 3893       emitMapTypeToInterceptor(mainBuffer); | 
| 3846       emitLazilyInitializedStaticFields(mainBuffer); | 3894       emitLazilyInitializedStaticFields(mainBuffer); | 
| 3847 | 3895 | 
| 3848       mainBuffer.add(nativeBuffer); | 3896       mainBuffer.add(nativeBuffer); | 
| 3849 | 3897 | 
| 3850       emitMetadata(mainBuffer); | 3898       emitMetadata(mainBuffer); | 
| 3851 | 3899 | 
| 3852       isolateProperties = isolatePropertiesName; | 3900       isolateProperties = isolatePropertiesName; | 
| 3853       // The following code should not use the short-hand for the | 3901       // The following code should not use the short-hand for the | 
| 3854       // initialStatics. | 3902       // initialStatics. | 
| 3855       mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); | 3903       mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); | 
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4093 | 4141 | 
| 4094 const String HOOKS_API_USAGE = """ | 4142 const String HOOKS_API_USAGE = """ | 
| 4095 // The code supports the following hooks: | 4143 // The code supports the following hooks: | 
| 4096 // dartPrint(message)   - if this function is defined it is called | 4144 // dartPrint(message)   - if this function is defined it is called | 
| 4097 //                        instead of the Dart [print] method. | 4145 //                        instead of the Dart [print] method. | 
| 4098 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4146 // dartMainRunner(main) - if this function is defined, the Dart [main] | 
| 4099 //                        method will not be invoked directly. | 4147 //                        method will not be invoked directly. | 
| 4100 //                        Instead, a closure that will invoke [main] is | 4148 //                        Instead, a closure that will invoke [main] is | 
| 4101 //                        passed to [dartMainRunner]. | 4149 //                        passed to [dartMainRunner]. | 
| 4102 """; | 4150 """; | 
| OLD | NEW | 
|---|