Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 15026006: Support for extending native classes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698