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 2609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2620 } | 2620 } |
2621 } | 2621 } |
2622 | 2622 |
2623 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { | 2623 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { |
2624 ConstantHandler handler = compiler.constantHandler; | 2624 ConstantHandler handler = compiler.constantHandler; |
2625 Iterable<VariableElement> staticNonFinalFields = | 2625 Iterable<VariableElement> staticNonFinalFields = |
2626 handler.getStaticNonFinalFieldsForEmission(); | 2626 handler.getStaticNonFinalFieldsForEmission(); |
2627 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { | 2627 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { |
2628 // [:interceptedNames:] is handled in [emitInterceptedNames]. | 2628 // [:interceptedNames:] is handled in [emitInterceptedNames]. |
2629 if (element == backend.interceptedNames) continue; | 2629 if (element == backend.interceptedNames) continue; |
2630 // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor]. | |
2631 if (element == backend.mapTypeToInterceptor) continue; | |
2630 compiler.withCurrentElement(element, () { | 2632 compiler.withCurrentElement(element, () { |
2631 Constant initialValue = handler.getInitialValueFor(element); | 2633 Constant initialValue = handler.getInitialValueFor(element); |
2632 jsAst.Expression init = | 2634 jsAst.Expression init = |
2633 js('$isolateProperties.${namer.getName(element)} = #', | 2635 js('$isolateProperties.${namer.getName(element)} = #', |
2634 constantEmitter.referenceInInitializationContext(initialValue)); | 2636 constantEmitter.referenceInInitializationContext(initialValue)); |
2635 buffer.write(jsAst.prettyPrint(init, compiler)); | 2637 buffer.write(jsAst.prettyPrint(init, compiler)); |
2636 buffer.write('$N'); | 2638 buffer.write('$N'); |
2637 }); | 2639 }); |
2638 } | 2640 } |
2639 } | 2641 } |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3033 cls == backend.jsFixedArrayClass || | 3035 cls == backend.jsFixedArrayClass || |
3034 cls == backend.jsExtendableArrayClass) hasArray = true; | 3036 cls == backend.jsExtendableArrayClass) hasArray = true; |
3035 else if (cls == backend.jsBoolClass) hasBool = true; | 3037 else if (cls == backend.jsBoolClass) hasBool = true; |
3036 else if (cls == backend.jsDoubleClass) hasDouble = true; | 3038 else if (cls == backend.jsDoubleClass) hasDouble = true; |
3037 else if (cls == backend.jsIntClass) hasInt = true; | 3039 else if (cls == backend.jsIntClass) hasInt = true; |
3038 else if (cls == backend.jsNullClass) hasNull = true; | 3040 else if (cls == backend.jsNullClass) hasNull = true; |
3039 else if (cls == backend.jsNumberClass) hasNumber = true; | 3041 else if (cls == backend.jsNumberClass) hasNumber = true; |
3040 else if (cls == backend.jsStringClass) hasString = true; | 3042 else if (cls == backend.jsStringClass) hasString = true; |
3041 else { | 3043 else { |
3042 // TODO(sra): The set of classes includes classes mixed-in to | 3044 // TODO(sra): The set of classes includes classes mixed-in to |
3043 // interceptor classes. | 3045 // interceptor classes and user extensions of native classes. |
3044 // assert(cls == compiler.objectClass || cls.isNative()); | 3046 if (Elements.isNativeOrExtendsNative(cls)) hasNative = true; |
3045 if (cls.isNative()) hasNative = true; | |
3046 } | 3047 } |
3047 } | 3048 } |
3048 if (hasDouble) { | 3049 if (hasDouble) { |
3049 hasNumber = true; | 3050 hasNumber = true; |
3050 } | 3051 } |
3051 if (hasInt) hasNumber = true; | 3052 if (hasInt) hasNumber = true; |
3052 | 3053 |
3053 if (classes == backend.interceptedClasses) { | 3054 if (classes == backend.interceptedClasses) { |
3054 // I.e. this is the general interceptor. | 3055 // I.e. this is the general interceptor. |
3055 hasNative = compiler.enqueuer.codegen.nativeEnqueuer | 3056 hasNative = compiler.enqueuer.codegen.nativeEnqueuer |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3209 rtiNeededClasses.removeAll(neededClasses); | 3210 rtiNeededClasses.removeAll(neededClasses); |
3210 // rtiNeededClasses now contains only the "empty shells". | 3211 // rtiNeededClasses now contains only the "empty shells". |
3211 neededClasses.addAll(rtiNeededClasses); | 3212 neededClasses.addAll(rtiNeededClasses); |
3212 | 3213 |
3213 // 5. Finally, sort the classes. | 3214 // 5. Finally, sort the classes. |
3214 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); | 3215 List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
3215 | 3216 |
3216 for (ClassElement element in sortedClasses) { | 3217 for (ClassElement element in sortedClasses) { |
3217 if (rtiNeededClasses.contains(element)) { | 3218 if (rtiNeededClasses.contains(element)) { |
3218 regularClasses.add(element); | 3219 regularClasses.add(element); |
3219 } else if (element.isNative()) { | 3220 } else if (Elements.isNativeOrExtendsNative(element)) { |
3220 // For now, native classes cannot be deferred. | 3221 // For now, native classes and related classes cannot be deferred. |
3221 nativeClasses.add(element); | 3222 nativeClasses.add(element); |
3223 if (!element.isNative()) { | |
3224 assert(!isDeferred(element)); | |
ahe
2013/08/13 18:31:47
assert(invariant(element, !isDeferred(element));
sra1
2013/08/14 04:36:47
Done.
| |
3225 regularClasses.add(element); | |
3226 } | |
3222 } else if (isDeferred(element)) { | 3227 } else if (isDeferred(element)) { |
3223 deferredClasses.add(element); | 3228 deferredClasses.add(element); |
3224 } else { | 3229 } else { |
3225 regularClasses.add(element); | 3230 regularClasses.add(element); |
3226 } | 3231 } |
3227 } | 3232 } |
3228 } | 3233 } |
3229 | 3234 |
3230 Set<ClassElement> computeRtiNeededClasses() { | 3235 Set<ClassElement> computeRtiNeededClasses() { |
3231 void addClassWithSuperclasses(ClassElement cls) { | 3236 void addClassWithSuperclasses(ClassElement cls) { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3475 }).toList(); | 3480 }).toList(); |
3476 jsAst.ArrayInitializer array = | 3481 jsAst.ArrayInitializer array = |
3477 new jsAst.ArrayInitializer(invocationNames.length, elements); | 3482 new jsAst.ArrayInitializer(invocationNames.length, elements); |
3478 | 3483 |
3479 jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | 3484 jsAst.Expression assignment = js('$isolateProperties.$name = #', array); |
3480 | 3485 |
3481 buffer.write(jsAst.prettyPrint(assignment, compiler)); | 3486 buffer.write(jsAst.prettyPrint(assignment, compiler)); |
3482 buffer.write(N); | 3487 buffer.write(N); |
3483 } | 3488 } |
3484 | 3489 |
3490 /** | |
3491 * Emit initializer for [mapTypeToInterceptor] data structure used by | |
3492 * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in | |
3493 * `interceptors.dart`. | |
3494 */ | |
3495 void emitMapTypeToInterceptor(CodeBuffer buffer) { | |
3496 // TODO(sra): Perhaps inject a constant instead? | |
3497 // TODO(sra): Filter by subclasses of native types. | |
3498 List<jsAst.Expression> elements = <jsAst.Expression>[]; | |
3499 ConstantHandler handler = compiler.constantHandler; | |
3500 List<Constant> constants = handler.getConstantsForEmission(); | |
3501 for (Constant constant in constants) { | |
3502 if (constant is TypeConstant) { | |
3503 TypeConstant typeConstant = constant; | |
3504 Element element = typeConstant.representedType.element; | |
3505 if (element is ClassElement) { | |
ahe
2013/08/13 18:31:47
element.isClass()
| |
3506 ClassElement classElement = element; | |
3507 elements.add(backend.emitter.constantReference(constant)); | |
3508 elements.add(js(namer.isolateAccess(classElement))); | |
3509 } | |
3510 } | |
3511 } | |
3512 | |
3513 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer.from(elements); | |
3514 String name = backend.namer.getName(backend.mapTypeToInterceptor); | |
3515 jsAst.Expression assignment = js('$isolateProperties.$name = #', array); | |
3516 | |
3517 buffer.write(jsAst.prettyPrint(assignment, compiler)); | |
3518 buffer.write(N); | |
3519 } | |
3520 | |
3485 void emitInitFunction(CodeBuffer buffer) { | 3521 void emitInitFunction(CodeBuffer buffer) { |
3486 jsAst.Fun fun = js.fun([], [ | 3522 jsAst.Fun fun = js.fun([], [ |
3487 js('$isolateProperties = {}'), | 3523 js('$isolateProperties = {}'), |
3488 ] | 3524 ] |
3489 ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary()) | 3525 ..addAll(buildDefineClassAndFinishClassFunctionsIfNecessary()) |
3490 ..addAll(buildLazyInitializerFunctionIfNecessary()) | 3526 ..addAll(buildLazyInitializerFunctionIfNecessary()) |
3491 ..addAll(buildFinishIsolateConstructor()) | 3527 ..addAll(buildFinishIsolateConstructor()) |
3492 ); | 3528 ); |
3493 jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration( | 3529 jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration( |
3494 new jsAst.VariableDeclaration('init'), fun); | 3530 new jsAst.VariableDeclaration('init'), fun); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3807 emitGetInterceptorMethods(mainBuffer); | 3843 emitGetInterceptorMethods(mainBuffer); |
3808 // Constants in checked mode call into RTI code to set type information | 3844 // Constants in checked mode call into RTI code to set type information |
3809 // which may need getInterceptor methods, so we have to make sure that | 3845 // which may need getInterceptor methods, so we have to make sure that |
3810 // [emitGetInterceptorMethods] has been called. | 3846 // [emitGetInterceptorMethods] has been called. |
3811 emitCompileTimeConstants(mainBuffer); | 3847 emitCompileTimeConstants(mainBuffer); |
3812 // Static field initializations require the classes and compile-time | 3848 // Static field initializations require the classes and compile-time |
3813 // constants to be set up. | 3849 // constants to be set up. |
3814 emitStaticNonFinalFieldInitializations(mainBuffer); | 3850 emitStaticNonFinalFieldInitializations(mainBuffer); |
3815 emitOneShotInterceptors(mainBuffer); | 3851 emitOneShotInterceptors(mainBuffer); |
3816 emitInterceptedNames(mainBuffer); | 3852 emitInterceptedNames(mainBuffer); |
3853 emitMapTypeToInterceptor(mainBuffer); | |
3817 emitLazilyInitializedStaticFields(mainBuffer); | 3854 emitLazilyInitializedStaticFields(mainBuffer); |
3818 | 3855 |
3819 mainBuffer.add(nativeBuffer); | 3856 mainBuffer.add(nativeBuffer); |
3820 | 3857 |
3821 emitMetadata(mainBuffer); | 3858 emitMetadata(mainBuffer); |
3822 | 3859 |
3823 isolateProperties = isolatePropertiesName; | 3860 isolateProperties = isolatePropertiesName; |
3824 // The following code should not use the short-hand for the | 3861 // The following code should not use the short-hand for the |
3825 // initialStatics. | 3862 // initialStatics. |
3826 mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); | 3863 mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N'); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4064 | 4101 |
4065 const String HOOKS_API_USAGE = """ | 4102 const String HOOKS_API_USAGE = """ |
4066 // The code supports the following hooks: | 4103 // The code supports the following hooks: |
4067 // dartPrint(message) - if this function is defined it is called | 4104 // dartPrint(message) - if this function is defined it is called |
4068 // instead of the Dart [print] method. | 4105 // instead of the Dart [print] method. |
4069 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4106 // dartMainRunner(main) - if this function is defined, the Dart [main] |
4070 // method will not be invoked directly. | 4107 // method will not be invoked directly. |
4071 // Instead, a closure that will invoke [main] is | 4108 // Instead, a closure that will invoke [main] is |
4072 // passed to [dartMainRunner]. | 4109 // passed to [dartMainRunner]. |
4073 """; | 4110 """; |
OLD | NEW |